@askexenow/exe-os 0.9.105 → 0.9.107

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 (89) hide show
  1. package/dist/bin/agentic-ontology-backfill.js +10 -8
  2. package/dist/bin/agentic-reflection-backfill.js +10 -8
  3. package/dist/bin/agentic-semantic-label.js +10 -8
  4. package/dist/bin/backfill-conversations.js +10 -8
  5. package/dist/bin/backfill-responses.js +10 -8
  6. package/dist/bin/backfill-vectors.js +10 -8
  7. package/dist/bin/bulk-sync-postgres.js +10 -8
  8. package/dist/bin/cleanup-stale-review-tasks.js +10 -8
  9. package/dist/bin/cli.js +10 -8
  10. package/dist/bin/exe-agent.js +1 -7
  11. package/dist/bin/exe-assign.js +10 -8
  12. package/dist/bin/exe-boot.js +10 -8
  13. package/dist/bin/exe-call.js +1 -7
  14. package/dist/bin/exe-cloud.js +10 -8
  15. package/dist/bin/exe-dispatch.js +10 -8
  16. package/dist/bin/exe-doctor.js +10 -8
  17. package/dist/bin/exe-export-behaviors.js +10 -8
  18. package/dist/bin/exe-forget.js +36 -9
  19. package/dist/bin/exe-gateway.js +10 -8
  20. package/dist/bin/exe-heartbeat.js +10 -8
  21. package/dist/bin/exe-kill.js +10 -8
  22. package/dist/bin/exe-launch-agent.js +10 -8
  23. package/dist/bin/exe-new-employee.js +10 -8
  24. package/dist/bin/exe-pending-messages.js +10 -8
  25. package/dist/bin/exe-pending-notifications.js +10 -8
  26. package/dist/bin/exe-pending-reviews.js +10 -8
  27. package/dist/bin/exe-rename.js +10 -8
  28. package/dist/bin/exe-review.js +10 -8
  29. package/dist/bin/exe-search.js +36 -9
  30. package/dist/bin/exe-session-cleanup.js +10 -8
  31. package/dist/bin/exe-start-codex.js +10 -8
  32. package/dist/bin/exe-start-opencode.js +10 -8
  33. package/dist/bin/exe-status.js +10 -8
  34. package/dist/bin/exe-team.js +10 -8
  35. package/dist/bin/git-sweep.js +10 -8
  36. package/dist/bin/graph-backfill.js +10 -8
  37. package/dist/bin/graph-export.js +10 -8
  38. package/dist/bin/intercom-check.js +10 -8
  39. package/dist/bin/pre-publish.js +1 -7
  40. package/dist/bin/scan-tasks.js +10 -8
  41. package/dist/bin/setup.js +10 -8
  42. package/dist/bin/shard-migrate.js +10 -8
  43. package/dist/gateway/index.js +10 -8
  44. package/dist/hooks/bug-report-worker.js +10 -8
  45. package/dist/hooks/codex-stop-task-finalizer.js +10 -8
  46. package/dist/hooks/commit-complete.js +10 -8
  47. package/dist/hooks/error-recall.js +36 -9
  48. package/dist/hooks/ingest.js +10 -8
  49. package/dist/hooks/instructions-loaded.js +10 -8
  50. package/dist/hooks/notification.js +10 -8
  51. package/dist/hooks/post-compact.js +10 -8
  52. package/dist/hooks/post-tool-combined.js +36 -9
  53. package/dist/hooks/pre-compact.js +10 -8
  54. package/dist/hooks/pre-tool-use.js +10 -8
  55. package/dist/hooks/prompt-submit.js +36 -9
  56. package/dist/hooks/session-end.js +10 -8
  57. package/dist/hooks/session-start.js +36 -9
  58. package/dist/hooks/stop.js +10 -8
  59. package/dist/hooks/subagent-stop.js +10 -8
  60. package/dist/hooks/summary-worker.js +10 -8
  61. package/dist/index.js +10 -8
  62. package/dist/lib/cloud-sync.js +9 -1
  63. package/dist/lib/database.js +9 -1
  64. package/dist/lib/db.js +9 -1
  65. package/dist/lib/device-registry.js +9 -1
  66. package/dist/lib/employee-templates.js +1 -7
  67. package/dist/lib/exe-daemon.js +36 -9
  68. package/dist/lib/hybrid-search.js +36 -9
  69. package/dist/lib/identity.js +9 -1
  70. package/dist/lib/messaging.js +9 -1
  71. package/dist/lib/reminders.js +9 -1
  72. package/dist/lib/schedules.js +10 -8
  73. package/dist/lib/skill-learning.js +9 -1
  74. package/dist/lib/store.js +10 -8
  75. package/dist/lib/tasks.js +9 -1
  76. package/dist/lib/tmux-routing.js +9 -1
  77. package/dist/lib/token-spend.js +9 -1
  78. package/dist/mcp/server.js +36 -9
  79. package/dist/mcp/tools/complete-reminder.js +9 -1
  80. package/dist/mcp/tools/create-reminder.js +9 -1
  81. package/dist/mcp/tools/create-task.js +9 -1
  82. package/dist/mcp/tools/deactivate-behavior.js +9 -1
  83. package/dist/mcp/tools/list-reminders.js +9 -1
  84. package/dist/mcp/tools/list-tasks.js +9 -1
  85. package/dist/mcp/tools/send-message.js +9 -1
  86. package/dist/mcp/tools/update-task.js +9 -1
  87. package/dist/runtime/index.js +10 -8
  88. package/dist/tui/App.js +10 -8
  89. package/package.json +1 -1
@@ -1606,7 +1606,15 @@ function getClient() {
1606
1606
  if (!_resilientClient) {
1607
1607
  return _adapterClient;
1608
1608
  }
1609
- return _resilientClient;
1609
+ if (process.env.EXE_DB_READONLY === "1") {
1610
+ return _resilientClient;
1611
+ }
1612
+ process.stderr.write(
1613
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1614
+ );
1615
+ throw new Error(
1616
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1617
+ );
1610
1618
  }
1611
1619
  async function initDaemonClient() {
1612
1620
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3660,7 +3668,7 @@ var init_platform_procedures = __esm({
3660
3668
  title: "What the platform provides vs what you customize",
3661
3669
  domain: "architecture",
3662
3670
  priority: "p0",
3663
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3671
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3664
3672
  },
3665
3673
  // --- Updates ---
3666
3674
  {
@@ -3737,12 +3745,6 @@ var init_platform_procedures = __esm({
3737
3745
  priority: "p0",
3738
3746
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3739
3747
  },
3740
- {
3741
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3742
- domain: "workflow",
3743
- priority: "p0",
3744
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3745
- },
3746
3748
  {
3747
3749
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3748
3750
  domain: "architecture",
@@ -1606,7 +1606,15 @@ function getClient() {
1606
1606
  if (!_resilientClient) {
1607
1607
  return _adapterClient;
1608
1608
  }
1609
- return _resilientClient;
1609
+ if (process.env.EXE_DB_READONLY === "1") {
1610
+ return _resilientClient;
1611
+ }
1612
+ process.stderr.write(
1613
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1614
+ );
1615
+ throw new Error(
1616
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1617
+ );
1610
1618
  }
1611
1619
  async function initDaemonClient() {
1612
1620
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3660,7 +3668,7 @@ var init_platform_procedures = __esm({
3660
3668
  title: "What the platform provides vs what you customize",
3661
3669
  domain: "architecture",
3662
3670
  priority: "p0",
3663
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3671
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3664
3672
  },
3665
3673
  // --- Updates ---
3666
3674
  {
@@ -3737,12 +3745,6 @@ var init_platform_procedures = __esm({
3737
3745
  priority: "p0",
3738
3746
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3739
3747
  },
3740
- {
3741
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3742
- domain: "workflow",
3743
- priority: "p0",
3744
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3745
- },
3746
3748
  {
3747
3749
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3748
3750
  domain: "architecture",
@@ -1606,7 +1606,15 @@ function getClient() {
1606
1606
  if (!_resilientClient) {
1607
1607
  return _adapterClient;
1608
1608
  }
1609
- return _resilientClient;
1609
+ if (process.env.EXE_DB_READONLY === "1") {
1610
+ return _resilientClient;
1611
+ }
1612
+ process.stderr.write(
1613
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1614
+ );
1615
+ throw new Error(
1616
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1617
+ );
1610
1618
  }
1611
1619
  async function initDaemonClient() {
1612
1620
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3660,7 +3668,7 @@ var init_platform_procedures = __esm({
3660
3668
  title: "What the platform provides vs what you customize",
3661
3669
  domain: "architecture",
3662
3670
  priority: "p0",
3663
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3671
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3664
3672
  },
3665
3673
  // --- Updates ---
3666
3674
  {
@@ -3737,12 +3745,6 @@ var init_platform_procedures = __esm({
3737
3745
  priority: "p0",
3738
3746
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3739
3747
  },
3740
- {
3741
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3742
- domain: "workflow",
3743
- priority: "p0",
3744
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3745
- },
3746
3748
  {
3747
3749
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3748
3750
  domain: "architecture",
@@ -1746,7 +1746,15 @@ function getClient() {
1746
1746
  if (!_resilientClient) {
1747
1747
  return _adapterClient;
1748
1748
  }
1749
- return _resilientClient;
1749
+ if (process.env.EXE_DB_READONLY === "1") {
1750
+ return _resilientClient;
1751
+ }
1752
+ process.stderr.write(
1753
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1754
+ );
1755
+ throw new Error(
1756
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1757
+ );
1750
1758
  }
1751
1759
  async function initDaemonClient() {
1752
1760
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3800,7 +3808,7 @@ var init_platform_procedures = __esm({
3800
3808
  title: "What the platform provides vs what you customize",
3801
3809
  domain: "architecture",
3802
3810
  priority: "p0",
3803
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3811
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3804
3812
  },
3805
3813
  // --- Updates ---
3806
3814
  {
@@ -3877,12 +3885,6 @@ var init_platform_procedures = __esm({
3877
3885
  priority: "p0",
3878
3886
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3879
3887
  },
3880
- {
3881
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3882
- domain: "workflow",
3883
- priority: "p0",
3884
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3885
- },
3886
3888
  {
3887
3889
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3888
3890
  domain: "architecture",
@@ -1746,7 +1746,15 @@ function getClient() {
1746
1746
  if (!_resilientClient) {
1747
1747
  return _adapterClient;
1748
1748
  }
1749
- return _resilientClient;
1749
+ if (process.env.EXE_DB_READONLY === "1") {
1750
+ return _resilientClient;
1751
+ }
1752
+ process.stderr.write(
1753
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1754
+ );
1755
+ throw new Error(
1756
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1757
+ );
1750
1758
  }
1751
1759
  async function initDaemonClient() {
1752
1760
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3800,7 +3808,7 @@ var init_platform_procedures = __esm({
3800
3808
  title: "What the platform provides vs what you customize",
3801
3809
  domain: "architecture",
3802
3810
  priority: "p0",
3803
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3811
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3804
3812
  },
3805
3813
  // --- Updates ---
3806
3814
  {
@@ -3877,12 +3885,6 @@ var init_platform_procedures = __esm({
3877
3885
  priority: "p0",
3878
3886
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3879
3887
  },
3880
- {
3881
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3882
- domain: "workflow",
3883
- priority: "p0",
3884
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3885
- },
3886
3888
  {
3887
3889
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3888
3890
  domain: "architecture",
@@ -1742,7 +1742,15 @@ function getClient() {
1742
1742
  if (!_resilientClient) {
1743
1743
  return _adapterClient;
1744
1744
  }
1745
- return _resilientClient;
1745
+ if (process.env.EXE_DB_READONLY === "1") {
1746
+ return _resilientClient;
1747
+ }
1748
+ process.stderr.write(
1749
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1750
+ );
1751
+ throw new Error(
1752
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1753
+ );
1746
1754
  }
1747
1755
  async function initDaemonClient() {
1748
1756
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3796,7 +3804,7 @@ var init_platform_procedures = __esm({
3796
3804
  title: "What the platform provides vs what you customize",
3797
3805
  domain: "architecture",
3798
3806
  priority: "p0",
3799
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3807
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3800
3808
  },
3801
3809
  // --- Updates ---
3802
3810
  {
@@ -3873,12 +3881,6 @@ var init_platform_procedures = __esm({
3873
3881
  priority: "p0",
3874
3882
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3875
3883
  },
3876
- {
3877
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3878
- domain: "workflow",
3879
- priority: "p0",
3880
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3881
- },
3882
3884
  {
3883
3885
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3884
3886
  domain: "architecture",
@@ -1606,7 +1606,15 @@ function getClient() {
1606
1606
  if (!_resilientClient) {
1607
1607
  return _adapterClient;
1608
1608
  }
1609
- return _resilientClient;
1609
+ if (process.env.EXE_DB_READONLY === "1") {
1610
+ return _resilientClient;
1611
+ }
1612
+ process.stderr.write(
1613
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1614
+ );
1615
+ throw new Error(
1616
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1617
+ );
1610
1618
  }
1611
1619
  async function initDaemonClient() {
1612
1620
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3968,7 +3976,7 @@ var init_platform_procedures = __esm({
3968
3976
  title: "What the platform provides vs what you customize",
3969
3977
  domain: "architecture",
3970
3978
  priority: "p0",
3971
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3979
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3972
3980
  },
3973
3981
  // --- Updates ---
3974
3982
  {
@@ -4045,12 +4053,6 @@ var init_platform_procedures = __esm({
4045
4053
  priority: "p0",
4046
4054
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
4047
4055
  },
4048
- {
4049
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
4050
- domain: "workflow",
4051
- priority: "p0",
4052
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
4053
- },
4054
4056
  {
4055
4057
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
4056
4058
  domain: "architecture",
@@ -1832,7 +1832,15 @@ function getClient() {
1832
1832
  if (!_resilientClient) {
1833
1833
  return _adapterClient;
1834
1834
  }
1835
- return _resilientClient;
1835
+ if (process.env.EXE_DB_READONLY === "1") {
1836
+ return _resilientClient;
1837
+ }
1838
+ process.stderr.write(
1839
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1840
+ );
1841
+ throw new Error(
1842
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1843
+ );
1836
1844
  }
1837
1845
  async function initDaemonClient() {
1838
1846
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -4443,7 +4451,7 @@ var init_platform_procedures = __esm({
4443
4451
  title: "What the platform provides vs what you customize",
4444
4452
  domain: "architecture",
4445
4453
  priority: "p0",
4446
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
4454
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
4447
4455
  },
4448
4456
  // --- Updates ---
4449
4457
  {
@@ -4520,12 +4528,6 @@ var init_platform_procedures = __esm({
4520
4528
  priority: "p0",
4521
4529
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
4522
4530
  },
4523
- {
4524
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
4525
- domain: "workflow",
4526
- priority: "p0",
4527
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
4528
- },
4529
4531
  {
4530
4532
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
4531
4533
  domain: "architecture",
package/dist/bin/cli.js CHANGED
@@ -4487,7 +4487,15 @@ function getClient() {
4487
4487
  if (!_resilientClient) {
4488
4488
  return _adapterClient;
4489
4489
  }
4490
- return _resilientClient;
4490
+ if (process.env.EXE_DB_READONLY === "1") {
4491
+ return _resilientClient;
4492
+ }
4493
+ process.stderr.write(
4494
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
4495
+ );
4496
+ throw new Error(
4497
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
4498
+ );
4491
4499
  }
4492
4500
  async function initDaemonClient() {
4493
4501
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -9149,7 +9157,7 @@ var init_platform_procedures = __esm({
9149
9157
  title: "What the platform provides vs what you customize",
9150
9158
  domain: "architecture",
9151
9159
  priority: "p0",
9152
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
9160
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
9153
9161
  },
9154
9162
  // --- Updates ---
9155
9163
  {
@@ -9226,12 +9234,6 @@ var init_platform_procedures = __esm({
9226
9234
  priority: "p0",
9227
9235
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
9228
9236
  },
9229
- {
9230
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
9231
- domain: "workflow",
9232
- priority: "p0",
9233
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
9234
- },
9235
9237
  {
9236
9238
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
9237
9239
  domain: "architecture",
@@ -1434,7 +1434,7 @@ var PLATFORM_PROCEDURES = [
1434
1434
  title: "What the platform provides vs what you customize",
1435
1435
  domain: "architecture",
1436
1436
  priority: "p0",
1437
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
1437
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
1438
1438
  },
1439
1439
  // --- Updates ---
1440
1440
  {
@@ -1511,12 +1511,6 @@ var PLATFORM_PROCEDURES = [
1511
1511
  priority: "p0",
1512
1512
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
1513
1513
  },
1514
- {
1515
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
1516
- domain: "workflow",
1517
- priority: "p0",
1518
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
1519
- },
1520
1514
  {
1521
1515
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
1522
1516
  domain: "architecture",
@@ -1756,7 +1756,15 @@ function getClient() {
1756
1756
  if (!_resilientClient) {
1757
1757
  return _adapterClient;
1758
1758
  }
1759
- return _resilientClient;
1759
+ if (process.env.EXE_DB_READONLY === "1") {
1760
+ return _resilientClient;
1761
+ }
1762
+ process.stderr.write(
1763
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1764
+ );
1765
+ throw new Error(
1766
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1767
+ );
1760
1768
  }
1761
1769
  async function initDaemonClient() {
1762
1770
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3810,7 +3818,7 @@ var init_platform_procedures = __esm({
3810
3818
  title: "What the platform provides vs what you customize",
3811
3819
  domain: "architecture",
3812
3820
  priority: "p0",
3813
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3821
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3814
3822
  },
3815
3823
  // --- Updates ---
3816
3824
  {
@@ -3887,12 +3895,6 @@ var init_platform_procedures = __esm({
3887
3895
  priority: "p0",
3888
3896
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3889
3897
  },
3890
- {
3891
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3892
- domain: "workflow",
3893
- priority: "p0",
3894
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3895
- },
3896
3898
  {
3897
3899
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3898
3900
  domain: "architecture",
@@ -1908,7 +1908,15 @@ function getClient() {
1908
1908
  if (!_resilientClient) {
1909
1909
  return _adapterClient;
1910
1910
  }
1911
- return _resilientClient;
1911
+ if (process.env.EXE_DB_READONLY === "1") {
1912
+ return _resilientClient;
1913
+ }
1914
+ process.stderr.write(
1915
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
1916
+ );
1917
+ throw new Error(
1918
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
1919
+ );
1912
1920
  }
1913
1921
  async function initDaemonClient() {
1914
1922
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -3498,7 +3506,7 @@ var init_platform_procedures = __esm({
3498
3506
  title: "What the platform provides vs what you customize",
3499
3507
  domain: "architecture",
3500
3508
  priority: "p0",
3501
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3509
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
3502
3510
  },
3503
3511
  // --- Updates ---
3504
3512
  {
@@ -3575,12 +3583,6 @@ var init_platform_procedures = __esm({
3575
3583
  priority: "p0",
3576
3584
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
3577
3585
  },
3578
- {
3579
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
3580
- domain: "workflow",
3581
- priority: "p0",
3582
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
3583
- },
3584
3586
  {
3585
3587
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
3586
3588
  domain: "architecture",
@@ -371,7 +371,7 @@ var init_platform_procedures = __esm({
371
371
  title: "What the platform provides vs what you customize",
372
372
  domain: "architecture",
373
373
  priority: "p0",
374
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
374
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
375
375
  },
376
376
  // --- Updates ---
377
377
  {
@@ -448,12 +448,6 @@ var init_platform_procedures = __esm({
448
448
  priority: "p0",
449
449
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
450
450
  },
451
- {
452
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
453
- domain: "workflow",
454
- priority: "p0",
455
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
456
- },
457
451
  {
458
452
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
459
453
  domain: "architecture",
@@ -2344,7 +2344,15 @@ function getClient() {
2344
2344
  if (!_resilientClient) {
2345
2345
  return _adapterClient;
2346
2346
  }
2347
- return _resilientClient;
2347
+ if (process.env.EXE_DB_READONLY === "1") {
2348
+ return _resilientClient;
2349
+ }
2350
+ process.stderr.write(
2351
+ "[database] ERROR: Daemon is not running \u2014 refusing direct SQLite write access.\n[database] Direct writes bypass the single-writer gate and corrupt FTS5 indexes.\n[database] Restart the daemon: kill $(cat ~/.exe-os/exed.pid) && exe-os update\n[database] Or set EXE_DB_READONLY=1 if you only need read access.\n"
2352
+ );
2353
+ throw new Error(
2354
+ "Daemon not running. Direct SQLite writes are blocked to prevent FTS5 corruption. Restart daemon or set EXE_DB_READONLY=1 for read-only access."
2355
+ );
2348
2356
  }
2349
2357
  async function initDaemonClient() {
2350
2358
  if (process.env.DATABASE_URL && process.env.EXE_USE_POSTGRES === "1") return;
@@ -6958,7 +6966,7 @@ var init_platform_procedures = __esm({
6958
6966
  title: "What the platform provides vs what you customize",
6959
6967
  domain: "architecture",
6960
6968
  priority: "p0",
6961
- content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
6969
+ content: "Exe OS has two layers. PLATFORM layer (shipped in code, updated via npm): platform procedures, default identity templates, MCP tools, tool gating, schema migrations, daemon behavior. You get improvements automatically on update. CUSTOMER layer (yours, stored locally): agent identities (exe.md files), behaviors, company procedures, config.json, wiki content, CRM data, memory. These are NEVER overwritten by updates. Identity templates are stamped once at /exe-new-employee \u2014 after that the file is yours. If the platform ships a better template, you can compare yours against the default with getTemplate() and merge what you want. Company procedures (company_procedure tool) layer ON TOP of platform procedures \u2014 both are injected, platform first. FIVE LAYERS \u2014 know when to use each: (1) Platform procedures: how exe-os works, shipped to ALL customers, updated via npm. Never put org-specific rules here. (2) Company procedures: your org's workflow rules, stored in DB, injected after platform. Use for internal gates, review checklists, org-specific policies. (3) Identity (exe.md): an agent's permanent role definition \u2014 who they are, what they own, non-negotiable rules. Use for rules that must NEVER be forgotten across sessions. (4) Behaviors: corrections and learned patterns (Layer 2 expertise). Use for 'from now on do X' or 'never do Y again' \u2014 agent-specific, deactivatable. (5) Memory: facts, decisions, context (Layer 3 experience). Use for what happened, what was decided, project state. Searchable, consolidatable. Rule of thumb: platform procedures for product behavior, company procedures for org workflow, identity for permanent role rules, behaviors for corrections, memory for facts. Behaviors are always yours. Config is always yours. The platform will never modify your local data."
6962
6970
  },
6963
6971
  // --- Updates ---
6964
6972
  {
@@ -7035,12 +7043,6 @@ var init_platform_procedures = __esm({
7035
7043
  priority: "p0",
7036
7044
  content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
7037
7045
  },
7038
- {
7039
- title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
7040
- domain: "workflow",
7041
- priority: "p0",
7042
- content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
7043
- },
7044
7046
  {
7045
7047
  title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
7046
7048
  domain: "architecture",