@askexenow/exe-os 0.9.92 → 0.9.94

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 (88) hide show
  1. package/deploy/compose/docker-compose.yml +1 -0
  2. package/dist/bin/agentic-ontology-backfill.js +65 -8
  3. package/dist/bin/agentic-reflection-backfill.js +54 -3
  4. package/dist/bin/agentic-semantic-label.js +54 -3
  5. package/dist/bin/backfill-conversations.js +69 -9
  6. package/dist/bin/backfill-responses.js +69 -9
  7. package/dist/bin/backfill-vectors.js +54 -3
  8. package/dist/bin/bulk-sync-postgres.js +66 -8
  9. package/dist/bin/cleanup-stale-review-tasks.js +118 -13
  10. package/dist/bin/cli.js +1605 -456
  11. package/dist/bin/customer-readiness.js +51 -0
  12. package/dist/bin/exe-agent.js +17 -3
  13. package/dist/bin/exe-assign.js +75 -9
  14. package/dist/bin/exe-boot.js +111 -12
  15. package/dist/bin/exe-call.js +17 -3
  16. package/dist/bin/exe-cloud.js +76 -10
  17. package/dist/bin/exe-dispatch.js +133 -18
  18. package/dist/bin/exe-doctor.js +75 -9
  19. package/dist/bin/exe-export-behaviors.js +75 -9
  20. package/dist/bin/exe-forget.js +94 -9
  21. package/dist/bin/exe-gateway.js +132 -18
  22. package/dist/bin/exe-heartbeat.js +118 -13
  23. package/dist/bin/exe-kill.js +75 -9
  24. package/dist/bin/exe-launch-agent.js +75 -9
  25. package/dist/bin/exe-new-employee.js +18 -4
  26. package/dist/bin/exe-pending-messages.js +118 -13
  27. package/dist/bin/exe-pending-notifications.js +118 -13
  28. package/dist/bin/exe-pending-reviews.js +118 -13
  29. package/dist/bin/exe-rename.js +75 -9
  30. package/dist/bin/exe-review.js +75 -9
  31. package/dist/bin/exe-search.js +100 -9
  32. package/dist/bin/exe-session-cleanup.js +133 -18
  33. package/dist/bin/exe-settings.js +1 -0
  34. package/dist/bin/exe-start-codex.js +65 -8
  35. package/dist/bin/exe-start-opencode.js +65 -8
  36. package/dist/bin/exe-status.js +118 -13
  37. package/dist/bin/exe-support.js +1 -0
  38. package/dist/bin/exe-team.js +75 -9
  39. package/dist/bin/git-sweep.js +133 -18
  40. package/dist/bin/graph-backfill.js +65 -8
  41. package/dist/bin/graph-export.js +75 -9
  42. package/dist/bin/intercom-check.js +133 -18
  43. package/dist/bin/scan-tasks.js +133 -18
  44. package/dist/bin/setup.js +55 -4
  45. package/dist/bin/shard-migrate.js +65 -8
  46. package/dist/bin/stack-update.js +57 -1
  47. package/dist/bin/update.js +1 -1
  48. package/dist/gateway/index.js +133 -18
  49. package/dist/hooks/bug-report-worker.js +133 -18
  50. package/dist/hooks/codex-stop-task-finalizer.js +123 -14
  51. package/dist/hooks/commit-complete.js +133 -18
  52. package/dist/hooks/error-recall.js +100 -9
  53. package/dist/hooks/ingest.js +75 -9
  54. package/dist/hooks/instructions-loaded.js +75 -9
  55. package/dist/hooks/notification.js +75 -9
  56. package/dist/hooks/post-compact.js +310 -50
  57. package/dist/hooks/post-tool-combined.js +433 -13
  58. package/dist/hooks/pre-compact.js +133 -18
  59. package/dist/hooks/pre-tool-use.js +118 -13
  60. package/dist/hooks/prompt-submit.js +191 -19
  61. package/dist/hooks/session-end.js +133 -18
  62. package/dist/hooks/session-start.js +143 -13
  63. package/dist/hooks/stop.js +118 -13
  64. package/dist/hooks/subagent-stop.js +118 -13
  65. package/dist/hooks/summary-worker.js +96 -7
  66. package/dist/index.js +133 -18
  67. package/dist/lib/cloud-sync.js +38 -0
  68. package/dist/lib/consolidation.js +3 -1
  69. package/dist/lib/database.js +37 -0
  70. package/dist/lib/db.js +37 -0
  71. package/dist/lib/device-registry.js +37 -0
  72. package/dist/lib/employee-templates.js +17 -3
  73. package/dist/lib/exe-daemon.js +913 -42
  74. package/dist/lib/hybrid-search.js +100 -9
  75. package/dist/lib/license.js +1 -1
  76. package/dist/lib/messaging.js +40 -4
  77. package/dist/lib/schedules.js +54 -3
  78. package/dist/lib/store.js +75 -9
  79. package/dist/lib/tasks.js +58 -9
  80. package/dist/lib/tmux-routing.js +58 -9
  81. package/dist/mcp/server.js +875 -42
  82. package/dist/mcp/tools/create-task.js +67 -12
  83. package/dist/mcp/tools/list-tasks.js +46 -5
  84. package/dist/mcp/tools/send-message.js +40 -4
  85. package/dist/mcp/tools/update-task.js +58 -9
  86. package/dist/runtime/index.js +133 -18
  87. package/dist/tui/App.js +132 -18
  88. package/package.json +1 -1
@@ -296,6 +296,7 @@ services:
296
296
  WHATSAPP_ACCESS_TOKEN: ${WHATSAPP_ACCESS_TOKEN:-}
297
297
  API_ROUTER_URL: ${API_ROUTER_URL:-https://gateway.askexe.com}
298
298
  API_ROUTER_KEY: ${API_ROUTER_KEY:-}
299
+ EXED_MCP_URL: http://exed:8765/mcp
299
300
  BYOK_ENABLED: ${BYOK_ENABLED:-false}
300
301
  ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
301
302
  EXE_LICENSE_KEY: ${EXE_LICENSE_KEY:?EXE_LICENSE_KEY is required — purchase at https://askexe.com}
@@ -2550,6 +2550,20 @@ async function ensureSchema() {
2550
2550
  });
2551
2551
  } catch {
2552
2552
  }
2553
+ try {
2554
+ await client.execute({
2555
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2556
+ args: []
2557
+ });
2558
+ } catch {
2559
+ }
2560
+ try {
2561
+ await client.execute({
2562
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2563
+ args: []
2564
+ });
2565
+ } catch {
2566
+ }
2553
2567
  await client.executeMultiple(`
2554
2568
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2555
2569
  content_text,
@@ -2801,6 +2815,22 @@ async function ensureSchema() {
2801
2815
  );
2802
2816
  } catch {
2803
2817
  }
2818
+ for (const col of [
2819
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2820
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2821
+ ]) {
2822
+ try {
2823
+ await client.execute(col);
2824
+ } catch {
2825
+ }
2826
+ }
2827
+ try {
2828
+ await client.execute({
2829
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2830
+ args: []
2831
+ });
2832
+ } catch {
2833
+ }
2804
2834
  try {
2805
2835
  await client.execute({
2806
2836
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2843,6 +2873,13 @@ async function ensureSchema() {
2843
2873
  } catch {
2844
2874
  }
2845
2875
  }
2876
+ try {
2877
+ await client.execute({
2878
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
2879
+ args: []
2880
+ });
2881
+ } catch {
2882
+ }
2846
2883
  try {
2847
2884
  await client.execute({
2848
2885
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3424,6 +3461,20 @@ var init_platform_procedures = __esm({
3424
3461
  priority: "p1",
3425
3462
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3426
3463
  },
3464
+ // --- Tool guidance ---
3465
+ {
3466
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3467
+ domain: "tools",
3468
+ priority: "p2",
3469
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3470
+ },
3471
+ // --- Release awareness ---
3472
+ {
3473
+ title: "What's New check \u2014 surface new features after update",
3474
+ domain: "support",
3475
+ priority: "p1",
3476
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3477
+ },
3427
3478
  // --- Platform vs Customer ownership ---
3428
3479
  {
3429
3480
  title: "What the platform provides vs what you customize",
@@ -3512,13 +3563,13 @@ var init_platform_procedures = __esm({
3512
3563
  title: "MCP tools \u2014 memory, decision, and search",
3513
3564
  domain: "tool-use",
3514
3565
  priority: "p1",
3515
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3566
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3516
3567
  },
3517
3568
  {
3518
3569
  title: "MCP tools \u2014 task orchestration",
3519
3570
  domain: "tool-use",
3520
3571
  priority: "p1",
3521
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3572
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3522
3573
  },
3523
3574
  {
3524
3575
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3548,7 +3599,7 @@ var init_platform_procedures = __esm({
3548
3599
  title: "MCP tools \u2014 admin, config, and operations",
3549
3600
  domain: "tool-use",
3550
3601
  priority: "p1",
3551
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3602
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3552
3603
  }
3553
3604
  ];
3554
3605
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4606,6 +4657,8 @@ async function flushBatch() {
4606
4657
  const sourceType = row.source_type ?? null;
4607
4658
  const tier = row.tier ?? 3;
4608
4659
  const supersedesId = row.supersedes_id ?? null;
4660
+ const validFrom = row.valid_from ?? row.timestamp;
4661
+ const invalidAt = row.invalid_at ?? null;
4609
4662
  const draft = row.draft ? 1 : 0;
4610
4663
  const memoryType = row.memory_type ?? "raw";
4611
4664
  const trajectory = row.trajectory ?? null;
@@ -4625,15 +4678,16 @@ async function flushBatch() {
4625
4678
  const audience = row.audience ?? null;
4626
4679
  const languageType = row.language_type ?? null;
4627
4680
  const parentMemoryId = row.parent_memory_id ?? null;
4681
+ const procedureFor = row.procedure_for ?? null;
4628
4682
  const cols = `id, agent_id, agent_role, session_id, timestamp,
4629
4683
  tool_name, project_name,
4630
4684
  has_error, raw_text, vector, version, task_id, importance, status,
4631
4685
  confidence, last_accessed,
4632
4686
  workspace_id, document_id, user_id, char_offset, page_number,
4633
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
4687
+ source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
4634
4688
  intent, outcome, domain, referenced_entities, retrieval_count,
4635
4689
  chain_position, review_status, context_window_pct, file_paths, commit_hash,
4636
- duration_ms, token_cost, audience, language_type, parent_memory_id`;
4690
+ duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
4637
4691
  const metaArgs = [
4638
4692
  intent,
4639
4693
  outcome,
@@ -4649,7 +4703,8 @@ async function flushBatch() {
4649
4703
  tokenCost,
4650
4704
  audience,
4651
4705
  languageType,
4652
- parentMemoryId
4706
+ parentMemoryId,
4707
+ procedureFor
4653
4708
  ];
4654
4709
  const baseArgs = [
4655
4710
  row.id,
@@ -4678,6 +4733,8 @@ async function flushBatch() {
4678
4733
  sourceType,
4679
4734
  tier,
4680
4735
  supersedesId,
4736
+ validFrom,
4737
+ invalidAt,
4681
4738
  draft,
4682
4739
  memoryType,
4683
4740
  trajectory,
@@ -4685,8 +4742,8 @@ async function flushBatch() {
4685
4742
  ];
4686
4743
  return {
4687
4744
  sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
4688
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
4689
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
4745
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
4746
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
4690
4747
  args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
4691
4748
  };
4692
4749
  };
@@ -2550,6 +2550,20 @@ async function ensureSchema() {
2550
2550
  });
2551
2551
  } catch {
2552
2552
  }
2553
+ try {
2554
+ await client.execute({
2555
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2556
+ args: []
2557
+ });
2558
+ } catch {
2559
+ }
2560
+ try {
2561
+ await client.execute({
2562
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2563
+ args: []
2564
+ });
2565
+ } catch {
2566
+ }
2553
2567
  await client.executeMultiple(`
2554
2568
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2555
2569
  content_text,
@@ -2801,6 +2815,22 @@ async function ensureSchema() {
2801
2815
  );
2802
2816
  } catch {
2803
2817
  }
2818
+ for (const col of [
2819
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2820
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2821
+ ]) {
2822
+ try {
2823
+ await client.execute(col);
2824
+ } catch {
2825
+ }
2826
+ }
2827
+ try {
2828
+ await client.execute({
2829
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2830
+ args: []
2831
+ });
2832
+ } catch {
2833
+ }
2804
2834
  try {
2805
2835
  await client.execute({
2806
2836
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2843,6 +2873,13 @@ async function ensureSchema() {
2843
2873
  } catch {
2844
2874
  }
2845
2875
  }
2876
+ try {
2877
+ await client.execute({
2878
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
2879
+ args: []
2880
+ });
2881
+ } catch {
2882
+ }
2846
2883
  try {
2847
2884
  await client.execute({
2848
2885
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3424,6 +3461,20 @@ var init_platform_procedures = __esm({
3424
3461
  priority: "p1",
3425
3462
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3426
3463
  },
3464
+ // --- Tool guidance ---
3465
+ {
3466
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3467
+ domain: "tools",
3468
+ priority: "p2",
3469
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3470
+ },
3471
+ // --- Release awareness ---
3472
+ {
3473
+ title: "What's New check \u2014 surface new features after update",
3474
+ domain: "support",
3475
+ priority: "p1",
3476
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3477
+ },
3427
3478
  // --- Platform vs Customer ownership ---
3428
3479
  {
3429
3480
  title: "What the platform provides vs what you customize",
@@ -3512,13 +3563,13 @@ var init_platform_procedures = __esm({
3512
3563
  title: "MCP tools \u2014 memory, decision, and search",
3513
3564
  domain: "tool-use",
3514
3565
  priority: "p1",
3515
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3566
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3516
3567
  },
3517
3568
  {
3518
3569
  title: "MCP tools \u2014 task orchestration",
3519
3570
  domain: "tool-use",
3520
3571
  priority: "p1",
3521
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3572
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3522
3573
  },
3523
3574
  {
3524
3575
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3548,7 +3599,7 @@ var init_platform_procedures = __esm({
3548
3599
  title: "MCP tools \u2014 admin, config, and operations",
3549
3600
  domain: "tool-use",
3550
3601
  priority: "p1",
3551
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3602
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3552
3603
  }
3553
3604
  ];
3554
3605
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -2550,6 +2550,20 @@ async function ensureSchema() {
2550
2550
  });
2551
2551
  } catch {
2552
2552
  }
2553
+ try {
2554
+ await client.execute({
2555
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2556
+ args: []
2557
+ });
2558
+ } catch {
2559
+ }
2560
+ try {
2561
+ await client.execute({
2562
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2563
+ args: []
2564
+ });
2565
+ } catch {
2566
+ }
2553
2567
  await client.executeMultiple(`
2554
2568
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2555
2569
  content_text,
@@ -2801,6 +2815,22 @@ async function ensureSchema() {
2801
2815
  );
2802
2816
  } catch {
2803
2817
  }
2818
+ for (const col of [
2819
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2820
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2821
+ ]) {
2822
+ try {
2823
+ await client.execute(col);
2824
+ } catch {
2825
+ }
2826
+ }
2827
+ try {
2828
+ await client.execute({
2829
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2830
+ args: []
2831
+ });
2832
+ } catch {
2833
+ }
2804
2834
  try {
2805
2835
  await client.execute({
2806
2836
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2843,6 +2873,13 @@ async function ensureSchema() {
2843
2873
  } catch {
2844
2874
  }
2845
2875
  }
2876
+ try {
2877
+ await client.execute({
2878
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
2879
+ args: []
2880
+ });
2881
+ } catch {
2882
+ }
2846
2883
  try {
2847
2884
  await client.execute({
2848
2885
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3424,6 +3461,20 @@ var init_platform_procedures = __esm({
3424
3461
  priority: "p1",
3425
3462
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3426
3463
  },
3464
+ // --- Tool guidance ---
3465
+ {
3466
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3467
+ domain: "tools",
3468
+ priority: "p2",
3469
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3470
+ },
3471
+ // --- Release awareness ---
3472
+ {
3473
+ title: "What's New check \u2014 surface new features after update",
3474
+ domain: "support",
3475
+ priority: "p1",
3476
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3477
+ },
3427
3478
  // --- Platform vs Customer ownership ---
3428
3479
  {
3429
3480
  title: "What the platform provides vs what you customize",
@@ -3512,13 +3563,13 @@ var init_platform_procedures = __esm({
3512
3563
  title: "MCP tools \u2014 memory, decision, and search",
3513
3564
  domain: "tool-use",
3514
3565
  priority: "p1",
3515
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3566
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3516
3567
  },
3517
3568
  {
3518
3569
  title: "MCP tools \u2014 task orchestration",
3519
3570
  domain: "tool-use",
3520
3571
  priority: "p1",
3521
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3572
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3522
3573
  },
3523
3574
  {
3524
3575
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3548,7 +3599,7 @@ var init_platform_procedures = __esm({
3548
3599
  title: "MCP tools \u2014 admin, config, and operations",
3549
3600
  domain: "tool-use",
3550
3601
  priority: "p1",
3551
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3602
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3552
3603
  }
3553
3604
  ];
3554
3605
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -2690,6 +2690,20 @@ async function ensureSchema() {
2690
2690
  });
2691
2691
  } catch {
2692
2692
  }
2693
+ try {
2694
+ await client.execute({
2695
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
2696
+ args: []
2697
+ });
2698
+ } catch {
2699
+ }
2700
+ try {
2701
+ await client.execute({
2702
+ sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
2703
+ args: []
2704
+ });
2705
+ } catch {
2706
+ }
2693
2707
  await client.executeMultiple(`
2694
2708
  CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
2695
2709
  content_text,
@@ -2941,6 +2955,22 @@ async function ensureSchema() {
2941
2955
  );
2942
2956
  } catch {
2943
2957
  }
2958
+ for (const col of [
2959
+ "ALTER TABLE memories ADD COLUMN valid_from TEXT",
2960
+ "ALTER TABLE memories ADD COLUMN invalid_at TEXT"
2961
+ ]) {
2962
+ try {
2963
+ await client.execute(col);
2964
+ } catch {
2965
+ }
2966
+ }
2967
+ try {
2968
+ await client.execute({
2969
+ sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
2970
+ args: []
2971
+ });
2972
+ } catch {
2973
+ }
2944
2974
  try {
2945
2975
  await client.execute({
2946
2976
  sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
@@ -2983,6 +3013,13 @@ async function ensureSchema() {
2983
3013
  } catch {
2984
3014
  }
2985
3015
  }
3016
+ try {
3017
+ await client.execute({
3018
+ sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
3019
+ args: []
3020
+ });
3021
+ } catch {
3022
+ }
2986
3023
  try {
2987
3024
  await client.execute({
2988
3025
  sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
@@ -3564,6 +3601,20 @@ var init_platform_procedures = __esm({
3564
3601
  priority: "p1",
3565
3602
  content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
3566
3603
  },
3604
+ // --- Tool guidance ---
3605
+ {
3606
+ title: "How to use company_actions \u2014 execute business actions through gateway connectors",
3607
+ domain: "tools",
3608
+ priority: "p2",
3609
+ content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
3610
+ },
3611
+ // --- Release awareness ---
3612
+ {
3613
+ title: "What's New check \u2014 surface new features after update",
3614
+ domain: "support",
3615
+ priority: "p1",
3616
+ content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
3617
+ },
3567
3618
  // --- Platform vs Customer ownership ---
3568
3619
  {
3569
3620
  title: "What the platform provides vs what you customize",
@@ -3652,13 +3703,13 @@ var init_platform_procedures = __esm({
3652
3703
  title: "MCP tools \u2014 memory, decision, and search",
3653
3704
  domain: "tool-use",
3654
3705
  priority: "p1",
3655
- content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3706
+ content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
3656
3707
  },
3657
3708
  {
3658
3709
  title: "MCP tools \u2014 task orchestration",
3659
3710
  domain: "tool-use",
3660
3711
  priority: "p1",
3661
- content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.'
3712
+ content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
3662
3713
  },
3663
3714
  {
3664
3715
  title: "MCP tools \u2014 knowledge graph (GraphRAG)",
@@ -3688,7 +3739,7 @@ var init_platform_procedures = __esm({
3688
3739
  title: "MCP tools \u2014 admin, config, and operations",
3689
3740
  domain: "tool-use",
3690
3741
  priority: "p1",
3691
- content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
3742
+ content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
3692
3743
  }
3693
3744
  ];
3694
3745
  PLATFORM_PROCEDURE_TITLES = new Set(
@@ -4918,6 +4969,8 @@ async function writeMemory(record) {
4918
4969
  source_type: record.source_type ?? null,
4919
4970
  tier: record.tier ?? classifyTier(record),
4920
4971
  supersedes_id: record.supersedes_id ?? null,
4972
+ valid_from: record.valid_from ?? record.timestamp,
4973
+ invalid_at: record.invalid_at ?? null,
4921
4974
  draft: record.draft ? 1 : 0,
4922
4975
  memory_type: memoryType,
4923
4976
  trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
@@ -4936,7 +4989,8 @@ async function writeMemory(record) {
4936
4989
  token_cost: record.token_cost ?? null,
4937
4990
  audience: record.audience ?? null,
4938
4991
  language_type: record.language_type ?? inferLanguageType(record),
4939
- parent_memory_id: record.parent_memory_id ?? null
4992
+ parent_memory_id: record.parent_memory_id ?? null,
4993
+ procedure_for: record.procedure_for ?? null
4940
4994
  };
4941
4995
  _pendingRecords.push(dbRow);
4942
4996
  orgBus.emit({
@@ -4991,6 +5045,8 @@ async function flushBatch() {
4991
5045
  const sourceType = row.source_type ?? null;
4992
5046
  const tier = row.tier ?? 3;
4993
5047
  const supersedesId = row.supersedes_id ?? null;
5048
+ const validFrom = row.valid_from ?? row.timestamp;
5049
+ const invalidAt = row.invalid_at ?? null;
4994
5050
  const draft = row.draft ? 1 : 0;
4995
5051
  const memoryType = row.memory_type ?? "raw";
4996
5052
  const trajectory = row.trajectory ?? null;
@@ -5010,15 +5066,16 @@ async function flushBatch() {
5010
5066
  const audience = row.audience ?? null;
5011
5067
  const languageType = row.language_type ?? null;
5012
5068
  const parentMemoryId = row.parent_memory_id ?? null;
5069
+ const procedureFor = row.procedure_for ?? null;
5013
5070
  const cols = `id, agent_id, agent_role, session_id, timestamp,
5014
5071
  tool_name, project_name,
5015
5072
  has_error, raw_text, vector, version, task_id, importance, status,
5016
5073
  confidence, last_accessed,
5017
5074
  workspace_id, document_id, user_id, char_offset, page_number,
5018
- source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
5075
+ source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
5019
5076
  intent, outcome, domain, referenced_entities, retrieval_count,
5020
5077
  chain_position, review_status, context_window_pct, file_paths, commit_hash,
5021
- duration_ms, token_cost, audience, language_type, parent_memory_id`;
5078
+ duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
5022
5079
  const metaArgs = [
5023
5080
  intent,
5024
5081
  outcome,
@@ -5034,7 +5091,8 @@ async function flushBatch() {
5034
5091
  tokenCost,
5035
5092
  audience,
5036
5093
  languageType,
5037
- parentMemoryId
5094
+ parentMemoryId,
5095
+ procedureFor
5038
5096
  ];
5039
5097
  const baseArgs = [
5040
5098
  row.id,
@@ -5063,6 +5121,8 @@ async function flushBatch() {
5063
5121
  sourceType,
5064
5122
  tier,
5065
5123
  supersedesId,
5124
+ validFrom,
5125
+ invalidAt,
5066
5126
  draft,
5067
5127
  memoryType,
5068
5128
  trajectory,
@@ -5070,8 +5130,8 @@ async function flushBatch() {
5070
5130
  ];
5071
5131
  return {
5072
5132
  sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
5073
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
5074
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
5133
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
5134
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
5075
5135
  args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
5076
5136
  };
5077
5137
  };