@velvetmonkey/vault-core 2.4.1 → 2.4.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.
- package/dist/migrations.js +9 -0
- package/dist/schema.d.ts +2 -2
- package/dist/schema.js +4 -3
- package/package.json +1 -1
package/dist/migrations.js
CHANGED
|
@@ -327,6 +327,15 @@ export function initSchema(db) {
|
|
|
327
327
|
}
|
|
328
328
|
// v37: prospect_ledger + prospect_summary tables (pre-entity pattern accumulation)
|
|
329
329
|
// (created by SCHEMA_SQL above via CREATE TABLE IF NOT EXISTS)
|
|
330
|
+
// v38: source column on wikilink_applications (proactive linking observability)
|
|
331
|
+
// Tracks who most recently applied each link: tool, proactive, enrichment, manual_detected
|
|
332
|
+
if (currentVersion < 38) {
|
|
333
|
+
const hasSource = db.prepare(`SELECT COUNT(*) as cnt FROM pragma_table_info('wikilink_applications') WHERE name = 'source'`).get();
|
|
334
|
+
if (hasSource.cnt === 0) {
|
|
335
|
+
db.exec(`ALTER TABLE wikilink_applications ADD COLUMN source TEXT NOT NULL DEFAULT 'tool'`);
|
|
336
|
+
}
|
|
337
|
+
db.prepare('INSERT OR REPLACE INTO schema_version (version) VALUES (?)').run(38);
|
|
338
|
+
}
|
|
330
339
|
db.prepare('INSERT OR IGNORE INTO schema_version (version) VALUES (?)').run(SCHEMA_VERSION);
|
|
331
340
|
}
|
|
332
341
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
* for the flywheel state database.
|
|
6
6
|
*/
|
|
7
7
|
/** Current schema version - bump when schema changes */
|
|
8
|
-
export declare const SCHEMA_VERSION =
|
|
8
|
+
export declare const SCHEMA_VERSION = 38;
|
|
9
9
|
/** State database filename */
|
|
10
10
|
export declare const STATE_DB_FILENAME = "state.db";
|
|
11
11
|
/** Directory for flywheel state */
|
|
12
12
|
export declare const FLYWHEEL_DIR = ".flywheel";
|
|
13
|
-
export declare const SCHEMA_SQL = "\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Metadata key-value store\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Entity index (replaces wikilink-entities.json)\nCREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n name_lower TEXT NOT NULL,\n path TEXT NOT NULL,\n category TEXT NOT NULL,\n aliases_json TEXT,\n hub_score INTEGER DEFAULT 0,\n description TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_entities_name_lower ON entities(name_lower);\nCREATE INDEX IF NOT EXISTS idx_entities_category ON entities(category);\n\n-- FTS5 for entity search with porter stemmer (contentless \u2014 triggers handle sync)\nCREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(\n name, aliases, category,\n content='',\n tokenize='porter unicode61'\n);\n\n-- Auto-sync triggers for entities_fts\nCREATE TRIGGER IF NOT EXISTS entities_ai AFTER INSERT ON entities BEGIN\n INSERT INTO entities_fts(rowid, name, aliases, category)\n VALUES (\n new.id,\n new.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(new.aliases_json)), ''),\n new.category\n );\nEND;\n\nCREATE TRIGGER IF NOT EXISTS entities_ad AFTER DELETE ON entities BEGIN\n INSERT INTO entities_fts(entities_fts, rowid, name, aliases, category)\n VALUES (\n 'delete',\n old.id,\n old.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(old.aliases_json)), ''),\n old.category\n );\nEND;\n\nCREATE TRIGGER IF NOT EXISTS entities_au AFTER UPDATE ON entities BEGIN\n INSERT INTO entities_fts(entities_fts, rowid, name, aliases, category)\n VALUES (\n 'delete',\n old.id,\n old.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(old.aliases_json)), ''),\n old.category\n );\n INSERT INTO entities_fts(rowid, name, aliases, category)\n VALUES (\n new.id,\n new.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(new.aliases_json)), ''),\n new.category\n );\nEND;\n\n-- Recency tracking (replaces entity-recency.json)\nCREATE TABLE IF NOT EXISTS recency (\n entity_name_lower TEXT PRIMARY KEY,\n last_mentioned_at INTEGER NOT NULL,\n mention_count INTEGER DEFAULT 1\n);\n\n-- Write state (replaces last-commit.json and other write state)\nCREATE TABLE IF NOT EXISTS write_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Content search FTS5 (migrated from vault-search.db)\n-- v11: Added frontmatter column for weighted search (path, title, frontmatter, content)\nCREATE VIRTUAL TABLE IF NOT EXISTS notes_fts USING fts5(\n path, title, frontmatter, content,\n tokenize='porter'\n);\n\n-- FTS5 build metadata (consolidated from vault-search.db)\nCREATE TABLE IF NOT EXISTS fts_metadata (\n key TEXT PRIMARY KEY,\n value TEXT\n);\n\n-- Vault index cache (for fast startup)\n-- Stores serialized VaultIndex to avoid full rebuild on startup\nCREATE TABLE IF NOT EXISTS vault_index_cache (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n data BLOB NOT NULL,\n built_at INTEGER NOT NULL,\n note_count INTEGER NOT NULL,\n version INTEGER DEFAULT 1\n);\n\n-- Flywheel configuration (replaces .flywheel.json)\nCREATE TABLE IF NOT EXISTS flywheel_config (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Vault metrics (v4: growth tracking)\nCREATE TABLE IF NOT EXISTS vault_metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n metric TEXT NOT NULL,\n value REAL NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_vault_metrics_ts ON vault_metrics(timestamp);\nCREATE INDEX IF NOT EXISTS idx_vault_metrics_m ON vault_metrics(metric, timestamp);\n\n-- Wikilink feedback (v4: quality tracking)\nCREATE TABLE IF NOT EXISTS wikilink_feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n context TEXT NOT NULL,\n note_path TEXT NOT NULL,\n correct INTEGER NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n matched_term TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_wl_feedback_entity ON wikilink_feedback(entity);\nCREATE INDEX IF NOT EXISTS idx_wl_feedback_note_path ON wikilink_feedback(note_path);\n\n-- Wikilink suppressions (v4: auto-suppress false positives)\nCREATE TABLE IF NOT EXISTS wikilink_suppressions (\n entity TEXT PRIMARY KEY,\n false_positive_rate REAL NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Wikilink applications tracking (v5: implicit feedback)\nCREATE TABLE IF NOT EXISTS wikilink_applications (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n note_path TEXT NOT NULL,\n matched_term TEXT,\n applied_at TEXT DEFAULT (datetime('now')),\n status TEXT DEFAULT 'applied'\n);\nCREATE UNIQUE INDEX IF NOT EXISTS idx_wl_apps_unique ON wikilink_applications(entity COLLATE NOCASE, note_path);\n\n-- Index events tracking (v6: index activity history)\nCREATE TABLE IF NOT EXISTS index_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n trigger TEXT NOT NULL,\n duration_ms INTEGER NOT NULL,\n success INTEGER NOT NULL DEFAULT 1,\n note_count INTEGER,\n files_changed INTEGER,\n changed_paths TEXT,\n error TEXT,\n steps TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_index_events_ts ON index_events(timestamp);\n\n-- Tool invocation tracking (v7: usage analytics)\nCREATE TABLE IF NOT EXISTS tool_invocations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n tool_name TEXT NOT NULL,\n session_id TEXT,\n note_paths TEXT,\n duration_ms INTEGER,\n success INTEGER NOT NULL DEFAULT 1,\n response_tokens INTEGER,\n baseline_tokens INTEGER,\n query_context TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_ts ON tool_invocations(timestamp);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_tool ON tool_invocations(tool_name, timestamp);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_session ON tool_invocations(session_id, timestamp);\n\n-- Graph topology snapshots (v8: structural evolution)\nCREATE TABLE IF NOT EXISTS graph_snapshots (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n metric TEXT NOT NULL,\n value REAL NOT NULL,\n details TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_graph_snap_ts ON graph_snapshots(timestamp);\nCREATE INDEX IF NOT EXISTS idx_graph_snap_m ON graph_snapshots(metric, timestamp);\n\n-- Note embeddings for semantic search (v9)\nCREATE TABLE IF NOT EXISTS note_embeddings (\n path TEXT PRIMARY KEY,\n embedding BLOB NOT NULL,\n content_hash TEXT NOT NULL,\n model TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Entity embeddings for semantic entity search (v10)\nCREATE TABLE IF NOT EXISTS entity_embeddings (\n entity_name TEXT PRIMARY KEY,\n embedding BLOB NOT NULL,\n source_hash TEXT NOT NULL,\n model TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Task cache for fast task queries (v12)\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n line INTEGER NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n raw TEXT NOT NULL,\n context TEXT,\n tags_json TEXT,\n due_date TEXT,\n UNIQUE(path, line)\n);\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_tasks_path ON tasks(path);\nCREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_date);\n\n-- Merge dismissals (v13: persistent merge pair suppression)\nCREATE TABLE IF NOT EXISTS merge_dismissals (\n pair_key TEXT PRIMARY KEY,\n source_path TEXT NOT NULL,\n target_path TEXT NOT NULL,\n source_name TEXT NOT NULL,\n target_name TEXT NOT NULL,\n reason TEXT NOT NULL,\n dismissed_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Suggestion events audit log (v15: pipeline observability)\nCREATE TABLE IF NOT EXISTS suggestion_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n note_path TEXT NOT NULL,\n entity TEXT NOT NULL,\n total_score REAL NOT NULL,\n breakdown_json TEXT NOT NULL,\n threshold REAL NOT NULL,\n passed INTEGER NOT NULL,\n strictness TEXT NOT NULL,\n applied INTEGER DEFAULT 0,\n pipeline_event_id INTEGER,\n UNIQUE(timestamp, note_path, entity)\n);\nCREATE INDEX IF NOT EXISTS idx_suggestion_entity ON suggestion_events(entity);\nCREATE INDEX IF NOT EXISTS idx_suggestion_note ON suggestion_events(note_path);\n\n-- Forward-link persistence for diff-based feedback (v16), edge weights (v22)\nCREATE TABLE IF NOT EXISTS note_links (\n note_path TEXT NOT NULL,\n target TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n weight_updated_at INTEGER,\n PRIMARY KEY (note_path, target)\n);\n\n-- Entity field change audit log (v17, rowid PK since v32)\nCREATE TABLE IF NOT EXISTS entity_changes (\n entity TEXT NOT NULL,\n field TEXT NOT NULL,\n old_value TEXT,\n new_value TEXT,\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Note tag persistence for diff-based feedback (v18)\nCREATE TABLE IF NOT EXISTS note_tags (\n note_path TEXT NOT NULL,\n tag TEXT NOT NULL,\n PRIMARY KEY (note_path, tag)\n);\n\n-- Wikilink survival tracking for positive feedback signals (v19)\nCREATE TABLE IF NOT EXISTS note_link_history (\n note_path TEXT NOT NULL,\n target TEXT NOT NULL,\n first_seen_at TEXT NOT NULL DEFAULT (datetime('now')),\n edits_survived INTEGER NOT NULL DEFAULT 0,\n last_positive_at TEXT,\n PRIMARY KEY (note_path, target)\n);\n\n-- Note move history (v20): records when files are moved/renamed to a different folder\nCREATE TABLE IF NOT EXISTS note_moves (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n old_path TEXT NOT NULL,\n new_path TEXT NOT NULL,\n moved_at TEXT NOT NULL DEFAULT (datetime('now')),\n old_folder TEXT,\n new_folder TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_note_moves_old_path ON note_moves(old_path);\nCREATE INDEX IF NOT EXISTS idx_note_moves_new_path ON note_moves(new_path);\nCREATE INDEX IF NOT EXISTS idx_note_moves_moved_at ON note_moves(moved_at);\n\n-- Corrections (v24): persistent correction records from user/engine feedback\nCREATE TABLE IF NOT EXISTS corrections (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT,\n note_path TEXT,\n correction_type TEXT NOT NULL,\n description TEXT NOT NULL,\n source TEXT NOT NULL DEFAULT 'user',\n status TEXT DEFAULT 'pending',\n created_at TEXT DEFAULT (datetime('now')),\n resolved_at TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_corrections_status ON corrections(status);\nCREATE INDEX IF NOT EXISTS idx_corrections_entity ON corrections(entity);\n\n-- Memories (v26): lightweight key-value working memory for agents\nCREATE TABLE IF NOT EXISTS memories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n memory_type TEXT NOT NULL,\n entity TEXT,\n entities_json TEXT,\n source_agent_id TEXT,\n source_session_id TEXT,\n confidence REAL NOT NULL DEFAULT 1.0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n accessed_at INTEGER NOT NULL,\n ttl_days INTEGER,\n superseded_by INTEGER REFERENCES memories(id),\n visibility TEXT NOT NULL DEFAULT 'shared'\n);\nCREATE INDEX IF NOT EXISTS idx_memories_key ON memories(key);\nCREATE INDEX IF NOT EXISTS idx_memories_entity ON memories(entity);\nCREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n key, value,\n content=memories, content_rowid=id,\n tokenize='porter unicode61'\n);\n\n-- Auto-sync triggers for memories_fts\nCREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, key, value)\n VALUES (new.id, new.key, new.value);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, key, value)\n VALUES ('delete', old.id, old.key, old.value);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, key, value)\n VALUES ('delete', old.id, old.key, old.value);\n INSERT INTO memories_fts(rowid, key, value)\n VALUES (new.id, new.key, new.value);\nEND;\n\n-- Co-occurrence cache (v27): persist co-occurrence index to avoid full vault scan on restart\nCREATE TABLE IF NOT EXISTS cooccurrence_cache (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n data TEXT NOT NULL,\n built_at INTEGER NOT NULL,\n entity_count INTEGER NOT NULL,\n association_count INTEGER NOT NULL\n);\n\n-- Content hashes (v28): persist watcher content hashes across restarts\nCREATE TABLE IF NOT EXISTS content_hashes (\n path TEXT PRIMARY KEY,\n hash TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Session summaries (v26): agent session tracking\nCREATE TABLE IF NOT EXISTS session_summaries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL UNIQUE,\n summary TEXT NOT NULL,\n topics_json TEXT,\n notes_modified_json TEXT,\n agent_id TEXT,\n started_at INTEGER,\n ended_at INTEGER NOT NULL,\n tool_count INTEGER\n);\n\n-- Retrieval co-occurrence (v30): notes retrieved together build implicit edges\nCREATE TABLE IF NOT EXISTS retrieval_cooccurrence (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n note_a TEXT NOT NULL,\n note_b TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n UNIQUE(note_a, note_b, session_id)\n);\nCREATE INDEX IF NOT EXISTS idx_retcooc_notes ON retrieval_cooccurrence(note_a, note_b);\nCREATE INDEX IF NOT EXISTS idx_retcooc_ts ON retrieval_cooccurrence(timestamp);\n\n-- Deferred proactive linking queue (v31)\nCREATE TABLE IF NOT EXISTS proactive_queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n note_path TEXT NOT NULL,\n entity TEXT NOT NULL,\n score REAL NOT NULL,\n confidence TEXT NOT NULL,\n queued_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n applied_at INTEGER,\n UNIQUE(note_path, entity)\n);\nCREATE INDEX IF NOT EXISTS idx_pq_status ON proactive_queue(status, expires_at);\n\n-- Performance benchmarks (v33: longitudinal tracking)\nCREATE TABLE IF NOT EXISTS performance_benchmarks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n version TEXT NOT NULL,\n benchmark TEXT NOT NULL,\n mean_ms REAL NOT NULL,\n p50_ms REAL,\n p95_ms REAL,\n iterations INTEGER NOT NULL DEFAULT 1\n);\nCREATE INDEX IF NOT EXISTS idx_perf_bench_ts ON performance_benchmarks(timestamp);\nCREATE INDEX IF NOT EXISTS idx_perf_bench_name ON performance_benchmarks(benchmark, timestamp);\n\n-- Tool selection feedback (v36: tool selection quality tracking)\nCREATE TABLE IF NOT EXISTS tool_selection_feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n tool_invocation_id INTEGER,\n tool_name TEXT NOT NULL,\n query_context TEXT,\n expected_tool TEXT,\n expected_category TEXT,\n correct INTEGER,\n source TEXT NOT NULL DEFAULT 'explicit',\n rule_id TEXT,\n rule_version INTEGER,\n session_id TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_tsf_tool ON tool_selection_feedback(tool_name);\nCREATE INDEX IF NOT EXISTS idx_tsf_ts ON tool_selection_feedback(timestamp);\n\n-- Prospect ledger (v37): day-grain sightings for pre-entity pattern accumulation\nCREATE TABLE IF NOT EXISTS prospect_ledger (\n term TEXT NOT NULL,\n display_name TEXT NOT NULL,\n note_path TEXT NOT NULL,\n seen_day TEXT NOT NULL,\n source TEXT NOT NULL,\n pattern TEXT,\n confidence TEXT NOT NULL DEFAULT 'low',\n backlink_count INTEGER DEFAULT 0,\n score REAL DEFAULT 0,\n first_seen_at INTEGER NOT NULL,\n last_seen_at INTEGER NOT NULL,\n sighting_count INTEGER NOT NULL DEFAULT 1,\n PRIMARY KEY (term, note_path, seen_day)\n);\nCREATE INDEX IF NOT EXISTS idx_prospect_term ON prospect_ledger(term);\nCREATE INDEX IF NOT EXISTS idx_prospect_last_seen ON prospect_ledger(last_seen_at);\n\n-- Prospect summary (v37): materialized aggregate for fast scoring\nCREATE TABLE IF NOT EXISTS prospect_summary (\n term TEXT PRIMARY KEY,\n display_name TEXT NOT NULL,\n note_count INTEGER NOT NULL DEFAULT 0,\n day_count INTEGER NOT NULL DEFAULT 0,\n total_sightings INTEGER NOT NULL DEFAULT 0,\n backlink_max INTEGER NOT NULL DEFAULT 0,\n cooccurring_entities TEXT,\n best_source TEXT NOT NULL DEFAULT 'implicit',\n best_confidence TEXT NOT NULL DEFAULT 'low',\n best_score REAL NOT NULL DEFAULT 0,\n first_seen_at INTEGER NOT NULL,\n last_seen_at INTEGER NOT NULL,\n promotion_score REAL NOT NULL DEFAULT 0,\n promoted_at INTEGER,\n updated_at INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_prospect_summary_score ON prospect_summary(promotion_score DESC);\n\n";
|
|
13
|
+
export declare const SCHEMA_SQL = "\n-- Schema version tracking\nCREATE TABLE IF NOT EXISTS schema_version (\n version INTEGER PRIMARY KEY,\n applied_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Metadata key-value store\nCREATE TABLE IF NOT EXISTS metadata (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Entity index (replaces wikilink-entities.json)\nCREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY,\n name TEXT NOT NULL,\n name_lower TEXT NOT NULL,\n path TEXT NOT NULL,\n category TEXT NOT NULL,\n aliases_json TEXT,\n hub_score INTEGER DEFAULT 0,\n description TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_entities_name_lower ON entities(name_lower);\nCREATE INDEX IF NOT EXISTS idx_entities_category ON entities(category);\n\n-- FTS5 for entity search with porter stemmer (contentless \u2014 triggers handle sync)\nCREATE VIRTUAL TABLE IF NOT EXISTS entities_fts USING fts5(\n name, aliases, category,\n content='',\n tokenize='porter unicode61'\n);\n\n-- Auto-sync triggers for entities_fts\nCREATE TRIGGER IF NOT EXISTS entities_ai AFTER INSERT ON entities BEGIN\n INSERT INTO entities_fts(rowid, name, aliases, category)\n VALUES (\n new.id,\n new.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(new.aliases_json)), ''),\n new.category\n );\nEND;\n\nCREATE TRIGGER IF NOT EXISTS entities_ad AFTER DELETE ON entities BEGIN\n INSERT INTO entities_fts(entities_fts, rowid, name, aliases, category)\n VALUES (\n 'delete',\n old.id,\n old.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(old.aliases_json)), ''),\n old.category\n );\nEND;\n\nCREATE TRIGGER IF NOT EXISTS entities_au AFTER UPDATE ON entities BEGIN\n INSERT INTO entities_fts(entities_fts, rowid, name, aliases, category)\n VALUES (\n 'delete',\n old.id,\n old.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(old.aliases_json)), ''),\n old.category\n );\n INSERT INTO entities_fts(rowid, name, aliases, category)\n VALUES (\n new.id,\n new.name,\n COALESCE((SELECT group_concat(value, ' ') FROM json_each(new.aliases_json)), ''),\n new.category\n );\nEND;\n\n-- Recency tracking (replaces entity-recency.json)\nCREATE TABLE IF NOT EXISTS recency (\n entity_name_lower TEXT PRIMARY KEY,\n last_mentioned_at INTEGER NOT NULL,\n mention_count INTEGER DEFAULT 1\n);\n\n-- Write state (replaces last-commit.json and other write state)\nCREATE TABLE IF NOT EXISTS write_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Content search FTS5 (migrated from vault-search.db)\n-- v11: Added frontmatter column for weighted search (path, title, frontmatter, content)\nCREATE VIRTUAL TABLE IF NOT EXISTS notes_fts USING fts5(\n path, title, frontmatter, content,\n tokenize='porter'\n);\n\n-- FTS5 build metadata (consolidated from vault-search.db)\nCREATE TABLE IF NOT EXISTS fts_metadata (\n key TEXT PRIMARY KEY,\n value TEXT\n);\n\n-- Vault index cache (for fast startup)\n-- Stores serialized VaultIndex to avoid full rebuild on startup\nCREATE TABLE IF NOT EXISTS vault_index_cache (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n data BLOB NOT NULL,\n built_at INTEGER NOT NULL,\n note_count INTEGER NOT NULL,\n version INTEGER DEFAULT 1\n);\n\n-- Flywheel configuration (replaces .flywheel.json)\nCREATE TABLE IF NOT EXISTS flywheel_config (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Vault metrics (v4: growth tracking)\nCREATE TABLE IF NOT EXISTS vault_metrics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n metric TEXT NOT NULL,\n value REAL NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_vault_metrics_ts ON vault_metrics(timestamp);\nCREATE INDEX IF NOT EXISTS idx_vault_metrics_m ON vault_metrics(metric, timestamp);\n\n-- Wikilink feedback (v4: quality tracking)\nCREATE TABLE IF NOT EXISTS wikilink_feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n context TEXT NOT NULL,\n note_path TEXT NOT NULL,\n correct INTEGER NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n matched_term TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_wl_feedback_entity ON wikilink_feedback(entity);\nCREATE INDEX IF NOT EXISTS idx_wl_feedback_note_path ON wikilink_feedback(note_path);\n\n-- Wikilink suppressions (v4: auto-suppress false positives)\nCREATE TABLE IF NOT EXISTS wikilink_suppressions (\n entity TEXT PRIMARY KEY,\n false_positive_rate REAL NOT NULL,\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Wikilink applications tracking (v5: implicit feedback, v38: source provenance)\nCREATE TABLE IF NOT EXISTS wikilink_applications (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT NOT NULL,\n note_path TEXT NOT NULL,\n matched_term TEXT,\n applied_at TEXT DEFAULT (datetime('now')),\n status TEXT DEFAULT 'applied',\n source TEXT NOT NULL DEFAULT 'tool'\n);\nCREATE UNIQUE INDEX IF NOT EXISTS idx_wl_apps_unique ON wikilink_applications(entity COLLATE NOCASE, note_path);\n\n-- Index events tracking (v6: index activity history)\nCREATE TABLE IF NOT EXISTS index_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n trigger TEXT NOT NULL,\n duration_ms INTEGER NOT NULL,\n success INTEGER NOT NULL DEFAULT 1,\n note_count INTEGER,\n files_changed INTEGER,\n changed_paths TEXT,\n error TEXT,\n steps TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_index_events_ts ON index_events(timestamp);\n\n-- Tool invocation tracking (v7: usage analytics)\nCREATE TABLE IF NOT EXISTS tool_invocations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n tool_name TEXT NOT NULL,\n session_id TEXT,\n note_paths TEXT,\n duration_ms INTEGER,\n success INTEGER NOT NULL DEFAULT 1,\n response_tokens INTEGER,\n baseline_tokens INTEGER,\n query_context TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_ts ON tool_invocations(timestamp);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_tool ON tool_invocations(tool_name, timestamp);\nCREATE INDEX IF NOT EXISTS idx_tool_inv_session ON tool_invocations(session_id, timestamp);\n\n-- Graph topology snapshots (v8: structural evolution)\nCREATE TABLE IF NOT EXISTS graph_snapshots (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n metric TEXT NOT NULL,\n value REAL NOT NULL,\n details TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_graph_snap_ts ON graph_snapshots(timestamp);\nCREATE INDEX IF NOT EXISTS idx_graph_snap_m ON graph_snapshots(metric, timestamp);\n\n-- Note embeddings for semantic search (v9)\nCREATE TABLE IF NOT EXISTS note_embeddings (\n path TEXT PRIMARY KEY,\n embedding BLOB NOT NULL,\n content_hash TEXT NOT NULL,\n model TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Entity embeddings for semantic entity search (v10)\nCREATE TABLE IF NOT EXISTS entity_embeddings (\n entity_name TEXT PRIMARY KEY,\n embedding BLOB NOT NULL,\n source_hash TEXT NOT NULL,\n model TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Task cache for fast task queries (v12)\nCREATE TABLE IF NOT EXISTS tasks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n path TEXT NOT NULL,\n line INTEGER NOT NULL,\n text TEXT NOT NULL,\n status TEXT NOT NULL,\n raw TEXT NOT NULL,\n context TEXT,\n tags_json TEXT,\n due_date TEXT,\n UNIQUE(path, line)\n);\nCREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);\nCREATE INDEX IF NOT EXISTS idx_tasks_path ON tasks(path);\nCREATE INDEX IF NOT EXISTS idx_tasks_due ON tasks(due_date);\n\n-- Merge dismissals (v13: persistent merge pair suppression)\nCREATE TABLE IF NOT EXISTS merge_dismissals (\n pair_key TEXT PRIMARY KEY,\n source_path TEXT NOT NULL,\n target_path TEXT NOT NULL,\n source_name TEXT NOT NULL,\n target_name TEXT NOT NULL,\n reason TEXT NOT NULL,\n dismissed_at TEXT DEFAULT (datetime('now'))\n);\n\n-- Suggestion events audit log (v15: pipeline observability)\nCREATE TABLE IF NOT EXISTS suggestion_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n note_path TEXT NOT NULL,\n entity TEXT NOT NULL,\n total_score REAL NOT NULL,\n breakdown_json TEXT NOT NULL,\n threshold REAL NOT NULL,\n passed INTEGER NOT NULL,\n strictness TEXT NOT NULL,\n applied INTEGER DEFAULT 0,\n pipeline_event_id INTEGER,\n UNIQUE(timestamp, note_path, entity)\n);\nCREATE INDEX IF NOT EXISTS idx_suggestion_entity ON suggestion_events(entity);\nCREATE INDEX IF NOT EXISTS idx_suggestion_note ON suggestion_events(note_path);\n\n-- Forward-link persistence for diff-based feedback (v16), edge weights (v22)\nCREATE TABLE IF NOT EXISTS note_links (\n note_path TEXT NOT NULL,\n target TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n weight_updated_at INTEGER,\n PRIMARY KEY (note_path, target)\n);\n\n-- Entity field change audit log (v17, rowid PK since v32)\nCREATE TABLE IF NOT EXISTS entity_changes (\n entity TEXT NOT NULL,\n field TEXT NOT NULL,\n old_value TEXT,\n new_value TEXT,\n changed_at TEXT NOT NULL DEFAULT (datetime('now'))\n);\n\n-- Note tag persistence for diff-based feedback (v18)\nCREATE TABLE IF NOT EXISTS note_tags (\n note_path TEXT NOT NULL,\n tag TEXT NOT NULL,\n PRIMARY KEY (note_path, tag)\n);\n\n-- Wikilink survival tracking for positive feedback signals (v19)\nCREATE TABLE IF NOT EXISTS note_link_history (\n note_path TEXT NOT NULL,\n target TEXT NOT NULL,\n first_seen_at TEXT NOT NULL DEFAULT (datetime('now')),\n edits_survived INTEGER NOT NULL DEFAULT 0,\n last_positive_at TEXT,\n PRIMARY KEY (note_path, target)\n);\n\n-- Note move history (v20): records when files are moved/renamed to a different folder\nCREATE TABLE IF NOT EXISTS note_moves (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n old_path TEXT NOT NULL,\n new_path TEXT NOT NULL,\n moved_at TEXT NOT NULL DEFAULT (datetime('now')),\n old_folder TEXT,\n new_folder TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_note_moves_old_path ON note_moves(old_path);\nCREATE INDEX IF NOT EXISTS idx_note_moves_new_path ON note_moves(new_path);\nCREATE INDEX IF NOT EXISTS idx_note_moves_moved_at ON note_moves(moved_at);\n\n-- Corrections (v24): persistent correction records from user/engine feedback\nCREATE TABLE IF NOT EXISTS corrections (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n entity TEXT,\n note_path TEXT,\n correction_type TEXT NOT NULL,\n description TEXT NOT NULL,\n source TEXT NOT NULL DEFAULT 'user',\n status TEXT DEFAULT 'pending',\n created_at TEXT DEFAULT (datetime('now')),\n resolved_at TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_corrections_status ON corrections(status);\nCREATE INDEX IF NOT EXISTS idx_corrections_entity ON corrections(entity);\n\n-- Memories (v26): lightweight key-value working memory for agents\nCREATE TABLE IF NOT EXISTS memories (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n key TEXT NOT NULL,\n value TEXT NOT NULL,\n memory_type TEXT NOT NULL,\n entity TEXT,\n entities_json TEXT,\n source_agent_id TEXT,\n source_session_id TEXT,\n confidence REAL NOT NULL DEFAULT 1.0,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n accessed_at INTEGER NOT NULL,\n ttl_days INTEGER,\n superseded_by INTEGER REFERENCES memories(id),\n visibility TEXT NOT NULL DEFAULT 'shared'\n);\nCREATE INDEX IF NOT EXISTS idx_memories_key ON memories(key);\nCREATE INDEX IF NOT EXISTS idx_memories_entity ON memories(entity);\nCREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n key, value,\n content=memories, content_rowid=id,\n tokenize='porter unicode61'\n);\n\n-- Auto-sync triggers for memories_fts\nCREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, key, value)\n VALUES (new.id, new.key, new.value);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, key, value)\n VALUES ('delete', old.id, old.key, old.value);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, key, value)\n VALUES ('delete', old.id, old.key, old.value);\n INSERT INTO memories_fts(rowid, key, value)\n VALUES (new.id, new.key, new.value);\nEND;\n\n-- Co-occurrence cache (v27): persist co-occurrence index to avoid full vault scan on restart\nCREATE TABLE IF NOT EXISTS cooccurrence_cache (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n data TEXT NOT NULL,\n built_at INTEGER NOT NULL,\n entity_count INTEGER NOT NULL,\n association_count INTEGER NOT NULL\n);\n\n-- Content hashes (v28): persist watcher content hashes across restarts\nCREATE TABLE IF NOT EXISTS content_hashes (\n path TEXT PRIMARY KEY,\n hash TEXT NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\n-- Session summaries (v26): agent session tracking\nCREATE TABLE IF NOT EXISTS session_summaries (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL UNIQUE,\n summary TEXT NOT NULL,\n topics_json TEXT,\n notes_modified_json TEXT,\n agent_id TEXT,\n started_at INTEGER,\n ended_at INTEGER NOT NULL,\n tool_count INTEGER\n);\n\n-- Retrieval co-occurrence (v30): notes retrieved together build implicit edges\nCREATE TABLE IF NOT EXISTS retrieval_cooccurrence (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n note_a TEXT NOT NULL,\n note_b TEXT NOT NULL,\n session_id TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n weight REAL NOT NULL DEFAULT 1.0,\n UNIQUE(note_a, note_b, session_id)\n);\nCREATE INDEX IF NOT EXISTS idx_retcooc_notes ON retrieval_cooccurrence(note_a, note_b);\nCREATE INDEX IF NOT EXISTS idx_retcooc_ts ON retrieval_cooccurrence(timestamp);\n\n-- Deferred proactive linking queue (v31)\nCREATE TABLE IF NOT EXISTS proactive_queue (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n note_path TEXT NOT NULL,\n entity TEXT NOT NULL,\n score REAL NOT NULL,\n confidence TEXT NOT NULL,\n queued_at INTEGER NOT NULL,\n expires_at INTEGER NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n applied_at INTEGER,\n UNIQUE(note_path, entity)\n);\nCREATE INDEX IF NOT EXISTS idx_pq_status ON proactive_queue(status, expires_at);\n\n-- Performance benchmarks (v33: longitudinal tracking)\nCREATE TABLE IF NOT EXISTS performance_benchmarks (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n version TEXT NOT NULL,\n benchmark TEXT NOT NULL,\n mean_ms REAL NOT NULL,\n p50_ms REAL,\n p95_ms REAL,\n iterations INTEGER NOT NULL DEFAULT 1\n);\nCREATE INDEX IF NOT EXISTS idx_perf_bench_ts ON performance_benchmarks(timestamp);\nCREATE INDEX IF NOT EXISTS idx_perf_bench_name ON performance_benchmarks(benchmark, timestamp);\n\n-- Tool selection feedback (v36: tool selection quality tracking)\nCREATE TABLE IF NOT EXISTS tool_selection_feedback (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n timestamp INTEGER NOT NULL,\n tool_invocation_id INTEGER,\n tool_name TEXT NOT NULL,\n query_context TEXT,\n expected_tool TEXT,\n expected_category TEXT,\n correct INTEGER,\n source TEXT NOT NULL DEFAULT 'explicit',\n rule_id TEXT,\n rule_version INTEGER,\n session_id TEXT,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_tsf_tool ON tool_selection_feedback(tool_name);\nCREATE INDEX IF NOT EXISTS idx_tsf_ts ON tool_selection_feedback(timestamp);\n\n-- Prospect ledger (v37): day-grain sightings for pre-entity pattern accumulation\nCREATE TABLE IF NOT EXISTS prospect_ledger (\n term TEXT NOT NULL,\n display_name TEXT NOT NULL,\n note_path TEXT NOT NULL,\n seen_day TEXT NOT NULL,\n source TEXT NOT NULL,\n pattern TEXT,\n confidence TEXT NOT NULL DEFAULT 'low',\n backlink_count INTEGER DEFAULT 0,\n score REAL DEFAULT 0,\n first_seen_at INTEGER NOT NULL,\n last_seen_at INTEGER NOT NULL,\n sighting_count INTEGER NOT NULL DEFAULT 1,\n PRIMARY KEY (term, note_path, seen_day)\n);\nCREATE INDEX IF NOT EXISTS idx_prospect_term ON prospect_ledger(term);\nCREATE INDEX IF NOT EXISTS idx_prospect_last_seen ON prospect_ledger(last_seen_at);\n\n-- Prospect summary (v37): materialized aggregate for fast scoring\nCREATE TABLE IF NOT EXISTS prospect_summary (\n term TEXT PRIMARY KEY,\n display_name TEXT NOT NULL,\n note_count INTEGER NOT NULL DEFAULT 0,\n day_count INTEGER NOT NULL DEFAULT 0,\n total_sightings INTEGER NOT NULL DEFAULT 0,\n backlink_max INTEGER NOT NULL DEFAULT 0,\n cooccurring_entities TEXT,\n best_source TEXT NOT NULL DEFAULT 'implicit',\n best_confidence TEXT NOT NULL DEFAULT 'low',\n best_score REAL NOT NULL DEFAULT 0,\n first_seen_at INTEGER NOT NULL,\n last_seen_at INTEGER NOT NULL,\n promotion_score REAL NOT NULL DEFAULT 0,\n promoted_at INTEGER,\n updated_at INTEGER NOT NULL\n);\nCREATE INDEX IF NOT EXISTS idx_prospect_summary_score ON prospect_summary(promotion_score DESC);\n\n";
|
|
14
14
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// Constants
|
|
9
9
|
// =============================================================================
|
|
10
10
|
/** Current schema version - bump when schema changes */
|
|
11
|
-
export const SCHEMA_VERSION =
|
|
11
|
+
export const SCHEMA_VERSION = 38;
|
|
12
12
|
/** State database filename */
|
|
13
13
|
export const STATE_DB_FILENAME = 'state.db';
|
|
14
14
|
/** Directory for flywheel state */
|
|
@@ -166,14 +166,15 @@ CREATE TABLE IF NOT EXISTS wikilink_suppressions (
|
|
|
166
166
|
updated_at TEXT DEFAULT (datetime('now'))
|
|
167
167
|
);
|
|
168
168
|
|
|
169
|
-
-- Wikilink applications tracking (v5: implicit feedback)
|
|
169
|
+
-- Wikilink applications tracking (v5: implicit feedback, v38: source provenance)
|
|
170
170
|
CREATE TABLE IF NOT EXISTS wikilink_applications (
|
|
171
171
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
172
172
|
entity TEXT NOT NULL,
|
|
173
173
|
note_path TEXT NOT NULL,
|
|
174
174
|
matched_term TEXT,
|
|
175
175
|
applied_at TEXT DEFAULT (datetime('now')),
|
|
176
|
-
status TEXT DEFAULT 'applied'
|
|
176
|
+
status TEXT DEFAULT 'applied',
|
|
177
|
+
source TEXT NOT NULL DEFAULT 'tool'
|
|
177
178
|
);
|
|
178
179
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_wl_apps_unique ON wikilink_applications(entity COLLATE NOCASE, note_path);
|
|
179
180
|
|
package/package.json
CHANGED