sqlew 2.1.3 → 3.0.2

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 (84) hide show
  1. package/CHANGELOG.md +891 -535
  2. package/README.md +302 -613
  3. package/assets/kanban-style.png +0 -0
  4. package/assets/schema.sql +531 -402
  5. package/dist/database.d.ts +9 -0
  6. package/dist/database.d.ts.map +1 -1
  7. package/dist/database.js +33 -34
  8. package/dist/database.js.map +1 -1
  9. package/dist/index.js +1024 -21
  10. package/dist/index.js.map +1 -1
  11. package/dist/migrations/add-task-tables.d.ts +47 -0
  12. package/dist/migrations/add-task-tables.d.ts.map +1 -0
  13. package/dist/migrations/add-task-tables.js +285 -0
  14. package/dist/migrations/add-task-tables.js.map +1 -0
  15. package/dist/migrations/index.d.ts +96 -0
  16. package/dist/migrations/index.d.ts.map +1 -0
  17. package/dist/migrations/index.js +239 -0
  18. package/dist/migrations/index.js.map +1 -0
  19. package/dist/migrations/migrate-decisions-to-tasks.d.ts +61 -0
  20. package/dist/migrations/migrate-decisions-to-tasks.d.ts.map +1 -0
  21. package/dist/migrations/migrate-decisions-to-tasks.js +442 -0
  22. package/dist/migrations/migrate-decisions-to-tasks.js.map +1 -0
  23. package/dist/schema.d.ts.map +1 -1
  24. package/dist/schema.js +14 -3
  25. package/dist/schema.js.map +1 -1
  26. package/dist/tools/constraints.d.ts +4 -0
  27. package/dist/tools/constraints.d.ts.map +1 -1
  28. package/dist/tools/constraints.js +6 -27
  29. package/dist/tools/constraints.js.map +1 -1
  30. package/dist/tools/context.d.ts +17 -1
  31. package/dist/tools/context.d.ts.map +1 -1
  32. package/dist/tools/context.js +195 -190
  33. package/dist/tools/context.js.map +1 -1
  34. package/dist/tools/files.d.ts.map +1 -1
  35. package/dist/tools/files.js +113 -166
  36. package/dist/tools/files.js.map +1 -1
  37. package/dist/tools/messaging.d.ts +2 -9
  38. package/dist/tools/messaging.d.ts.map +1 -1
  39. package/dist/tools/messaging.js +67 -126
  40. package/dist/tools/messaging.js.map +1 -1
  41. package/dist/tools/tasks.d.ts +90 -0
  42. package/dist/tools/tasks.d.ts.map +1 -0
  43. package/dist/tools/tasks.js +732 -0
  44. package/dist/tools/tasks.js.map +1 -0
  45. package/dist/tools/utils.d.ts +8 -1
  46. package/dist/tools/utils.d.ts.map +1 -1
  47. package/dist/tools/utils.js +50 -21
  48. package/dist/tools/utils.js.map +1 -1
  49. package/dist/types.d.ts +14 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/utils/batch.d.ts +69 -0
  52. package/dist/utils/batch.d.ts.map +1 -0
  53. package/dist/utils/batch.js +148 -0
  54. package/dist/utils/batch.js.map +1 -0
  55. package/dist/utils/query-builder.d.ts +68 -0
  56. package/dist/utils/query-builder.d.ts.map +1 -0
  57. package/dist/utils/query-builder.js +116 -0
  58. package/dist/utils/query-builder.js.map +1 -0
  59. package/dist/utils/task-stale-detection.d.ts +28 -0
  60. package/dist/utils/task-stale-detection.d.ts.map +1 -0
  61. package/dist/utils/task-stale-detection.js +92 -0
  62. package/dist/utils/task-stale-detection.js.map +1 -0
  63. package/dist/utils/validators.d.ts +57 -0
  64. package/dist/utils/validators.d.ts.map +1 -0
  65. package/dist/utils/validators.js +117 -0
  66. package/dist/utils/validators.js.map +1 -0
  67. package/docs/AI_AGENT_GUIDE.md +1471 -0
  68. package/{ARCHITECTURE.md → docs/ARCHITECTURE.md} +636 -636
  69. package/docs/BEST_PRACTICES.md +481 -0
  70. package/docs/DECISION_TO_TASK_MIGRATION_GUIDE.md +457 -0
  71. package/docs/MIGRATION_CHAIN.md +280 -0
  72. package/{MIGRATION_v2.md → docs/MIGRATION_v2.md} +538 -538
  73. package/docs/SHARED_CONCEPTS.md +339 -0
  74. package/docs/TASK_ACTIONS.md +854 -0
  75. package/docs/TASK_LINKING.md +729 -0
  76. package/docs/TASK_MIGRATION.md +701 -0
  77. package/docs/TASK_OVERVIEW.md +363 -0
  78. package/docs/TASK_SYSTEM.md +1244 -0
  79. package/docs/TOOL_REFERENCE.md +471 -0
  80. package/docs/TOOL_SELECTION.md +279 -0
  81. package/docs/WORKFLOWS.md +602 -0
  82. package/docs/refactoring-summary-2025-10-17.md +365 -0
  83. package/docs/requirement-2025-10-17.md +508 -0
  84. package/package.json +64 -63
package/assets/schema.sql CHANGED
@@ -1,402 +1,531 @@
1
- -- MCP Shared Context Server - Database Schema
2
- -- Version: 2.1.0 (with activity log, smart defaults, batch ops, templates, CLI, subscriptions)
3
-
4
- -- ============================================================================
5
- -- Master Tables (Normalization)
6
- -- ============================================================================
7
-
8
- -- Agent Management
9
- CREATE TABLE IF NOT EXISTS m_agents (
10
- id INTEGER PRIMARY KEY AUTOINCREMENT,
11
- name TEXT UNIQUE NOT NULL
12
- );
13
-
14
- -- File Path Management
15
- CREATE TABLE IF NOT EXISTS m_files (
16
- id INTEGER PRIMARY KEY AUTOINCREMENT,
17
- path TEXT UNIQUE NOT NULL
18
- );
19
-
20
- -- Context Key Management
21
- CREATE TABLE IF NOT EXISTS m_context_keys (
22
- id INTEGER PRIMARY KEY AUTOINCREMENT,
23
- key TEXT UNIQUE NOT NULL
24
- );
25
-
26
- -- Constraint Category Management
27
- CREATE TABLE IF NOT EXISTS m_constraint_categories (
28
- id INTEGER PRIMARY KEY AUTOINCREMENT,
29
- name TEXT UNIQUE NOT NULL
30
- );
31
-
32
- -- Layer Management
33
- CREATE TABLE IF NOT EXISTS m_layers (
34
- id INTEGER PRIMARY KEY AUTOINCREMENT,
35
- name TEXT UNIQUE NOT NULL
36
- );
37
-
38
- -- Tag Management
39
- CREATE TABLE IF NOT EXISTS m_tags (
40
- id INTEGER PRIMARY KEY AUTOINCREMENT,
41
- name TEXT UNIQUE NOT NULL
42
- );
43
-
44
- -- Scope Management (Modules/Components)
45
- CREATE TABLE IF NOT EXISTS m_scopes (
46
- id INTEGER PRIMARY KEY AUTOINCREMENT,
47
- name TEXT UNIQUE NOT NULL
48
- );
49
-
50
- -- Configuration Management (Server Settings)
51
- CREATE TABLE IF NOT EXISTS m_config (
52
- key TEXT PRIMARY KEY,
53
- value TEXT NOT NULL
54
- );
55
-
56
- -- ============================================================================
57
- -- Transaction Tables
58
- -- ============================================================================
59
-
60
- -- Decisions (String Values)
61
- CREATE TABLE IF NOT EXISTS t_decisions (
62
- key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
63
- value TEXT NOT NULL,
64
- agent_id INTEGER REFERENCES m_agents(id),
65
- layer_id INTEGER REFERENCES m_layers(id),
66
- version TEXT DEFAULT '1.0.0',
67
- status INTEGER DEFAULT 1, -- 1=active, 2=deprecated, 3=draft
68
- ts INTEGER DEFAULT (unixepoch())
69
- );
70
-
71
- -- Decisions (Numeric Values)
72
- CREATE TABLE IF NOT EXISTS t_decisions_numeric (
73
- key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
74
- value REAL NOT NULL,
75
- agent_id INTEGER REFERENCES m_agents(id),
76
- layer_id INTEGER REFERENCES m_layers(id),
77
- version TEXT DEFAULT '1.0.0',
78
- status INTEGER DEFAULT 1,
79
- ts INTEGER DEFAULT (unixepoch())
80
- );
81
-
82
- -- Decision Version History
83
- CREATE TABLE IF NOT EXISTS t_decision_history (
84
- id INTEGER PRIMARY KEY AUTOINCREMENT,
85
- key_id INTEGER REFERENCES m_context_keys(id),
86
- version TEXT NOT NULL,
87
- value TEXT NOT NULL,
88
- agent_id INTEGER REFERENCES m_agents(id),
89
- ts INTEGER NOT NULL
90
- );
91
-
92
- -- Decision Tagging (Many-to-Many)
93
- CREATE TABLE IF NOT EXISTS t_decision_tags (
94
- decision_key_id INTEGER REFERENCES m_context_keys(id),
95
- tag_id INTEGER REFERENCES m_tags(id),
96
- PRIMARY KEY (decision_key_id, tag_id)
97
- );
98
-
99
- -- Decision Scopes (Many-to-Many)
100
- CREATE TABLE IF NOT EXISTS t_decision_scopes (
101
- decision_key_id INTEGER REFERENCES m_context_keys(id),
102
- scope_id INTEGER REFERENCES m_scopes(id),
103
- PRIMARY KEY (decision_key_id, scope_id)
104
- );
105
-
106
- -- Inter-Agent Messages
107
- CREATE TABLE IF NOT EXISTS t_agent_messages (
108
- id INTEGER PRIMARY KEY AUTOINCREMENT,
109
- from_agent_id INTEGER NOT NULL REFERENCES m_agents(id),
110
- to_agent_id INTEGER REFERENCES m_agents(id), -- NULL = broadcast
111
- msg_type INTEGER NOT NULL, -- 1=decision, 2=warning, 3=request, 4=info
112
- priority INTEGER DEFAULT 2, -- 1=low, 2=medium, 3=high, 4=critical
113
- payload TEXT, -- JSON string (only when needed)
114
- ts INTEGER DEFAULT (unixepoch()),
115
- read INTEGER DEFAULT 0
116
- );
117
-
118
- -- File Change History
119
- CREATE TABLE IF NOT EXISTS t_file_changes (
120
- id INTEGER PRIMARY KEY AUTOINCREMENT,
121
- file_id INTEGER NOT NULL REFERENCES m_files(id),
122
- agent_id INTEGER NOT NULL REFERENCES m_agents(id),
123
- layer_id INTEGER REFERENCES m_layers(id),
124
- change_type INTEGER NOT NULL, -- 1=created, 2=modified, 3=deleted
125
- description TEXT,
126
- ts INTEGER DEFAULT (unixepoch())
127
- );
128
-
129
- -- Constraints/Requirements
130
- CREATE TABLE IF NOT EXISTS t_constraints (
131
- id INTEGER PRIMARY KEY AUTOINCREMENT,
132
- category_id INTEGER NOT NULL REFERENCES m_constraint_categories(id),
133
- layer_id INTEGER REFERENCES m_layers(id),
134
- constraint_text TEXT NOT NULL,
135
- priority INTEGER DEFAULT 2, -- 1=low, 2=medium, 3=high, 4=critical
136
- active INTEGER DEFAULT 1,
137
- created_by INTEGER REFERENCES m_agents(id),
138
- ts INTEGER DEFAULT (unixepoch())
139
- );
140
-
141
- -- Constraint Tagging (Many-to-Many)
142
- CREATE TABLE IF NOT EXISTS t_constraint_tags (
143
- constraint_id INTEGER REFERENCES t_constraints(id),
144
- tag_id INTEGER REFERENCES m_tags(id),
145
- PRIMARY KEY (constraint_id, tag_id)
146
- );
147
-
148
- -- Activity Log (v2.1.0 - FR-001)
149
- CREATE TABLE IF NOT EXISTS t_activity_log (
150
- id INTEGER PRIMARY KEY AUTOINCREMENT,
151
- ts INTEGER DEFAULT (unixepoch()),
152
- agent_id INTEGER NOT NULL REFERENCES m_agents(id),
153
- action_type TEXT NOT NULL, -- 'decision_set', 'decision_update', 'message_send', 'file_record'
154
- target TEXT NOT NULL, -- key name, message id, file path, etc.
155
- layer_id INTEGER REFERENCES m_layers(id),
156
- details TEXT -- JSON string with additional details
157
- );
158
-
159
- -- Decision Templates (v2.1.0 - FR-006)
160
- CREATE TABLE IF NOT EXISTS t_decision_templates (
161
- id INTEGER PRIMARY KEY AUTOINCREMENT,
162
- name TEXT UNIQUE NOT NULL,
163
- defaults TEXT NOT NULL, -- JSON: {layer, status, tags, priority}
164
- required_fields TEXT, -- JSON array: ["cve_id", "severity"]
165
- created_by INTEGER REFERENCES m_agents(id),
166
- ts INTEGER DEFAULT (unixepoch())
167
- );
168
-
169
- -- ============================================================================
170
- -- Indexes
171
- -- ============================================================================
172
-
173
- CREATE INDEX IF NOT EXISTS idx_decisions_ts ON t_decisions(ts DESC);
174
- CREATE INDEX IF NOT EXISTS idx_decisions_layer ON t_decisions(layer_id);
175
- CREATE INDEX IF NOT EXISTS idx_decisions_status ON t_decisions(status);
176
- CREATE INDEX IF NOT EXISTS idx_messages_to_agent ON t_agent_messages(to_agent_id, read);
177
- CREATE INDEX IF NOT EXISTS idx_messages_ts ON t_agent_messages(ts DESC);
178
- CREATE INDEX IF NOT EXISTS idx_messages_priority ON t_agent_messages(priority DESC);
179
- CREATE INDEX IF NOT EXISTS idx_file_changes_ts ON t_file_changes(ts DESC);
180
- CREATE INDEX IF NOT EXISTS idx_file_changes_file ON t_file_changes(file_id);
181
- CREATE INDEX IF NOT EXISTS idx_file_changes_layer ON t_file_changes(layer_id);
182
- CREATE INDEX IF NOT EXISTS idx_constraints_active ON t_constraints(active, category_id);
183
- CREATE INDEX IF NOT EXISTS idx_constraints_priority ON t_constraints(priority DESC);
184
- CREATE INDEX IF NOT EXISTS idx_decision_tags_tag ON t_decision_tags(tag_id);
185
- CREATE INDEX IF NOT EXISTS idx_decision_scopes_scope ON t_decision_scopes(scope_id);
186
- CREATE INDEX IF NOT EXISTS idx_activity_log_ts ON t_activity_log(ts DESC);
187
- CREATE INDEX IF NOT EXISTS idx_activity_log_agent ON t_activity_log(agent_id);
188
- CREATE INDEX IF NOT EXISTS idx_activity_log_action ON t_activity_log(action_type);
189
-
190
- -- ============================================================================
191
- -- Views (Token Efficiency)
192
- -- ============================================================================
193
-
194
- -- Tagged Decisions (Most Efficient View)
195
- CREATE VIEW IF NOT EXISTS v_tagged_decisions AS
196
- SELECT
197
- k.key,
198
- d.value,
199
- d.version,
200
- CASE d.status WHEN 1 THEN 'active' WHEN 2 THEN 'deprecated' ELSE 'draft' END as status,
201
- l.name as layer,
202
- (SELECT GROUP_CONCAT(t2.name, ',') FROM t_decision_tags dt2
203
- JOIN m_tags t2 ON dt2.tag_id = t2.id
204
- WHERE dt2.decision_key_id = d.key_id) as tags,
205
- (SELECT GROUP_CONCAT(s2.name, ',') FROM t_decision_scopes ds2
206
- JOIN m_scopes s2 ON ds2.scope_id = s2.id
207
- WHERE ds2.decision_key_id = d.key_id) as scopes,
208
- a.name as decided_by,
209
- datetime(d.ts, 'unixepoch') as updated
210
- FROM t_decisions d
211
- JOIN m_context_keys k ON d.key_id = k.id
212
- LEFT JOIN m_layers l ON d.layer_id = l.id
213
- LEFT JOIN m_agents a ON d.agent_id = a.id;
214
-
215
- -- Active Context (Last Hour, Active Only)
216
- CREATE VIEW IF NOT EXISTS v_active_context AS
217
- SELECT
218
- k.key,
219
- d.value,
220
- d.version,
221
- l.name as layer,
222
- a.name as decided_by,
223
- datetime(d.ts, 'unixepoch') as updated
224
- FROM t_decisions d
225
- JOIN m_context_keys k ON d.key_id = k.id
226
- LEFT JOIN m_layers l ON d.layer_id = l.id
227
- LEFT JOIN m_agents a ON d.agent_id = a.id
228
- WHERE d.status = 1 AND d.ts > unixepoch() - 3600
229
- ORDER BY d.ts DESC;
230
-
231
- -- Layer Summary
232
- CREATE VIEW IF NOT EXISTS v_layer_summary AS
233
- SELECT
234
- l.name as layer,
235
- COUNT(DISTINCT d.key_id) as decisions_count,
236
- COUNT(DISTINCT fc.id) as file_changes_count,
237
- COUNT(DISTINCT c.id) as constraints_count
238
- FROM m_layers l
239
- LEFT JOIN t_decisions d ON l.id = d.layer_id AND d.status = 1
240
- LEFT JOIN t_file_changes fc ON l.id = fc.layer_id AND fc.ts > unixepoch() - 3600
241
- LEFT JOIN t_constraints c ON l.id = c.layer_id AND c.active = 1
242
- GROUP BY l.id;
243
-
244
- -- Unread Messages by Priority
245
- CREATE VIEW IF NOT EXISTS v_unread_messages_by_priority AS
246
- SELECT
247
- a.name as agent,
248
- CASE m.priority WHEN 4 THEN 'critical' WHEN 3 THEN 'high' WHEN 2 THEN 'medium' ELSE 'low' END as priority,
249
- COUNT(*) as count
250
- FROM t_agent_messages m
251
- JOIN m_agents a ON m.to_agent_id = a.id
252
- WHERE m.read = 0
253
- GROUP BY m.to_agent_id, m.priority
254
- ORDER BY m.priority DESC;
255
-
256
- -- Recent File Changes (With Layer)
257
- CREATE VIEW IF NOT EXISTS v_recent_file_changes AS
258
- SELECT
259
- f.path,
260
- a.name as changed_by,
261
- l.name as layer,
262
- CASE fc.change_type WHEN 1 THEN 'created' WHEN 2 THEN 'modified' ELSE 'deleted' END as change_type,
263
- fc.description,
264
- datetime(fc.ts, 'unixepoch') as changed_at
265
- FROM t_file_changes fc
266
- JOIN m_files f ON fc.file_id = f.id
267
- JOIN m_agents a ON fc.agent_id = a.id
268
- LEFT JOIN m_layers l ON fc.layer_id = l.id
269
- WHERE fc.ts > unixepoch() - 3600
270
- ORDER BY fc.ts DESC;
271
-
272
- -- Tagged Constraints
273
- CREATE VIEW IF NOT EXISTS v_tagged_constraints AS
274
- SELECT
275
- c.id,
276
- cc.name as category,
277
- l.name as layer,
278
- c.constraint_text,
279
- CASE c.priority WHEN 4 THEN 'critical' WHEN 3 THEN 'high' WHEN 2 THEN 'medium' ELSE 'low' END as priority,
280
- (SELECT GROUP_CONCAT(t2.name, ',') FROM t_constraint_tags ct2
281
- JOIN m_tags t2 ON ct2.tag_id = t2.id
282
- WHERE ct2.constraint_id = c.id) as tags,
283
- a.name as created_by,
284
- datetime(c.ts, 'unixepoch') as created_at
285
- FROM t_constraints c
286
- JOIN m_constraint_categories cc ON c.category_id = cc.id
287
- LEFT JOIN m_layers l ON c.layer_id = l.id
288
- LEFT JOIN m_agents a ON c.created_by = a.id
289
- WHERE c.active = 1
290
- ORDER BY c.priority DESC, cc.name, c.ts DESC;
291
-
292
- -- ============================================================================
293
- -- Triggers (Automatic Processing)
294
- -- ============================================================================
295
-
296
- -- Automatic Version History Recording
297
- CREATE TRIGGER IF NOT EXISTS trg_record_decision_history
298
- AFTER UPDATE ON t_decisions
299
- WHEN OLD.value != NEW.value OR OLD.version != NEW.version
300
- BEGIN
301
- INSERT INTO t_decision_history (key_id, version, value, agent_id, ts)
302
- VALUES (OLD.key_id, OLD.version, OLD.value, OLD.agent_id, OLD.ts);
303
- END;
304
-
305
- -- Activity Log Recording Triggers (v2.1.0 - FR-001)
306
- -- Decision Addition Log
307
- CREATE TRIGGER IF NOT EXISTS trg_log_decision_set
308
- AFTER INSERT ON t_decisions
309
- BEGIN
310
- INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
311
- SELECT
312
- COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
313
- 'decision_set',
314
- (SELECT key FROM m_context_keys WHERE id = NEW.key_id),
315
- NEW.layer_id,
316
- json_object('value', NEW.value, 'version', NEW.version, 'status', NEW.status);
317
- END;
318
-
319
- -- Decision Update Log
320
- CREATE TRIGGER IF NOT EXISTS trg_log_decision_update
321
- AFTER UPDATE ON t_decisions
322
- WHEN OLD.value != NEW.value OR OLD.version != NEW.version OR OLD.status != NEW.status
323
- BEGIN
324
- INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
325
- SELECT
326
- COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
327
- 'decision_update',
328
- (SELECT key FROM m_context_keys WHERE id = NEW.key_id),
329
- NEW.layer_id,
330
- json_object('old_value', OLD.value, 'new_value', NEW.value, 'old_version', OLD.version, 'new_version', NEW.version, 'old_status', OLD.status, 'new_status', NEW.status);
331
- END;
332
-
333
- -- Message Send Log
334
- CREATE TRIGGER IF NOT EXISTS trg_log_message_send
335
- AFTER INSERT ON t_agent_messages
336
- BEGIN
337
- INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
338
- SELECT
339
- NEW.from_agent_id,
340
- 'message_send',
341
- 'msg_id:' || NEW.id,
342
- NULL,
343
- json_object('to_agent_id', NEW.to_agent_id, 'msg_type', NEW.msg_type, 'priority', NEW.priority);
344
- END;
345
-
346
- -- File Change Log
347
- CREATE TRIGGER IF NOT EXISTS trg_log_file_record
348
- AFTER INSERT ON t_file_changes
349
- BEGIN
350
- INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
351
- SELECT
352
- NEW.agent_id,
353
- 'file_record',
354
- (SELECT path FROM m_files WHERE id = NEW.file_id),
355
- NEW.layer_id,
356
- json_object('change_type', NEW.change_type, 'description', NEW.description);
357
- END;
358
-
359
- -- ============================================================================
360
- -- Initial Data
361
- -- ============================================================================
362
-
363
- -- Standard Layers
364
- INSERT OR IGNORE INTO m_layers (name) VALUES
365
- ('presentation'),
366
- ('business'),
367
- ('data'),
368
- ('infrastructure'),
369
- ('cross-cutting');
370
-
371
- -- Standard Categories
372
- INSERT OR IGNORE INTO m_constraint_categories (name) VALUES
373
- ('performance'),
374
- ('architecture'),
375
- ('security');
376
-
377
- -- Common Tags
378
- INSERT OR IGNORE INTO m_tags (name) VALUES
379
- ('authentication'),
380
- ('authorization'),
381
- ('performance'),
382
- ('security'),
383
- ('api'),
384
- ('database'),
385
- ('caching'),
386
- ('testing'),
387
- ('validation'),
388
- ('error-handling');
389
-
390
- -- Default Settings (Auto-deletion Configuration)
391
- INSERT OR IGNORE INTO m_config (key, value) VALUES
392
- ('autodelete_ignore_weekend', '0'),
393
- ('autodelete_message_hours', '24'),
394
- ('autodelete_file_history_days', '7');
395
-
396
- -- Built-in Templates (Built-in Decision Templates - FR-006)
397
- INSERT OR IGNORE INTO t_decision_templates (name, defaults, required_fields, created_by, ts) VALUES
398
- ('breaking_change', '{"layer":"business","status":"active","tags":["breaking"]}', NULL, NULL, unixepoch()),
399
- ('security_vulnerability', '{"layer":"infrastructure","status":"active","tags":["security","vulnerability"]}', '["cve_id","severity"]', NULL, unixepoch()),
400
- ('performance_optimization', '{"layer":"business","status":"active","tags":["performance","optimization"]}', NULL, NULL, unixepoch()),
401
- ('deprecation', '{"layer":"business","status":"active","tags":["deprecation"]}', NULL, NULL, unixepoch()),
402
- ('architecture_decision', '{"layer":"infrastructure","status":"active","tags":["architecture","adr"]}', NULL, NULL, unixepoch());
1
+ -- MCP Shared Context Server - Database Schema
2
+ -- Version: 3.0.0 (with Kanban Task Watcher, activity log, smart defaults, batch ops, templates)
3
+
4
+ -- ============================================================================
5
+ -- Master Tables (Normalization)
6
+ -- ============================================================================
7
+
8
+ -- Agent Management
9
+ CREATE TABLE IF NOT EXISTS m_agents (
10
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
11
+ name TEXT UNIQUE NOT NULL
12
+ );
13
+
14
+ -- File Path Management
15
+ CREATE TABLE IF NOT EXISTS m_files (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ path TEXT UNIQUE NOT NULL
18
+ );
19
+
20
+ -- Context Key Management
21
+ CREATE TABLE IF NOT EXISTS m_context_keys (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ key TEXT UNIQUE NOT NULL
24
+ );
25
+
26
+ -- Constraint Category Management
27
+ CREATE TABLE IF NOT EXISTS m_constraint_categories (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ name TEXT UNIQUE NOT NULL
30
+ );
31
+
32
+ -- Layer Management
33
+ CREATE TABLE IF NOT EXISTS m_layers (
34
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
35
+ name TEXT UNIQUE NOT NULL
36
+ );
37
+
38
+ -- Tag Management
39
+ CREATE TABLE IF NOT EXISTS m_tags (
40
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
41
+ name TEXT UNIQUE NOT NULL
42
+ );
43
+
44
+ -- Scope Management (Modules/Components)
45
+ CREATE TABLE IF NOT EXISTS m_scopes (
46
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
47
+ name TEXT UNIQUE NOT NULL
48
+ );
49
+
50
+ -- Configuration Management (Server Settings)
51
+ CREATE TABLE IF NOT EXISTS m_config (
52
+ key TEXT PRIMARY KEY,
53
+ value TEXT NOT NULL
54
+ );
55
+
56
+ -- ============================================================================
57
+ -- Transaction Tables
58
+ -- ============================================================================
59
+
60
+ -- Decisions (String Values)
61
+ CREATE TABLE IF NOT EXISTS t_decisions (
62
+ key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
63
+ value TEXT NOT NULL,
64
+ agent_id INTEGER REFERENCES m_agents(id),
65
+ layer_id INTEGER REFERENCES m_layers(id),
66
+ version TEXT DEFAULT '1.0.0',
67
+ status INTEGER DEFAULT 1, -- 1=active, 2=deprecated, 3=draft
68
+ ts INTEGER DEFAULT (unixepoch())
69
+ );
70
+
71
+ -- Decisions (Numeric Values)
72
+ CREATE TABLE IF NOT EXISTS t_decisions_numeric (
73
+ key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
74
+ value REAL NOT NULL,
75
+ agent_id INTEGER REFERENCES m_agents(id),
76
+ layer_id INTEGER REFERENCES m_layers(id),
77
+ version TEXT DEFAULT '1.0.0',
78
+ status INTEGER DEFAULT 1,
79
+ ts INTEGER DEFAULT (unixepoch())
80
+ );
81
+
82
+ -- Decision Version History
83
+ CREATE TABLE IF NOT EXISTS t_decision_history (
84
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
85
+ key_id INTEGER REFERENCES m_context_keys(id),
86
+ version TEXT NOT NULL,
87
+ value TEXT NOT NULL,
88
+ agent_id INTEGER REFERENCES m_agents(id),
89
+ ts INTEGER NOT NULL
90
+ );
91
+
92
+ -- Decision Tagging (Many-to-Many)
93
+ CREATE TABLE IF NOT EXISTS t_decision_tags (
94
+ decision_key_id INTEGER REFERENCES m_context_keys(id),
95
+ tag_id INTEGER REFERENCES m_tags(id),
96
+ PRIMARY KEY (decision_key_id, tag_id)
97
+ );
98
+
99
+ -- Decision Scopes (Many-to-Many)
100
+ CREATE TABLE IF NOT EXISTS t_decision_scopes (
101
+ decision_key_id INTEGER REFERENCES m_context_keys(id),
102
+ scope_id INTEGER REFERENCES m_scopes(id),
103
+ PRIMARY KEY (decision_key_id, scope_id)
104
+ );
105
+
106
+ -- Inter-Agent Messages
107
+ CREATE TABLE IF NOT EXISTS t_agent_messages (
108
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
109
+ from_agent_id INTEGER NOT NULL REFERENCES m_agents(id),
110
+ to_agent_id INTEGER REFERENCES m_agents(id), -- NULL = broadcast
111
+ msg_type INTEGER NOT NULL, -- 1=decision, 2=warning, 3=request, 4=info
112
+ priority INTEGER DEFAULT 2, -- 1=low, 2=medium, 3=high, 4=critical
113
+ payload TEXT, -- JSON string (only when needed)
114
+ ts INTEGER DEFAULT (unixepoch()),
115
+ read INTEGER DEFAULT 0
116
+ );
117
+
118
+ -- File Change History
119
+ CREATE TABLE IF NOT EXISTS t_file_changes (
120
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
121
+ file_id INTEGER NOT NULL REFERENCES m_files(id),
122
+ agent_id INTEGER NOT NULL REFERENCES m_agents(id),
123
+ layer_id INTEGER REFERENCES m_layers(id),
124
+ change_type INTEGER NOT NULL, -- 1=created, 2=modified, 3=deleted
125
+ description TEXT,
126
+ ts INTEGER DEFAULT (unixepoch())
127
+ );
128
+
129
+ -- Constraints/Requirements
130
+ CREATE TABLE IF NOT EXISTS t_constraints (
131
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
132
+ category_id INTEGER NOT NULL REFERENCES m_constraint_categories(id),
133
+ layer_id INTEGER REFERENCES m_layers(id),
134
+ constraint_text TEXT NOT NULL,
135
+ priority INTEGER DEFAULT 2, -- 1=low, 2=medium, 3=high, 4=critical
136
+ active INTEGER DEFAULT 1,
137
+ created_by INTEGER REFERENCES m_agents(id),
138
+ ts INTEGER DEFAULT (unixepoch())
139
+ );
140
+
141
+ -- Constraint Tagging (Many-to-Many)
142
+ CREATE TABLE IF NOT EXISTS t_constraint_tags (
143
+ constraint_id INTEGER REFERENCES t_constraints(id),
144
+ tag_id INTEGER REFERENCES m_tags(id),
145
+ PRIMARY KEY (constraint_id, tag_id)
146
+ );
147
+
148
+ -- Activity Log (v2.1.0 - FR-001)
149
+ CREATE TABLE IF NOT EXISTS t_activity_log (
150
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
151
+ ts INTEGER DEFAULT (unixepoch()),
152
+ agent_id INTEGER NOT NULL REFERENCES m_agents(id),
153
+ action_type TEXT NOT NULL, -- 'decision_set', 'decision_update', 'message_send', 'file_record'
154
+ target TEXT NOT NULL, -- key name, message id, file path, etc.
155
+ layer_id INTEGER REFERENCES m_layers(id),
156
+ details TEXT -- JSON string with additional details
157
+ );
158
+
159
+ -- Decision Templates (v2.1.0 - FR-006)
160
+ CREATE TABLE IF NOT EXISTS t_decision_templates (
161
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
162
+ name TEXT UNIQUE NOT NULL,
163
+ defaults TEXT NOT NULL, -- JSON: {layer, status, tags, priority}
164
+ required_fields TEXT, -- JSON array: ["cve_id", "severity"]
165
+ created_by INTEGER REFERENCES m_agents(id),
166
+ ts INTEGER DEFAULT (unixepoch())
167
+ );
168
+
169
+ -- ============================================================================
170
+ -- Kanban Task Watcher (v3.0.0)
171
+ -- ============================================================================
172
+
173
+ -- Master table for task statuses
174
+ CREATE TABLE IF NOT EXISTS m_task_statuses (
175
+ id INTEGER PRIMARY KEY,
176
+ name TEXT UNIQUE NOT NULL
177
+ );
178
+
179
+ -- Task core data (token-efficient: no large text here)
180
+ CREATE TABLE IF NOT EXISTS t_tasks (
181
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
182
+ title TEXT NOT NULL,
183
+ status_id INTEGER NOT NULL REFERENCES m_task_statuses(id),
184
+ priority INTEGER DEFAULT 2,
185
+ assigned_agent_id INTEGER REFERENCES m_agents(id),
186
+ created_by_agent_id INTEGER REFERENCES m_agents(id),
187
+ layer_id INTEGER REFERENCES m_layers(id),
188
+ created_ts INTEGER DEFAULT (unixepoch()),
189
+ updated_ts INTEGER DEFAULT (unixepoch()),
190
+ completed_ts INTEGER
191
+ );
192
+
193
+ -- Task details (large text stored separately)
194
+ CREATE TABLE IF NOT EXISTS t_task_details (
195
+ task_id INTEGER PRIMARY KEY REFERENCES t_tasks(id) ON DELETE CASCADE,
196
+ description TEXT,
197
+ acceptance_criteria TEXT,
198
+ notes TEXT
199
+ );
200
+
201
+ -- Task tags (many-to-many)
202
+ CREATE TABLE IF NOT EXISTS t_task_tags (
203
+ task_id INTEGER REFERENCES t_tasks(id) ON DELETE CASCADE,
204
+ tag_id INTEGER REFERENCES m_tags(id),
205
+ PRIMARY KEY (task_id, tag_id)
206
+ );
207
+
208
+ -- Task-decision links
209
+ CREATE TABLE IF NOT EXISTS t_task_decision_links (
210
+ task_id INTEGER REFERENCES t_tasks(id) ON DELETE CASCADE,
211
+ decision_key_id INTEGER REFERENCES m_context_keys(id),
212
+ link_type TEXT DEFAULT 'implements',
213
+ PRIMARY KEY (task_id, decision_key_id)
214
+ );
215
+
216
+ -- Task-constraint links
217
+ CREATE TABLE IF NOT EXISTS t_task_constraint_links (
218
+ task_id INTEGER REFERENCES t_tasks(id) ON DELETE CASCADE,
219
+ constraint_id INTEGER REFERENCES t_constraints(id),
220
+ PRIMARY KEY (task_id, constraint_id)
221
+ );
222
+
223
+ -- Task-file links
224
+ CREATE TABLE IF NOT EXISTS t_task_file_links (
225
+ task_id INTEGER REFERENCES t_tasks(id) ON DELETE CASCADE,
226
+ file_id INTEGER REFERENCES m_files(id),
227
+ PRIMARY KEY (task_id, file_id)
228
+ );
229
+
230
+ -- ============================================================================
231
+ -- Indexes
232
+ -- ============================================================================
233
+
234
+ CREATE INDEX IF NOT EXISTS idx_decisions_ts ON t_decisions(ts DESC);
235
+ CREATE INDEX IF NOT EXISTS idx_decisions_layer ON t_decisions(layer_id);
236
+ CREATE INDEX IF NOT EXISTS idx_decisions_status ON t_decisions(status);
237
+ CREATE INDEX IF NOT EXISTS idx_messages_to_agent ON t_agent_messages(to_agent_id, read);
238
+ CREATE INDEX IF NOT EXISTS idx_messages_ts ON t_agent_messages(ts DESC);
239
+ CREATE INDEX IF NOT EXISTS idx_messages_priority ON t_agent_messages(priority DESC);
240
+ CREATE INDEX IF NOT EXISTS idx_file_changes_ts ON t_file_changes(ts DESC);
241
+ CREATE INDEX IF NOT EXISTS idx_file_changes_file ON t_file_changes(file_id);
242
+ CREATE INDEX IF NOT EXISTS idx_file_changes_layer ON t_file_changes(layer_id);
243
+ CREATE INDEX IF NOT EXISTS idx_constraints_active ON t_constraints(active, category_id);
244
+ CREATE INDEX IF NOT EXISTS idx_constraints_priority ON t_constraints(priority DESC);
245
+ CREATE INDEX IF NOT EXISTS idx_decision_tags_tag ON t_decision_tags(tag_id);
246
+ CREATE INDEX IF NOT EXISTS idx_decision_scopes_scope ON t_decision_scopes(scope_id);
247
+ CREATE INDEX IF NOT EXISTS idx_activity_log_ts ON t_activity_log(ts DESC);
248
+ CREATE INDEX IF NOT EXISTS idx_activity_log_agent ON t_activity_log(agent_id);
249
+ CREATE INDEX IF NOT EXISTS idx_activity_log_action ON t_activity_log(action_type);
250
+ CREATE INDEX IF NOT EXISTS idx_task_status ON t_tasks(status_id);
251
+ CREATE INDEX IF NOT EXISTS idx_task_updated ON t_tasks(updated_ts DESC);
252
+ CREATE INDEX IF NOT EXISTS idx_task_assignee ON t_tasks(assigned_agent_id);
253
+
254
+ -- ============================================================================
255
+ -- Views (Token Efficiency)
256
+ -- ============================================================================
257
+
258
+ -- Tagged Decisions (Most Efficient View)
259
+ CREATE VIEW IF NOT EXISTS v_tagged_decisions AS
260
+ SELECT
261
+ k.key,
262
+ d.value,
263
+ d.version,
264
+ CASE d.status WHEN 1 THEN 'active' WHEN 2 THEN 'deprecated' ELSE 'draft' END as status,
265
+ l.name as layer,
266
+ (SELECT GROUP_CONCAT(t2.name, ',') FROM t_decision_tags dt2
267
+ JOIN m_tags t2 ON dt2.tag_id = t2.id
268
+ WHERE dt2.decision_key_id = d.key_id) as tags,
269
+ (SELECT GROUP_CONCAT(s2.name, ',') FROM t_decision_scopes ds2
270
+ JOIN m_scopes s2 ON ds2.scope_id = s2.id
271
+ WHERE ds2.decision_key_id = d.key_id) as scopes,
272
+ a.name as decided_by,
273
+ datetime(d.ts, 'unixepoch') as updated
274
+ FROM t_decisions d
275
+ JOIN m_context_keys k ON d.key_id = k.id
276
+ LEFT JOIN m_layers l ON d.layer_id = l.id
277
+ LEFT JOIN m_agents a ON d.agent_id = a.id;
278
+
279
+ -- Active Context (Last Hour, Active Only)
280
+ CREATE VIEW IF NOT EXISTS v_active_context AS
281
+ SELECT
282
+ k.key,
283
+ d.value,
284
+ d.version,
285
+ l.name as layer,
286
+ a.name as decided_by,
287
+ datetime(d.ts, 'unixepoch') as updated
288
+ FROM t_decisions d
289
+ JOIN m_context_keys k ON d.key_id = k.id
290
+ LEFT JOIN m_layers l ON d.layer_id = l.id
291
+ LEFT JOIN m_agents a ON d.agent_id = a.id
292
+ WHERE d.status = 1 AND d.ts > unixepoch() - 3600
293
+ ORDER BY d.ts DESC;
294
+
295
+ -- Layer Summary
296
+ CREATE VIEW IF NOT EXISTS v_layer_summary AS
297
+ SELECT
298
+ l.name as layer,
299
+ COUNT(DISTINCT d.key_id) as decisions_count,
300
+ COUNT(DISTINCT fc.id) as file_changes_count,
301
+ COUNT(DISTINCT c.id) as constraints_count
302
+ FROM m_layers l
303
+ LEFT JOIN t_decisions d ON l.id = d.layer_id AND d.status = 1
304
+ LEFT JOIN t_file_changes fc ON l.id = fc.layer_id AND fc.ts > unixepoch() - 3600
305
+ LEFT JOIN t_constraints c ON l.id = c.layer_id AND c.active = 1
306
+ GROUP BY l.id;
307
+
308
+ -- Unread Messages by Priority
309
+ CREATE VIEW IF NOT EXISTS v_unread_messages_by_priority AS
310
+ SELECT
311
+ a.name as agent,
312
+ CASE m.priority WHEN 4 THEN 'critical' WHEN 3 THEN 'high' WHEN 2 THEN 'medium' ELSE 'low' END as priority,
313
+ COUNT(*) as count
314
+ FROM t_agent_messages m
315
+ JOIN m_agents a ON m.to_agent_id = a.id
316
+ WHERE m.read = 0
317
+ GROUP BY m.to_agent_id, m.priority
318
+ ORDER BY m.priority DESC;
319
+
320
+ -- Recent File Changes (With Layer)
321
+ CREATE VIEW IF NOT EXISTS v_recent_file_changes AS
322
+ SELECT
323
+ f.path,
324
+ a.name as changed_by,
325
+ l.name as layer,
326
+ CASE fc.change_type WHEN 1 THEN 'created' WHEN 2 THEN 'modified' ELSE 'deleted' END as change_type,
327
+ fc.description,
328
+ datetime(fc.ts, 'unixepoch') as changed_at
329
+ FROM t_file_changes fc
330
+ JOIN m_files f ON fc.file_id = f.id
331
+ JOIN m_agents a ON fc.agent_id = a.id
332
+ LEFT JOIN m_layers l ON fc.layer_id = l.id
333
+ WHERE fc.ts > unixepoch() - 3600
334
+ ORDER BY fc.ts DESC;
335
+
336
+ -- Tagged Constraints
337
+ CREATE VIEW IF NOT EXISTS v_tagged_constraints AS
338
+ SELECT
339
+ c.id,
340
+ cc.name as category,
341
+ l.name as layer,
342
+ c.constraint_text,
343
+ CASE c.priority WHEN 4 THEN 'critical' WHEN 3 THEN 'high' WHEN 2 THEN 'medium' ELSE 'low' END as priority,
344
+ (SELECT GROUP_CONCAT(t2.name, ',') FROM t_constraint_tags ct2
345
+ JOIN m_tags t2 ON ct2.tag_id = t2.id
346
+ WHERE ct2.constraint_id = c.id) as tags,
347
+ a.name as created_by,
348
+ datetime(c.ts, 'unixepoch') as created_at
349
+ FROM t_constraints c
350
+ JOIN m_constraint_categories cc ON c.category_id = cc.id
351
+ LEFT JOIN m_layers l ON c.layer_id = l.id
352
+ LEFT JOIN m_agents a ON c.created_by = a.id
353
+ WHERE c.active = 1
354
+ ORDER BY c.priority DESC, cc.name, c.ts DESC;
355
+
356
+ -- Task Board View (Token-efficient)
357
+ CREATE VIEW IF NOT EXISTS v_task_board AS
358
+ SELECT
359
+ t.id,
360
+ t.title,
361
+ s.name as status,
362
+ t.priority,
363
+ a.name as assigned_to,
364
+ l.name as layer,
365
+ t.created_ts,
366
+ t.updated_ts,
367
+ t.completed_ts,
368
+ (SELECT GROUP_CONCAT(tg2.name, ', ')
369
+ FROM t_task_tags tt2
370
+ JOIN m_tags tg2 ON tt2.tag_id = tg2.id
371
+ WHERE tt2.task_id = t.id) as tags
372
+ FROM t_tasks t
373
+ LEFT JOIN m_task_statuses s ON t.status_id = s.id
374
+ LEFT JOIN m_agents a ON t.assigned_agent_id = a.id
375
+ LEFT JOIN m_layers l ON t.layer_id = l.id;
376
+
377
+ -- ============================================================================
378
+ -- Triggers (Automatic Processing)
379
+ -- ============================================================================
380
+
381
+ -- Automatic Version History Recording
382
+ CREATE TRIGGER IF NOT EXISTS trg_record_decision_history
383
+ AFTER UPDATE ON t_decisions
384
+ WHEN OLD.value != NEW.value OR OLD.version != NEW.version
385
+ BEGIN
386
+ INSERT INTO t_decision_history (key_id, version, value, agent_id, ts)
387
+ VALUES (OLD.key_id, OLD.version, OLD.value, OLD.agent_id, OLD.ts);
388
+ END;
389
+
390
+ -- Activity Log Recording Triggers (v2.1.0 - FR-001)
391
+ -- Decision Addition Log
392
+ CREATE TRIGGER IF NOT EXISTS trg_log_decision_set
393
+ AFTER INSERT ON t_decisions
394
+ BEGIN
395
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
396
+ SELECT
397
+ COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
398
+ 'decision_set',
399
+ (SELECT key FROM m_context_keys WHERE id = NEW.key_id),
400
+ NEW.layer_id,
401
+ json_object('value', NEW.value, 'version', NEW.version, 'status', NEW.status);
402
+ END;
403
+
404
+ -- Decision Update Log
405
+ CREATE TRIGGER IF NOT EXISTS trg_log_decision_update
406
+ AFTER UPDATE ON t_decisions
407
+ WHEN OLD.value != NEW.value OR OLD.version != NEW.version OR OLD.status != NEW.status
408
+ BEGIN
409
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
410
+ SELECT
411
+ COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
412
+ 'decision_update',
413
+ (SELECT key FROM m_context_keys WHERE id = NEW.key_id),
414
+ NEW.layer_id,
415
+ json_object('old_value', OLD.value, 'new_value', NEW.value, 'old_version', OLD.version, 'new_version', NEW.version, 'old_status', OLD.status, 'new_status', NEW.status);
416
+ END;
417
+
418
+ -- Message Send Log
419
+ CREATE TRIGGER IF NOT EXISTS trg_log_message_send
420
+ AFTER INSERT ON t_agent_messages
421
+ BEGIN
422
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
423
+ SELECT
424
+ NEW.from_agent_id,
425
+ 'message_send',
426
+ 'msg_id:' || NEW.id,
427
+ NULL,
428
+ json_object('to_agent_id', NEW.to_agent_id, 'msg_type', NEW.msg_type, 'priority', NEW.priority);
429
+ END;
430
+
431
+ -- File Change Log
432
+ CREATE TRIGGER IF NOT EXISTS trg_log_file_record
433
+ AFTER INSERT ON t_file_changes
434
+ BEGIN
435
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
436
+ SELECT
437
+ NEW.agent_id,
438
+ 'file_record',
439
+ (SELECT path FROM m_files WHERE id = NEW.file_id),
440
+ NEW.layer_id,
441
+ json_object('change_type', NEW.change_type, 'description', NEW.description);
442
+ END;
443
+
444
+ -- Task Activity Log Triggers
445
+ CREATE TRIGGER IF NOT EXISTS trg_log_task_create
446
+ AFTER INSERT ON t_tasks
447
+ BEGIN
448
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
449
+ SELECT
450
+ COALESCE(NEW.created_by_agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
451
+ 'task_create',
452
+ 'task_id:' || NEW.id,
453
+ NEW.layer_id,
454
+ json_object('title', NEW.title, 'status_id', NEW.status_id, 'priority', NEW.priority);
455
+ END;
456
+
457
+ CREATE TRIGGER IF NOT EXISTS trg_log_task_status_change
458
+ AFTER UPDATE OF status_id ON t_tasks
459
+ WHEN OLD.status_id != NEW.status_id
460
+ BEGIN
461
+ INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
462
+ SELECT
463
+ COALESCE(NEW.assigned_agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
464
+ 'task_status_change',
465
+ 'task_id:' || NEW.id,
466
+ NEW.layer_id,
467
+ json_object('old_status', OLD.status_id, 'new_status', NEW.status_id);
468
+ END;
469
+
470
+ CREATE TRIGGER IF NOT EXISTS trg_update_task_timestamp
471
+ AFTER UPDATE ON t_tasks
472
+ BEGIN
473
+ UPDATE t_tasks SET updated_ts = unixepoch() WHERE id = NEW.id;
474
+ END;
475
+
476
+ -- ============================================================================
477
+ -- Initial Data
478
+ -- ============================================================================
479
+
480
+ -- Standard Layers
481
+ INSERT OR IGNORE INTO m_layers (name) VALUES
482
+ ('presentation'),
483
+ ('business'),
484
+ ('data'),
485
+ ('infrastructure'),
486
+ ('cross-cutting');
487
+
488
+ -- Standard Categories
489
+ INSERT OR IGNORE INTO m_constraint_categories (name) VALUES
490
+ ('performance'),
491
+ ('architecture'),
492
+ ('security');
493
+
494
+ -- Common Tags
495
+ INSERT OR IGNORE INTO m_tags (name) VALUES
496
+ ('authentication'),
497
+ ('authorization'),
498
+ ('performance'),
499
+ ('security'),
500
+ ('api'),
501
+ ('database'),
502
+ ('caching'),
503
+ ('testing'),
504
+ ('validation'),
505
+ ('error-handling');
506
+
507
+ -- Default Settings (Auto-deletion Configuration)
508
+ INSERT OR IGNORE INTO m_config (key, value) VALUES
509
+ ('autodelete_ignore_weekend', '0'),
510
+ ('autodelete_message_hours', '24'),
511
+ ('autodelete_file_history_days', '7'),
512
+ ('task_stale_hours_in_progress', '2'),
513
+ ('task_stale_hours_waiting_review', '24'),
514
+ ('task_auto_stale_enabled', '1');
515
+
516
+ -- Task Statuses (1=todo, 2=in_progress, 3=waiting_review, 4=blocked, 5=done, 6=archived)
517
+ INSERT OR IGNORE INTO m_task_statuses (id, name) VALUES
518
+ (1, 'todo'),
519
+ (2, 'in_progress'),
520
+ (3, 'waiting_review'),
521
+ (4, 'blocked'),
522
+ (5, 'done'),
523
+ (6, 'archived');
524
+
525
+ -- Built-in Templates (Built-in Decision Templates - FR-006)
526
+ INSERT OR IGNORE INTO t_decision_templates (name, defaults, required_fields, created_by, ts) VALUES
527
+ ('breaking_change', '{"layer":"business","status":"active","tags":["breaking"]}', NULL, NULL, unixepoch()),
528
+ ('security_vulnerability', '{"layer":"infrastructure","status":"active","tags":["security","vulnerability"]}', '["cve_id","severity"]', NULL, NULL, unixepoch()),
529
+ ('performance_optimization', '{"layer":"business","status":"active","tags":["performance","optimization"]}', NULL, NULL, unixepoch()),
530
+ ('deprecation', '{"layer":"business","status":"active","tags":["deprecation"]}', NULL, NULL, unixepoch()),
531
+ ('architecture_decision', '{"layer":"infrastructure","status":"active","tags":["architecture","adr"]}', NULL, NULL, unixepoch());