igniter 0.4.5 → 0.5.1

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 (638) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -3
  3. data/README.md +164 -409
  4. data/bin/igniter-stack +94 -0
  5. data/docs/README.md +62 -0
  6. data/examples/README.md +74 -312
  7. data/examples/agent_orchestration.rb +76 -0
  8. data/examples/agents.rb +2 -1
  9. data/examples/catalog.rb +412 -0
  10. data/examples/consensus.rb +241 -0
  11. data/examples/dataflow.rb +309 -0
  12. data/examples/distributed_workflow.rb +1 -1
  13. data/examples/effects.rb +10 -9
  14. data/examples/elocal_webhook.rb +1 -0
  15. data/examples/incremental.rb +4 -3
  16. data/examples/introspection.rb +49 -0
  17. data/examples/invariants.rb +4 -3
  18. data/examples/llm_tools.rb +237 -0
  19. data/examples/mesh.rb +241 -0
  20. data/examples/mesh_discovery.rb +287 -0
  21. data/examples/mesh_gossip.rb +164 -0
  22. data/examples/reactive_auditing.rb +50 -0
  23. data/examples/ringcentral_routing.rb +1 -1
  24. data/examples/run.rb +163 -0
  25. data/lib/igniter/monorepo_packages.rb +17 -0
  26. data/lib/igniter/stack.rb +5 -0
  27. data/lib/igniter.rb +48 -15
  28. data/packages/igniter-agents/README.md +22 -0
  29. data/{lib → packages/igniter-agents/lib}/igniter/agent/ref.rb +1 -0
  30. data/{lib → packages/igniter-agents/lib}/igniter/agent/runner.rb +12 -0
  31. data/{lib → packages/igniter-agents/lib}/igniter/agent.rb +6 -0
  32. data/packages/igniter-agents/lib/igniter/agents/observability/metrics_agent.rb +130 -0
  33. data/packages/igniter-agents/lib/igniter/agents/pipeline/batch_processor_agent.rb +131 -0
  34. data/packages/igniter-agents/lib/igniter/agents/proactive/alert_agent.rb +111 -0
  35. data/packages/igniter-agents/lib/igniter/agents/proactive/health_check_agent.rb +122 -0
  36. data/packages/igniter-agents/lib/igniter/agents/proactive_agent.rb +208 -0
  37. data/packages/igniter-agents/lib/igniter/agents/reliability/retry_agent.rb +99 -0
  38. data/packages/igniter-agents/lib/igniter/agents/scheduling/cron_agent.rb +110 -0
  39. data/packages/igniter-agents/lib/igniter/agents.rb +23 -0
  40. data/packages/igniter-agents/lib/igniter/ai/agents/chain_agent.rb +129 -0
  41. data/packages/igniter-agents/lib/igniter/ai/agents/critic_agent.rb +165 -0
  42. data/packages/igniter-agents/lib/igniter/ai/agents/evaluator_agent.rb +195 -0
  43. data/packages/igniter-agents/lib/igniter/ai/agents/evolution_agent.rb +288 -0
  44. data/packages/igniter-agents/lib/igniter/ai/agents/observer_agent.rb +186 -0
  45. data/packages/igniter-agents/lib/igniter/ai/agents/planner_agent.rb +212 -0
  46. data/packages/igniter-agents/lib/igniter/ai/agents/router_agent.rb +133 -0
  47. data/packages/igniter-agents/lib/igniter/ai/agents/self_reflection_agent.rb +177 -0
  48. data/packages/igniter-agents/lib/igniter/ai/agents.rb +25 -0
  49. data/{lib → packages/igniter-agents/lib}/igniter/registry.rb +2 -0
  50. data/packages/igniter-agents/lib/igniter/runtime/registry_agent_adapter.rb +102 -0
  51. data/{lib → packages/igniter-agents/lib}/igniter/supervisor.rb +3 -0
  52. data/packages/igniter-agents/lib/igniter-agents.rb +7 -0
  53. data/packages/igniter-ai/README.md +20 -0
  54. data/packages/igniter-ai/lib/igniter/ai/config.rb +113 -0
  55. data/{lib/igniter/integrations/llm → packages/igniter-ai/lib/igniter/ai}/context.rb +2 -2
  56. data/packages/igniter-ai/lib/igniter/ai/executor.rb +352 -0
  57. data/{lib/igniter/integrations/llm → packages/igniter-ai/lib/igniter/ai}/providers/anthropic.rb +42 -9
  58. data/{lib/igniter/integrations/llm → packages/igniter-ai/lib/igniter/ai}/providers/base.rb +1 -1
  59. data/{lib/igniter/integrations/llm → packages/igniter-ai/lib/igniter/ai}/providers/ollama.rb +4 -4
  60. data/{lib/igniter/integrations/llm → packages/igniter-ai/lib/igniter/ai}/providers/openai.rb +39 -10
  61. data/packages/igniter-ai/lib/igniter/ai/skill/feedback.rb +116 -0
  62. data/packages/igniter-ai/lib/igniter/ai/skill/output_schema.rb +110 -0
  63. data/packages/igniter-ai/lib/igniter/ai/skill/runtime_contract.rb +87 -0
  64. data/packages/igniter-ai/lib/igniter/ai/skill.rb +107 -0
  65. data/packages/igniter-ai/lib/igniter/ai/tool_registry.rb +79 -0
  66. data/packages/igniter-ai/lib/igniter/ai/transcription/providers/assemblyai.rb +200 -0
  67. data/packages/igniter-ai/lib/igniter/ai/transcription/providers/base.rb +122 -0
  68. data/packages/igniter-ai/lib/igniter/ai/transcription/providers/deepgram.rb +162 -0
  69. data/packages/igniter-ai/lib/igniter/ai/transcription/providers/openai.rb +102 -0
  70. data/packages/igniter-ai/lib/igniter/ai/transcription/transcriber.rb +145 -0
  71. data/packages/igniter-ai/lib/igniter/ai/transcription/transcript_result.rb +29 -0
  72. data/packages/igniter-ai/lib/igniter/ai.rb +98 -0
  73. data/packages/igniter-ai/lib/igniter-ai.rb +3 -0
  74. data/packages/igniter-app/README.md +19 -0
  75. data/packages/igniter-app/lib/igniter/app/app_config.rb +43 -0
  76. data/packages/igniter-app/lib/igniter/app/app_host.rb +56 -0
  77. data/packages/igniter-app/lib/igniter/app/app_host_config.rb +27 -0
  78. data/packages/igniter-app/lib/igniter/app/app_host_pack.rb +13 -0
  79. data/packages/igniter-app/lib/igniter/app/autoloader.rb +18 -0
  80. data/packages/igniter-app/lib/igniter/app/cluster_app_host.rb +95 -0
  81. data/packages/igniter-app/lib/igniter/app/cluster_app_host_config.rb +78 -0
  82. data/packages/igniter-app/lib/igniter/app/credentials/config_loader.rb +152 -0
  83. data/packages/igniter-app/lib/igniter/app/credentials/credential.rb +48 -0
  84. data/packages/igniter-app/lib/igniter/app/credentials/credential_policy.rb +38 -0
  85. data/packages/igniter-app/lib/igniter/app/credentials/events/credential_event.rb +179 -0
  86. data/packages/igniter-app/lib/igniter/app/credentials/events.rb +12 -0
  87. data/packages/igniter-app/lib/igniter/app/credentials/lease_request.rb +153 -0
  88. data/packages/igniter-app/lib/igniter/app/credentials/policies/ephemeral_lease_policy.rb +35 -0
  89. data/packages/igniter-app/lib/igniter/app/credentials/policies/local_only_policy.rb +33 -0
  90. data/packages/igniter-app/lib/igniter/app/credentials/policies.rb +13 -0
  91. data/packages/igniter-app/lib/igniter/app/credentials/store.rb +21 -0
  92. data/packages/igniter-app/lib/igniter/app/credentials/stores/file_store.rb +114 -0
  93. data/packages/igniter-app/lib/igniter/app/credentials/trail.rb +254 -0
  94. data/packages/igniter-app/lib/igniter/app/credentials.rb +20 -0
  95. data/packages/igniter-app/lib/igniter/app/dev_output_sync.rb +4 -0
  96. data/packages/igniter-app/lib/igniter/app/diagnostics/app_host_contributor.rb +71 -0
  97. data/packages/igniter-app/lib/igniter/app/diagnostics/cluster_app_host_contributor.rb +97 -0
  98. data/packages/igniter-app/lib/igniter/app/diagnostics/credential_contributor.rb +66 -0
  99. data/packages/igniter-app/lib/igniter/app/diagnostics/evolution_contributor.rb +74 -0
  100. data/packages/igniter-app/lib/igniter/app/diagnostics/ignite_contributor.rb +121 -0
  101. data/packages/igniter-app/lib/igniter/app/diagnostics/loader_contributor.rb +68 -0
  102. data/packages/igniter-app/lib/igniter/app/diagnostics/orchestration_contributor.rb +200 -0
  103. data/packages/igniter-app/lib/igniter/app/diagnostics/runtime_contributor.rb +68 -0
  104. data/packages/igniter-app/lib/igniter/app/diagnostics/scheduler_contributor.rb +72 -0
  105. data/packages/igniter-app/lib/igniter/app/diagnostics/sdk_contributor.rb +284 -0
  106. data/packages/igniter-app/lib/igniter/app/diagnostics.rb +62 -0
  107. data/packages/igniter-app/lib/igniter/app/evolution/approval_decision.rb +115 -0
  108. data/packages/igniter-app/lib/igniter/app/evolution/approval_request.rb +36 -0
  109. data/packages/igniter-app/lib/igniter/app/evolution/plan.rb +72 -0
  110. data/packages/igniter-app/lib/igniter/app/evolution/planner.rb +85 -0
  111. data/packages/igniter-app/lib/igniter/app/evolution/result.rb +45 -0
  112. data/packages/igniter-app/lib/igniter/app/evolution/runner.rb +102 -0
  113. data/packages/igniter-app/lib/igniter/app/evolution/store.rb +21 -0
  114. data/packages/igniter-app/lib/igniter/app/evolution/stores/file_store.rb +241 -0
  115. data/packages/igniter-app/lib/igniter/app/evolution/trail.rb +108 -0
  116. data/packages/igniter-app/lib/igniter/app/evolution.rb +11 -0
  117. data/packages/igniter-app/lib/igniter/app/filesystem_loader_adapter.rb +21 -0
  118. data/packages/igniter-app/lib/igniter/app/generator.rb +636 -0
  119. data/packages/igniter-app/lib/igniter/app/generators/cluster.rb +1367 -0
  120. data/packages/igniter-app/lib/igniter/app/generators/dashboard.rb +152 -0
  121. data/packages/igniter-app/lib/igniter/app/generators/playground.rb +1227 -0
  122. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/README.md.erb +37 -0
  123. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/app.rb.erb +19 -0
  124. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/contexts/home_context.rb.erb +54 -0
  125. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/frontend/application.js.erb +3 -0
  126. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/spec/dashboard_app_spec.rb.erb +79 -0
  127. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/support/stack_overview.rb.erb +23 -0
  128. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/web/handlers/home_handler.rb.erb +27 -0
  129. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/web/views/home_page.arb.erb +44 -0
  130. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/web/views/home_page.rb.erb +56 -0
  131. data/packages/igniter-app/lib/igniter/app/generators/templates/dashboard/web/views/layout.arb.erb +17 -0
  132. data/packages/igniter-app/lib/igniter/app/host_adapter.rb +26 -0
  133. data/packages/igniter-app/lib/igniter/app/host_config.rb +40 -0
  134. data/packages/igniter-app/lib/igniter/app/host_registry.rb +43 -0
  135. data/packages/igniter-app/lib/igniter/app/loader_adapter.rb +15 -0
  136. data/packages/igniter-app/lib/igniter/app/loader_pack.rb +8 -0
  137. data/packages/igniter-app/lib/igniter/app/loader_registry.rb +39 -0
  138. data/packages/igniter-app/lib/igniter/app/observability/operator_action_handler.rb +147 -0
  139. data/packages/igniter-app/lib/igniter/app/observability/operator_console_handler.rb +747 -0
  140. data/packages/igniter-app/lib/igniter/app/observability/operator_overview_handler.rb +350 -0
  141. data/packages/igniter-app/lib/igniter/app/observability.rb +5 -0
  142. data/packages/igniter-app/lib/igniter/app/observability_pack.rb +71 -0
  143. data/packages/igniter-app/lib/igniter/app/operator/dispatcher.rb +40 -0
  144. data/packages/igniter-app/lib/igniter/app/operator/handler_registry.rb +40 -0
  145. data/packages/igniter-app/lib/igniter/app/operator/handler_result.rb +67 -0
  146. data/packages/igniter-app/lib/igniter/app/operator/handlers/base.rb +79 -0
  147. data/packages/igniter-app/lib/igniter/app/operator/handlers/ignite_handler.rb +108 -0
  148. data/packages/igniter-app/lib/igniter/app/operator/handlers/orchestration_handler.rb +33 -0
  149. data/packages/igniter-app/lib/igniter/app/operator/handlers.rb +5 -0
  150. data/packages/igniter-app/lib/igniter/app/operator/lifecycle_contract.rb +55 -0
  151. data/packages/igniter-app/lib/igniter/app/operator/policy.rb +157 -0
  152. data/packages/igniter-app/lib/igniter/app/operator.rb +17 -0
  153. data/packages/igniter-app/lib/igniter/app/orchestration/action_result_builder.rb +65 -0
  154. data/packages/igniter-app/lib/igniter/app/orchestration/followup_request.rb +36 -0
  155. data/packages/igniter-app/lib/igniter/app/orchestration/handler_registry.rb +58 -0
  156. data/packages/igniter-app/lib/igniter/app/orchestration/handlers.rb +106 -0
  157. data/packages/igniter-app/lib/igniter/app/orchestration/inbox.rb +283 -0
  158. data/packages/igniter-app/lib/igniter/app/orchestration/inbox_query.rb +293 -0
  159. data/packages/igniter-app/lib/igniter/app/orchestration/lane_registry.rb +100 -0
  160. data/packages/igniter-app/lib/igniter/app/orchestration/operator_query.rb +449 -0
  161. data/packages/igniter-app/lib/igniter/app/orchestration/plan.rb +68 -0
  162. data/packages/igniter-app/lib/igniter/app/orchestration/planner.rb +89 -0
  163. data/packages/igniter-app/lib/igniter/app/orchestration/policies.rb +125 -0
  164. data/packages/igniter-app/lib/igniter/app/orchestration/policy_registry.rb +63 -0
  165. data/packages/igniter-app/lib/igniter/app/orchestration/result.rb +43 -0
  166. data/packages/igniter-app/lib/igniter/app/orchestration/routing_registry.rb +43 -0
  167. data/packages/igniter-app/lib/igniter/app/orchestration/runner.rb +50 -0
  168. data/packages/igniter-app/lib/igniter/app/orchestration/runtime_event_query.rb +205 -0
  169. data/packages/igniter-app/lib/igniter/app/orchestration/runtime_overview_builder.rb +286 -0
  170. data/packages/igniter-app/lib/igniter/app/orchestration/runtime_query_overview_builder.rb +20 -0
  171. data/packages/igniter-app/lib/igniter/app/orchestration/runtime_result_builder.rb +23 -0
  172. data/packages/igniter-app/lib/igniter/app/orchestration.rb +113 -0
  173. data/packages/igniter-app/lib/igniter/app/runtime.rb +4 -0
  174. data/packages/igniter-app/lib/igniter/app/runtime_context.rb +101 -0
  175. data/packages/igniter-app/lib/igniter/app/runtime_pack.rb +16 -0
  176. data/packages/igniter-app/lib/igniter/app/scaffold_pack.rb +6 -0
  177. data/packages/igniter-app/lib/igniter/app/scheduler.rb +109 -0
  178. data/packages/igniter-app/lib/igniter/app/scheduler_adapter.rb +17 -0
  179. data/packages/igniter-app/lib/igniter/app/scheduler_pack.rb +8 -0
  180. data/packages/igniter-app/lib/igniter/app/scheduler_registry.rb +39 -0
  181. data/packages/igniter-app/lib/igniter/app/stack.rb +1726 -0
  182. data/packages/igniter-app/lib/igniter/app/stack_pack.rb +3 -0
  183. data/packages/igniter-app/lib/igniter/app/threaded_scheduler_adapter.rb +35 -0
  184. data/packages/igniter-app/lib/igniter/app/yml_loader.rb +43 -0
  185. data/packages/igniter-app/lib/igniter/app.rb +2367 -0
  186. data/packages/igniter-app/lib/igniter/ignite/bootstrap_agent.rb +334 -0
  187. data/packages/igniter-app/lib/igniter/ignite/bootstrap_target.rb +79 -0
  188. data/packages/igniter-app/lib/igniter/ignite/deployment_intent.rb +82 -0
  189. data/packages/igniter-app/lib/igniter/ignite/ignition_agent.rb +1011 -0
  190. data/packages/igniter-app/lib/igniter/ignite/ignition_plan.rb +83 -0
  191. data/packages/igniter-app/lib/igniter/ignite/ignition_report.rb +144 -0
  192. data/packages/igniter-app/lib/igniter/ignite/store.rb +19 -0
  193. data/packages/igniter-app/lib/igniter/ignite/stores/file_store.rb +112 -0
  194. data/packages/igniter-app/lib/igniter/ignite/trail.rb +215 -0
  195. data/packages/igniter-app/lib/igniter/ignite.rb +11 -0
  196. data/packages/igniter-app/lib/igniter-app.rb +5 -0
  197. data/packages/igniter-cluster/README.md +9 -0
  198. data/packages/igniter-cluster/lib/igniter/cluster/agent_route_resolver.rb +58 -0
  199. data/packages/igniter-cluster/lib/igniter/cluster/consensus/cluster.rb +187 -0
  200. data/packages/igniter-cluster/lib/igniter/cluster/consensus/errors.rb +16 -0
  201. data/packages/igniter-cluster/lib/igniter/cluster/consensus/executors.rb +45 -0
  202. data/packages/igniter-cluster/lib/igniter/cluster/consensus/node.rb +322 -0
  203. data/packages/igniter-cluster/lib/igniter/cluster/consensus/read_query.rb +32 -0
  204. data/packages/igniter-cluster/lib/igniter/cluster/consensus/state_machine.rb +60 -0
  205. data/packages/igniter-cluster/lib/igniter/cluster/consensus.rb +18 -0
  206. data/packages/igniter-cluster/lib/igniter/cluster/diagnostics/governance_contributor.rb +90 -0
  207. data/packages/igniter-cluster/lib/igniter/cluster/diagnostics/identity_contributor.rb +98 -0
  208. data/packages/igniter-cluster/lib/igniter/cluster/diagnostics/routing_contributor.rb +674 -0
  209. data/packages/igniter-cluster/lib/igniter/cluster/diagnostics.rb +24 -0
  210. data/packages/igniter-cluster/lib/igniter/cluster/events/envelope.rb +136 -0
  211. data/packages/igniter-cluster/lib/igniter/cluster/events/hook_support.rb +33 -0
  212. data/packages/igniter-cluster/lib/igniter/cluster/events/log.rb +102 -0
  213. data/packages/igniter-cluster/lib/igniter/cluster/events/projection_feed.rb +98 -0
  214. data/packages/igniter-cluster/lib/igniter/cluster/events/read_model_projector.rb +32 -0
  215. data/packages/igniter-cluster/lib/igniter/cluster/events.rb +131 -0
  216. data/packages/igniter-cluster/lib/igniter/cluster/governance/admission_decision.rb +41 -0
  217. data/packages/igniter-cluster/lib/igniter/cluster/governance/admission_policy.rb +66 -0
  218. data/packages/igniter-cluster/lib/igniter/cluster/governance/admission_queue.rb +88 -0
  219. data/packages/igniter-cluster/lib/igniter/cluster/governance/admission_request.rb +62 -0
  220. data/packages/igniter-cluster/lib/igniter/cluster/governance/admission_workflow.rb +214 -0
  221. data/packages/igniter-cluster/lib/igniter/cluster/governance/checkpoint.rb +141 -0
  222. data/packages/igniter-cluster/lib/igniter/cluster/governance/compaction_record.rb +33 -0
  223. data/packages/igniter-cluster/lib/igniter/cluster/governance/stores/checkpoint_store.rb +89 -0
  224. data/packages/igniter-cluster/lib/igniter/cluster/governance/stores/file_store.rb +249 -0
  225. data/packages/igniter-cluster/lib/igniter/cluster/governance/trail.rb +164 -0
  226. data/packages/igniter-cluster/lib/igniter/cluster/governance.rb +12 -0
  227. data/packages/igniter-cluster/lib/igniter/cluster/identity/capability_attestation.rb +114 -0
  228. data/packages/igniter-cluster/lib/igniter/cluster/identity/manifest.rb +139 -0
  229. data/packages/igniter-cluster/lib/igniter/cluster/identity/node_identity.rb +106 -0
  230. data/packages/igniter-cluster/lib/igniter/cluster/identity.rb +5 -0
  231. data/packages/igniter-cluster/lib/igniter/cluster/mesh/announcer.rb +88 -0
  232. data/packages/igniter-cluster/lib/igniter/cluster/mesh/checkpoint_gossip.rb +60 -0
  233. data/packages/igniter-cluster/lib/igniter/cluster/mesh/config.rb +146 -0
  234. data/packages/igniter-cluster/lib/igniter/cluster/mesh/discovery.rb +44 -0
  235. data/packages/igniter-cluster/lib/igniter/cluster/mesh/errors.rb +36 -0
  236. data/packages/igniter-cluster/lib/igniter/cluster/mesh/gossip.rb +62 -0
  237. data/packages/igniter-cluster/lib/igniter/cluster/mesh/mesh_ql.rb +470 -0
  238. data/packages/igniter-cluster/lib/igniter/cluster/mesh/node_observation.rb +281 -0
  239. data/packages/igniter-cluster/lib/igniter/cluster/mesh/observation_query.rb +284 -0
  240. data/packages/igniter-cluster/lib/igniter/cluster/mesh/peer.rb +51 -0
  241. data/packages/igniter-cluster/lib/igniter/cluster/mesh/peer_capacity_report.rb +42 -0
  242. data/packages/igniter-cluster/lib/igniter/cluster/mesh/peer_identity_envelope.rb +158 -0
  243. data/packages/igniter-cluster/lib/igniter/cluster/mesh/peer_metadata.rb +122 -0
  244. data/packages/igniter-cluster/lib/igniter/cluster/mesh/peer_registry.rb +81 -0
  245. data/packages/igniter-cluster/lib/igniter/cluster/mesh/placement_decision.rb +64 -0
  246. data/packages/igniter-cluster/lib/igniter/cluster/mesh/placement_planner.rb +154 -0
  247. data/packages/igniter-cluster/lib/igniter/cluster/mesh/placement_policy.rb +103 -0
  248. data/packages/igniter-cluster/lib/igniter/cluster/mesh/poller.rb +92 -0
  249. data/packages/igniter-cluster/lib/igniter/cluster/mesh/rebalance_plan.rb +66 -0
  250. data/packages/igniter-cluster/lib/igniter/cluster/mesh/rebalance_planner.rb +153 -0
  251. data/packages/igniter-cluster/lib/igniter/cluster/mesh/repair_loop.rb +169 -0
  252. data/packages/igniter-cluster/lib/igniter/cluster/mesh/router.rb +306 -0
  253. data/packages/igniter-cluster/lib/igniter/cluster/mesh/workload_signal.rb +46 -0
  254. data/packages/igniter-cluster/lib/igniter/cluster/mesh/workload_tracker.rb +215 -0
  255. data/packages/igniter-cluster/lib/igniter/cluster/mesh.rb +452 -0
  256. data/packages/igniter-cluster/lib/igniter/cluster/ownership/claim.rb +69 -0
  257. data/packages/igniter-cluster/lib/igniter/cluster/ownership/errors.rb +19 -0
  258. data/packages/igniter-cluster/lib/igniter/cluster/ownership/owner_client.rb +76 -0
  259. data/packages/igniter-cluster/lib/igniter/cluster/ownership/registry.rb +98 -0
  260. data/packages/igniter-cluster/lib/igniter/cluster/ownership/resolver.rb +62 -0
  261. data/packages/igniter-cluster/lib/igniter/cluster/ownership.rb +81 -0
  262. data/packages/igniter-cluster/lib/igniter/cluster/projection_store.rb +62 -0
  263. data/packages/igniter-cluster/lib/igniter/cluster/rag/chunk.rb +49 -0
  264. data/packages/igniter-cluster/lib/igniter/cluster/rag/fanout_retriever.rb +93 -0
  265. data/packages/igniter-cluster/lib/igniter/cluster/rag/knowledge_shard.rb +140 -0
  266. data/packages/igniter-cluster/lib/igniter/cluster/rag/net_http_adapter.rb +85 -0
  267. data/packages/igniter-cluster/lib/igniter/cluster/rag/ranker.rb +46 -0
  268. data/packages/igniter-cluster/lib/igniter/cluster/rag/retrieval_query.rb +30 -0
  269. data/packages/igniter-cluster/lib/igniter/cluster/rag/retrieval_result.rb +77 -0
  270. data/packages/igniter-cluster/lib/igniter/cluster/rag.rb +38 -0
  271. data/packages/igniter-cluster/lib/igniter/cluster/remote_adapter.rb +101 -0
  272. data/packages/igniter-cluster/lib/igniter/cluster/replication/bootstrapper.rb +63 -0
  273. data/packages/igniter-cluster/lib/igniter/cluster/replication/bootstrappers/gem.rb +39 -0
  274. data/packages/igniter-cluster/lib/igniter/cluster/replication/bootstrappers/git.rb +46 -0
  275. data/packages/igniter-cluster/lib/igniter/cluster/replication/bootstrappers/tarball.rb +62 -0
  276. data/packages/igniter-cluster/lib/igniter/cluster/replication/capability_query.rb +675 -0
  277. data/packages/igniter-cluster/lib/igniter/cluster/replication/expansion_plan.rb +40 -0
  278. data/packages/igniter-cluster/lib/igniter/cluster/replication/expansion_planner.rb +154 -0
  279. data/packages/igniter-cluster/lib/igniter/cluster/replication/manifest.rb +47 -0
  280. data/packages/igniter-cluster/lib/igniter/cluster/replication/network_topology.rb +150 -0
  281. data/packages/igniter-cluster/lib/igniter/cluster/replication/node_profile.rb +134 -0
  282. data/packages/igniter-cluster/lib/igniter/cluster/replication/reflective_replication_agent.rb +259 -0
  283. data/packages/igniter-cluster/lib/igniter/cluster/replication/replication_agent.rb +89 -0
  284. data/packages/igniter-cluster/lib/igniter/cluster/replication/ssh_session.rb +79 -0
  285. data/packages/igniter-cluster/lib/igniter/cluster/replication.rb +38 -0
  286. data/packages/igniter-cluster/lib/igniter/cluster/routed_agent_adapter.rb +79 -0
  287. data/packages/igniter-cluster/lib/igniter/cluster/routing_plan_executor.rb +427 -0
  288. data/packages/igniter-cluster/lib/igniter/cluster/routing_plan_result.rb +38 -0
  289. data/packages/igniter-cluster/lib/igniter/cluster/trust/admission_plan.rb +34 -0
  290. data/packages/igniter-cluster/lib/igniter/cluster/trust/admission_planner.rb +76 -0
  291. data/packages/igniter-cluster/lib/igniter/cluster/trust/admission_result.rb +34 -0
  292. data/packages/igniter-cluster/lib/igniter/cluster/trust/admission_runner.rb +125 -0
  293. data/packages/igniter-cluster/lib/igniter/cluster/trust/trust_assessment.rb +37 -0
  294. data/packages/igniter-cluster/lib/igniter/cluster/trust/trust_store.rb +58 -0
  295. data/packages/igniter-cluster/lib/igniter/cluster/trust/verifier.rb +80 -0
  296. data/packages/igniter-cluster/lib/igniter/cluster/trust.rb +9 -0
  297. data/packages/igniter-cluster/lib/igniter/cluster.rb +71 -0
  298. data/packages/igniter-cluster/lib/igniter-cluster.rb +3 -0
  299. data/packages/igniter-core/README.md +21 -0
  300. data/packages/igniter-core/lib/igniter/core/capabilities.rb +70 -0
  301. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/compiled_graph.rb +40 -2
  302. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validation_pipeline.rb +1 -0
  303. data/packages/igniter-core/lib/igniter/core/compiler/validators/agent_validator.rb +142 -0
  304. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/dependencies_validator.rb +90 -3
  305. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/remote_validator.rb +2 -0
  306. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler.rb +1 -0
  307. data/packages/igniter-core/lib/igniter/core/content_addressing.rb +133 -0
  308. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/contract.rb +88 -6
  309. data/packages/igniter-core/lib/igniter/core/dataflow/aggregate_operators.rb +147 -0
  310. data/packages/igniter-core/lib/igniter/core/dataflow/aggregate_state.rb +77 -0
  311. data/packages/igniter-core/lib/igniter/core/dataflow/diff.rb +37 -0
  312. data/packages/igniter-core/lib/igniter/core/dataflow/diff_state.rb +81 -0
  313. data/packages/igniter-core/lib/igniter/core/dataflow/incremental_collection_result.rb +39 -0
  314. data/packages/igniter-core/lib/igniter/core/dataflow/window_filter.rb +48 -0
  315. data/packages/igniter-core/lib/igniter/core/dataflow.rb +65 -0
  316. data/packages/igniter-core/lib/igniter/core/diagnostics/agent_contributor.rb +241 -0
  317. data/packages/igniter-core/lib/igniter/core/diagnostics/capability_contributor.rb +162 -0
  318. data/packages/igniter-core/lib/igniter/core/diagnostics/orchestration_contributor.rb +75 -0
  319. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/diagnostics/report.rb +81 -6
  320. data/packages/igniter-core/lib/igniter/core/diagnostics.rb +58 -0
  321. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/dsl/contract_builder.rb +230 -9
  322. data/packages/igniter-core/lib/igniter/core/dto/record.rb +189 -0
  323. data/packages/igniter-core/lib/igniter/core/dto.rb +8 -0
  324. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/effect.rb +4 -0
  325. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/errors.rb +26 -3
  326. data/packages/igniter-core/lib/igniter/core/executor.rb +134 -0
  327. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/introspection/graph_formatter.rb +32 -1
  328. data/packages/igniter-core/lib/igniter/core/extensions/introspection/plan_formatter.rb +85 -0
  329. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/introspection/runtime_formatter.rb +26 -0
  330. data/packages/igniter-core/lib/igniter/core/extensions/invariants.rb +70 -0
  331. data/packages/igniter-core/lib/igniter/core/fingerprint.rb +43 -0
  332. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/incremental.rb +4 -4
  333. data/packages/igniter-core/lib/igniter/core/memory/agent_memory.rb +104 -0
  334. data/packages/igniter-core/lib/igniter/core/memory/episode.rb +29 -0
  335. data/packages/igniter-core/lib/igniter/core/memory/fact.rb +27 -0
  336. data/packages/igniter-core/lib/igniter/core/memory/memorable.rb +90 -0
  337. data/packages/igniter-core/lib/igniter/core/memory/reflection_cycle.rb +96 -0
  338. data/packages/igniter-core/lib/igniter/core/memory/reflection_record.rb +28 -0
  339. data/packages/igniter-core/lib/igniter/core/memory/store.rb +115 -0
  340. data/packages/igniter-core/lib/igniter/core/memory/stores/in_memory.rb +136 -0
  341. data/packages/igniter-core/lib/igniter/core/memory/stores/sqlite.rb +286 -0
  342. data/packages/igniter-core/lib/igniter/core/memory.rb +80 -0
  343. data/packages/igniter-core/lib/igniter/core/metrics/collector.rb +131 -0
  344. data/packages/igniter-core/lib/igniter/core/metrics/prometheus_exporter.rb +104 -0
  345. data/packages/igniter-core/lib/igniter/core/metrics/snapshot.rb +8 -0
  346. data/packages/igniter-core/lib/igniter/core/metrics.rb +37 -0
  347. data/packages/igniter-core/lib/igniter/core/model/agent_interaction_contract.rb +172 -0
  348. data/packages/igniter-core/lib/igniter/core/model/agent_node.rb +86 -0
  349. data/packages/igniter-core/lib/igniter/core/model/aggregate_node.rb +34 -0
  350. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/branch_node.rb +37 -1
  351. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/collection_node.rb +3 -2
  352. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/compute_node.rb +13 -0
  353. data/packages/igniter-core/lib/igniter/core/model/remote_node.rb +91 -0
  354. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model.rb +2 -0
  355. data/packages/igniter-core/lib/igniter/core/node_cache.rb +231 -0
  356. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing.rb +8 -8
  357. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/provenance/builder.rb +30 -1
  358. data/packages/igniter-core/lib/igniter/core/runtime/agent_adapter.rb +41 -0
  359. data/packages/igniter-core/lib/igniter/core/runtime/agent_result_contract.rb +91 -0
  360. data/packages/igniter-core/lib/igniter/core/runtime/agent_route.rb +60 -0
  361. data/packages/igniter-core/lib/igniter/core/runtime/agent_route_resolver.rb +26 -0
  362. data/packages/igniter-core/lib/igniter/core/runtime/agent_session.rb +922 -0
  363. data/packages/igniter-core/lib/igniter/core/runtime/agent_session_query.rb +379 -0
  364. data/packages/igniter-core/lib/igniter/core/runtime/agent_transport.rb +30 -0
  365. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/cache.rb +6 -3
  366. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/deferred_result.rb +27 -1
  367. data/packages/igniter-core/lib/igniter/core/runtime/execution.rb +913 -0
  368. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/input_validator.rb +6 -2
  369. data/packages/igniter-core/lib/igniter/core/runtime/job_worker.rb +39 -0
  370. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/node_state.rb +4 -2
  371. data/packages/igniter-core/lib/igniter/core/runtime/orchestration_overview.rb +213 -0
  372. data/packages/igniter-core/lib/igniter/core/runtime/orchestration_runtime_state.rb +176 -0
  373. data/packages/igniter-core/lib/igniter/core/runtime/orchestration_transition_query.rb +208 -0
  374. data/packages/igniter-core/lib/igniter/core/runtime/planner.rb +301 -0
  375. data/packages/igniter-core/lib/igniter/core/runtime/proxy_agent_adapter.rb +124 -0
  376. data/packages/igniter-core/lib/igniter/core/runtime/remote_adapter.rb +26 -0
  377. data/packages/igniter-core/lib/igniter/core/runtime/resolver.rb +951 -0
  378. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/result.rb +2 -0
  379. data/packages/igniter-core/lib/igniter/core/runtime/stores/redis_store.rb +93 -0
  380. data/packages/igniter-core/lib/igniter/core/runtime/stores/sqlite_store.rb +155 -0
  381. data/packages/igniter-core/lib/igniter/core/runtime/stream_result.rb +171 -0
  382. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime.rb +15 -0
  383. data/packages/igniter-core/lib/igniter/core/temporal.rb +84 -0
  384. data/packages/igniter-core/lib/igniter/core/tool/discoverable.rb +151 -0
  385. data/packages/igniter-core/lib/igniter/core/tool.rb +56 -0
  386. data/{lib/igniter → packages/igniter-core/lib/igniter/core}/version.rb +1 -1
  387. data/packages/igniter-core/lib/igniter/core.rb +23 -0
  388. data/packages/igniter-core/lib/igniter-core.rb +3 -0
  389. data/packages/igniter-extensions/README.md +21 -0
  390. data/packages/igniter-extensions/lib/igniter/extensions/auditing.rb +3 -0
  391. data/packages/igniter-extensions/lib/igniter/extensions/capabilities.rb +39 -0
  392. data/packages/igniter-extensions/lib/igniter/extensions/content_addressing.rb +5 -0
  393. data/packages/igniter-extensions/lib/igniter/extensions/dataflow.rb +117 -0
  394. data/{lib → packages/igniter-extensions/lib}/igniter/extensions/differential.rb +1 -1
  395. data/{lib → packages/igniter-extensions/lib}/igniter/extensions/execution_report.rb +1 -1
  396. data/{lib → packages/igniter-extensions/lib}/igniter/extensions/incremental.rb +1 -1
  397. data/packages/igniter-extensions/lib/igniter/extensions/introspection.rb +3 -0
  398. data/packages/igniter-extensions/lib/igniter/extensions/invariants.rb +3 -0
  399. data/{lib → packages/igniter-extensions/lib}/igniter/extensions/provenance.rb +1 -1
  400. data/packages/igniter-extensions/lib/igniter/extensions/reactive.rb +3 -0
  401. data/{lib → packages/igniter-extensions/lib}/igniter/extensions/saga.rb +1 -1
  402. data/packages/igniter-extensions/lib/igniter/extensions.rb +8 -0
  403. data/packages/igniter-extensions/lib/igniter-extensions.rb +3 -0
  404. data/packages/igniter-frontend/README.md +224 -0
  405. data/packages/igniter-frontend/lib/igniter/frontend/app.rb +90 -0
  406. data/packages/igniter-frontend/lib/igniter/frontend/app_access.rb +36 -0
  407. data/packages/igniter-frontend/lib/igniter/frontend/arbre/component.rb +120 -0
  408. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/action_group.rb +53 -0
  409. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/badge.rb +91 -0
  410. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/boolean.rb +53 -0
  411. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/breadcrumbs.rb +71 -0
  412. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/card.rb +114 -0
  413. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/conversation_panel.rb +61 -0
  414. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/datetime.rb +42 -0
  415. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/display_value_support.rb +38 -0
  416. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/empty_state.rb +39 -0
  417. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/event_list.rb +44 -0
  418. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/filters.rb +183 -0
  419. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/indicator.rb +59 -0
  420. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/json_panel.rb +36 -0
  421. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/key_value_list.rb +40 -0
  422. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/loading_state.rb +43 -0
  423. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/metric_grid.rb +37 -0
  424. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/number.rb +53 -0
  425. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/page_header.rb +53 -0
  426. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/pagination.rb +143 -0
  427. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/panel.rb +67 -0
  428. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/percentage.rb +79 -0
  429. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/resource_list.rb +38 -0
  430. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/scenario_card.rb +48 -0
  431. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/shell_columns.rb +67 -0
  432. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/sidebar_shell.rb +106 -0
  433. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/table_with.rb +203 -0
  434. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/tabs.rb +147 -0
  435. data/packages/igniter-frontend/lib/igniter/frontend/arbre/components/viz.rb +185 -0
  436. data/packages/igniter-frontend/lib/igniter/frontend/arbre/page.rb +74 -0
  437. data/packages/igniter-frontend/lib/igniter/frontend/arbre/raw_text_node.rb +40 -0
  438. data/packages/igniter-frontend/lib/igniter/frontend/arbre/template_page.rb +243 -0
  439. data/packages/igniter-frontend/lib/igniter/frontend/arbre.rb +48 -0
  440. data/packages/igniter-frontend/lib/igniter/frontend/arbre_page.rb +7 -0
  441. data/packages/igniter-frontend/lib/igniter/frontend/assets.rb +101 -0
  442. data/packages/igniter-frontend/lib/igniter/frontend/builder.rb +124 -0
  443. data/packages/igniter-frontend/lib/igniter/frontend/component.rb +24 -0
  444. data/packages/igniter-frontend/lib/igniter/frontend/components.rb +7 -0
  445. data/packages/igniter-frontend/lib/igniter/frontend/context.rb +53 -0
  446. data/packages/igniter-frontend/lib/igniter/frontend/form_builder.rb +63 -0
  447. data/packages/igniter-frontend/lib/igniter/frontend/handler.rb +92 -0
  448. data/packages/igniter-frontend/lib/igniter/frontend/javascript.rb +353 -0
  449. data/packages/igniter-frontend/lib/igniter/frontend/page.rb +24 -0
  450. data/packages/igniter-frontend/lib/igniter/frontend/request.rb +61 -0
  451. data/packages/igniter-frontend/lib/igniter/frontend/response.rb +67 -0
  452. data/packages/igniter-frontend/lib/igniter/frontend/tailwind/realtime/adapters.rb +226 -0
  453. data/packages/igniter-frontend/lib/igniter/frontend/tailwind/realtime/presets.rb +147 -0
  454. data/packages/igniter-frontend/lib/igniter/frontend/tailwind/realtime.rb +259 -0
  455. data/packages/igniter-frontend/lib/igniter/frontend/tailwind/surfaces.rb +1074 -0
  456. data/packages/igniter-frontend/lib/igniter/frontend/tailwind/ui.rb +1438 -0
  457. data/packages/igniter-frontend/lib/igniter/frontend/tailwind.rb +180 -0
  458. data/packages/igniter-frontend/lib/igniter/frontend/version.rb +9 -0
  459. data/packages/igniter-frontend/lib/igniter/frontend.rb +35 -0
  460. data/packages/igniter-frontend/lib/igniter-frontend.rb +3 -0
  461. data/packages/igniter-rails/README.md +96 -0
  462. data/packages/igniter-rails/lib/igniter/plugins/rails/generators/contract/templates/contract.rb.tt +22 -0
  463. data/packages/igniter-rails/lib/igniter/plugins/rails/generators/install/templates/igniter.rb.tt +16 -0
  464. data/packages/igniter-rails/lib/igniter-rails.rb +3 -0
  465. data/packages/igniter-schema-rendering/README.md +27 -0
  466. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/page.rb +35 -0
  467. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/patcher.rb +47 -0
  468. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/renderer.rb +268 -0
  469. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/schema.rb +172 -0
  470. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/store.rb +53 -0
  471. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/submission_normalizer.rb +117 -0
  472. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/submission_processor.rb +91 -0
  473. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/submission_validator.rb +62 -0
  474. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering/version.rb +9 -0
  475. data/packages/igniter-schema-rendering/lib/igniter/schema_rendering.rb +20 -0
  476. data/packages/igniter-schema-rendering/lib/igniter-schema-rendering.rb +3 -0
  477. data/packages/igniter-sdk/README.md +25 -0
  478. data/packages/igniter-sdk/lib/igniter/sdk/channels/base.rb +84 -0
  479. data/packages/igniter-sdk/lib/igniter/sdk/channels/delivery_result.rb +61 -0
  480. data/packages/igniter-sdk/lib/igniter/sdk/channels/message.rb +101 -0
  481. data/packages/igniter-sdk/lib/igniter/sdk/channels/telegram.rb +161 -0
  482. data/packages/igniter-sdk/lib/igniter/sdk/channels/webhook.rb +213 -0
  483. data/packages/igniter-sdk/lib/igniter/sdk/channels.rb +17 -0
  484. data/packages/igniter-sdk/lib/igniter/sdk/data/store.rb +31 -0
  485. data/packages/igniter-sdk/lib/igniter/sdk/data/stores/file.rb +113 -0
  486. data/packages/igniter-sdk/lib/igniter/sdk/data/stores/in_memory.rb +63 -0
  487. data/packages/igniter-sdk/lib/igniter/sdk/data/stores/sqlite.rb +144 -0
  488. data/packages/igniter-sdk/lib/igniter/sdk/data.rb +34 -0
  489. data/packages/igniter-sdk/lib/igniter/sdk/tools/agent_bootstrap_tool.rb +151 -0
  490. data/packages/igniter-sdk/lib/igniter/sdk/tools/local_workflow_selector_tool.rb +269 -0
  491. data/packages/igniter-sdk/lib/igniter/sdk/tools/system_discovery_tool.rb +198 -0
  492. data/packages/igniter-sdk/lib/igniter/sdk/tools.rb +9 -0
  493. data/packages/igniter-sdk/lib/igniter/sdk.rb +86 -0
  494. data/packages/igniter-sdk/lib/igniter-sdk.rb +3 -0
  495. data/packages/igniter-server/README.md +9 -0
  496. data/packages/igniter-server/lib/igniter/server/agent_session_store.rb +98 -0
  497. data/packages/igniter-server/lib/igniter/server/agent_transport.rb +95 -0
  498. data/packages/igniter-server/lib/igniter/server/app_host.rb +3 -0
  499. data/packages/igniter-server/lib/igniter/server/client.rb +256 -0
  500. data/packages/igniter-server/lib/igniter/server/config.rb +70 -0
  501. data/packages/igniter-server/lib/igniter/server/handlers/agent_message_handler.rb +107 -0
  502. data/packages/igniter-server/lib/igniter/server/handlers/agent_session_handler.rb +125 -0
  503. data/{lib → packages/igniter-server/lib}/igniter/server/handlers/event_handler.rb +4 -0
  504. data/{lib → packages/igniter-server/lib}/igniter/server/handlers/execute_handler.rb +6 -0
  505. data/packages/igniter-server/lib/igniter/server/handlers/liveness_handler.rb +20 -0
  506. data/packages/igniter-server/lib/igniter/server/handlers/manifest_handler.rb +77 -0
  507. data/packages/igniter-server/lib/igniter/server/handlers/metrics_handler.rb +51 -0
  508. data/packages/igniter-server/lib/igniter/server/handlers/peers_handler.rb +136 -0
  509. data/packages/igniter-server/lib/igniter/server/handlers/readiness_handler.rb +47 -0
  510. data/packages/igniter-server/lib/igniter/server/http_server.rb +222 -0
  511. data/{lib → packages/igniter-server/lib}/igniter/server/rack_app.rb +27 -2
  512. data/packages/igniter-server/lib/igniter/server/remote_adapter.rb +27 -0
  513. data/packages/igniter-server/lib/igniter/server/router.rb +291 -0
  514. data/packages/igniter-server/lib/igniter/server/server_logger.rb +54 -0
  515. data/packages/igniter-server/lib/igniter/server.rb +130 -0
  516. data/packages/igniter-server/lib/igniter-server.rb +3 -0
  517. metadata +638 -168
  518. data/docs/API_V2.md +0 -537
  519. data/docs/ARCHITECTURE_V2.md +0 -317
  520. data/docs/BACKLOG.md +0 -166
  521. data/docs/BRANCHES_V1.md +0 -213
  522. data/docs/COLLECTIONS_V1.md +0 -303
  523. data/docs/DISTRIBUTED_CONTRACTS_V1.md +0 -493
  524. data/docs/EXECUTION_MODEL_V2.md +0 -324
  525. data/docs/IGNITER_CONCEPTS.md +0 -81
  526. data/docs/LLM_V1.md +0 -335
  527. data/docs/PATTERNS.md +0 -411
  528. data/docs/SERVER_V1.md +0 -313
  529. data/docs/STORE_ADAPTERS.md +0 -126
  530. data/lib/igniter/diagnostics.rb +0 -8
  531. data/lib/igniter/executor.rb +0 -74
  532. data/lib/igniter/extensions/introspection/plan_formatter.rb +0 -55
  533. data/lib/igniter/extensions/invariants.rb +0 -116
  534. data/lib/igniter/integrations/agents.rb +0 -18
  535. data/lib/igniter/integrations/llm/config.rb +0 -69
  536. data/lib/igniter/integrations/llm/executor.rb +0 -159
  537. data/lib/igniter/integrations/llm.rb +0 -59
  538. data/lib/igniter/model/remote_node.rb +0 -26
  539. data/lib/igniter/runtime/execution.rb +0 -398
  540. data/lib/igniter/runtime/job_worker.rb +0 -18
  541. data/lib/igniter/runtime/planner.rb +0 -126
  542. data/lib/igniter/runtime/resolver.rb +0 -520
  543. data/lib/igniter/runtime/stores/redis_store.rb +0 -56
  544. data/lib/igniter/server/client.rb +0 -123
  545. data/lib/igniter/server/config.rb +0 -27
  546. data/lib/igniter/server/http_server.rb +0 -109
  547. data/lib/igniter/server/router.rb +0 -75
  548. data/lib/igniter/server.rb +0 -67
  549. /data/{lib → packages/igniter-agents/lib}/igniter/agent/mailbox.rb +0 -0
  550. /data/{lib → packages/igniter-agents/lib}/igniter/agent/message.rb +0 -0
  551. /data/{lib → packages/igniter-agents/lib}/igniter/agent/state_holder.rb +0 -0
  552. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/graph_compiler.rb +0 -0
  553. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/type_resolver.rb +0 -0
  554. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validation_context.rb +0 -0
  555. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validator.rb +0 -0
  556. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/await_validator.rb +0 -0
  557. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/callable_validator.rb +0 -0
  558. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/outputs_validator.rb +0 -0
  559. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/type_compatibility_validator.rb +0 -0
  560. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/compiler/validators/uniqueness_validator.rb +0 -0
  561. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/diagnostics/auditing/report/console_formatter.rb +0 -0
  562. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/diagnostics/auditing/report/markdown_formatter.rb +0 -0
  563. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/diagnostics/introspection/formatters/mermaid_formatter.rb +0 -0
  564. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/diagnostics/introspection/formatters/text_tree_formatter.rb +0 -0
  565. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/differential/divergence.rb +0 -0
  566. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/differential/formatter.rb +0 -0
  567. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/differential/report.rb +0 -0
  568. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/differential/runner.rb +0 -0
  569. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/differential.rb +0 -0
  570. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/dsl/schema_builder.rb +0 -0
  571. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/dsl.rb +0 -0
  572. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/effect_registry.rb +0 -0
  573. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/events/bus.rb +0 -0
  574. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/events/event.rb +0 -0
  575. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/events.rb +0 -0
  576. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/execution_report/builder.rb +0 -0
  577. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/execution_report/formatter.rb +0 -0
  578. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/execution_report/node_entry.rb +0 -0
  579. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/execution_report/report.rb +0 -0
  580. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/execution_report.rb +0 -0
  581. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/executor_registry.rb +0 -0
  582. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/auditing/timeline.rb +0 -0
  583. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/auditing.rb +0 -0
  584. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/introspection.rb +0 -0
  585. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/reactive/engine.rb +0 -0
  586. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/reactive/matcher.rb +0 -0
  587. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/reactive/reaction.rb +0 -0
  588. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions/reactive.rb +0 -0
  589. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/extensions.rb +0 -0
  590. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/incremental/formatter.rb +0 -0
  591. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/incremental/result.rb +0 -0
  592. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/incremental/tracker.rb +0 -0
  593. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/invariant.rb +0 -0
  594. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/await_node.rb +0 -0
  595. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/composition_node.rb +0 -0
  596. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/effect_node.rb +0 -0
  597. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/graph.rb +0 -0
  598. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/input_node.rb +0 -0
  599. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/node.rb +0 -0
  600. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/model/output_node.rb +0 -0
  601. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing/formatter.rb +0 -0
  602. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing/generators.rb +0 -0
  603. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing/result.rb +0 -0
  604. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing/run.rb +0 -0
  605. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/property_testing/runner.rb +0 -0
  606. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/provenance/lineage.rb +0 -0
  607. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/provenance/node_trace.rb +0 -0
  608. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/provenance/text_formatter.rb +0 -0
  609. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/provenance.rb +0 -0
  610. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/collection_result.rb +0 -0
  611. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/invalidator.rb +0 -0
  612. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/runner_factory.rb +0 -0
  613. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/runners/inline_runner.rb +0 -0
  614. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/runners/store_runner.rb +0 -0
  615. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/runners/thread_pool_runner.rb +0 -0
  616. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/stores/active_record_store.rb +0 -0
  617. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/stores/file_store.rb +0 -0
  618. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/runtime/stores/memory_store.rb +0 -0
  619. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga/compensation.rb +0 -0
  620. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga/compensation_record.rb +0 -0
  621. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga/executor.rb +0 -0
  622. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga/formatter.rb +0 -0
  623. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga/result.rb +0 -0
  624. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/saga.rb +0 -0
  625. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/stream_loop.rb +0 -0
  626. /data/{lib/igniter → packages/igniter-core/lib/igniter/core}/type_system.rb +0 -0
  627. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/cable_adapter.rb +0 -0
  628. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/contract_job.rb +0 -0
  629. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/generators/contract/contract_generator.rb +0 -0
  630. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/generators/install/install_generator.rb +0 -0
  631. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/railtie.rb +0 -0
  632. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails/webhook_concern.rb +0 -0
  633. /data/{lib/igniter/integrations → packages/igniter-rails/lib/igniter/plugins}/rails.rb +0 -0
  634. /data/{lib → packages/igniter-server/lib}/igniter/server/handlers/base.rb +0 -0
  635. /data/{lib → packages/igniter-server/lib}/igniter/server/handlers/contracts_handler.rb +0 -0
  636. /data/{lib → packages/igniter-server/lib}/igniter/server/handlers/health_handler.rb +0 -0
  637. /data/{lib → packages/igniter-server/lib}/igniter/server/handlers/status_handler.rb +0 -0
  638. /data/{lib → packages/igniter-server/lib}/igniter/server/registry.rb +0 -0
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Igniter
4
+ module Cluster
5
+ module RAG
6
+ # Merges and re-ranks RetrievalResult collections from multiple shards.
7
+ #
8
+ # Ranking is by composite_score, which weights raw text relevance by the
9
+ # source peer's trust status and observation confidence. This means a
10
+ # result from a trusted, high-confidence peer will beat an equally-
11
+ # relevant result from an unknown peer.
12
+ #
13
+ # Deduplication is id-based: when the same Chunk id appears in multiple
14
+ # shards, the highest-composite-score copy is kept.
15
+ #
16
+ # Entry point:
17
+ # ranker = Ranker.new
18
+ # merged = ranker.merge(local_results, remote_results_a, remote_results_b, limit: 10)
19
+ class Ranker
20
+ # Merge one or more RetrievalResult arrays into a single ranked list.
21
+ #
22
+ # @param result_arrays [Array<Array<RetrievalResult>>]
23
+ # @param limit [Integer, nil] max results; nil = no cap
24
+ # @param deduplicate [Boolean] remove duplicate chunk ids
25
+ # @return [Array<RetrievalResult>]
26
+ def merge(*result_arrays, limit: nil, deduplicate: true)
27
+ all = result_arrays.flatten
28
+ all = deduplicate(all) if deduplicate
29
+ sorted = all.sort_by { |r| -r.composite_score }
30
+ limit ? sorted.first(limit) : sorted
31
+ end
32
+
33
+ private
34
+
35
+ def deduplicate(results)
36
+ best = {}
37
+ results.each do |r|
38
+ existing = best[r.id]
39
+ best[r.id] = r if existing.nil? || r.composite_score > existing.composite_score
40
+ end
41
+ best.values
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Igniter
4
+ module Cluster
5
+ module RAG
6
+ # Typed specification for a knowledge retrieval request.
7
+ #
8
+ # Accepted by KnowledgeShard#search and Mesh.retrieve.
9
+ class RetrievalQuery
10
+ attr_reader :text, :tags, :limit, :min_score
11
+
12
+ # @param text [String] free-text query
13
+ # @param tags [Array<Symbol>] restrict to chunks that have ALL of these tags
14
+ # @param limit [Integer] max results to return
15
+ # @param min_score [Float] minimum text relevance score (0..1)
16
+ def initialize(text:, tags: [], limit: 10, min_score: 0.0)
17
+ @text = text.to_s.freeze
18
+ @tags = Array(tags).map(&:to_sym).freeze
19
+ @limit = [limit.to_i, 1].max
20
+ @min_score = [min_score.to_f, 0.0].max
21
+ freeze
22
+ end
23
+
24
+ def to_h
25
+ { text: @text, tags: @tags, limit: @limit, min_score: @min_score }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Igniter
4
+ module Cluster
5
+ module RAG
6
+ # A single result returned by KnowledgeShard#search or the Ranker.
7
+ #
8
+ # Carries the matched Chunk together with retrieval provenance:
9
+ # text relevance score, source shard name, and (optionally) the
10
+ # NodeObservation of the peer that holds the shard.
11
+ #
12
+ # composite_score weights the raw text score by the peer's trust
13
+ # status and observation confidence — results from trusted, high-
14
+ # confidence peers rank above equally-relevant but untrusted ones.
15
+ class RetrievalResult
16
+ attr_reader :chunk, :score, :source, :observation
17
+
18
+ # @param chunk [Chunk] the matched knowledge unit
19
+ # @param score [Float] raw text relevance score (0..1)
20
+ # @param source [String] shard name / peer name
21
+ # @param observation [NodeObservation, nil] live peer snapshot (nil = local)
22
+ def initialize(chunk:, score:, source:, observation: nil)
23
+ @chunk = chunk
24
+ @score = score.to_f
25
+ @source = source.to_s.freeze
26
+ @observation = observation
27
+ freeze
28
+ end
29
+
30
+ # Chunk attribute shortcuts
31
+ def id; @chunk.id; end
32
+ def content; @chunk.content; end
33
+ def tags; @chunk.tags; end
34
+ def metadata; @chunk.metadata; end
35
+ def indexed_at; @chunk.indexed_at; end
36
+
37
+ # Provenance accessors
38
+ def trusted?
39
+ @observation ? @observation.trusted? : true
40
+ end
41
+
42
+ def confidence
43
+ @observation&.confidence || 1.0
44
+ end
45
+
46
+ # Composite score = raw_score × trust_factor × confidence
47
+ #
48
+ # trust_factor:
49
+ # trusted peer → 1.00
50
+ # unknown peer → 0.85
51
+ # untrusted peer → 0.70
52
+ def composite_score
53
+ trust_factor = case @observation&.trust_status
54
+ when :trusted then 1.00
55
+ when nil then 1.00 # local / no observation
56
+ else
57
+ @observation.trusted? ? 1.00 : 0.85
58
+ end
59
+ (@score * trust_factor * confidence).round(6)
60
+ end
61
+
62
+ def to_h
63
+ {
64
+ id: id,
65
+ content: content,
66
+ score: @score,
67
+ composite_score: composite_score,
68
+ source: @source,
69
+ tags: tags,
70
+ trusted: trusted?,
71
+ confidence: confidence
72
+ }
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rag/chunk"
4
+ require_relative "rag/retrieval_query"
5
+ require_relative "rag/retrieval_result"
6
+ require_relative "rag/knowledge_shard"
7
+ require_relative "rag/ranker"
8
+ require_relative "rag/net_http_adapter"
9
+ require_relative "rag/fanout_retriever"
10
+
11
+ module Igniter
12
+ module Cluster
13
+ # Phase 5+7: Decentralized Knowledge Plane.
14
+ #
15
+ # Each cluster node can maintain a local KnowledgeShard — a content-addressed
16
+ # store of text chunks that can be searched via keyword relevance.
17
+ #
18
+ # v1: local shard retrieval with trust-aware scoring.
19
+ # v2: distributed fan-out to remote `:rag`-capable peers via FanoutRetriever.
20
+ #
21
+ # Cluster integration:
22
+ # Igniter::Cluster::Mesh.configure { |c| c.local_capabilities << :rag }
23
+ # Igniter::Cluster::Mesh.shard.add("Ruby closures bind at creation time", tags: [:ruby])
24
+ #
25
+ # # Local only (default):
26
+ # results = Igniter::Cluster::Mesh.retrieve("how closures work", limit: 5)
27
+ #
28
+ # # Distributed fan-out:
29
+ # results = Igniter::Cluster::Mesh.retrieve("how closures work", distributed: true)
30
+ #
31
+ # Standalone:
32
+ # shard = Igniter::Cluster::RAG::KnowledgeShard.new(name: "my-shard")
33
+ # shard.add("...", tags: [:topic])
34
+ # results = shard.search("query text", tags: [:topic], limit: 10)
35
+ module RAG
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Igniter
4
+ module Cluster
5
+ # Cluster-aware remote adapter.
6
+ #
7
+ # Builds on top of the plain server transport and adds capability/pinned
8
+ # peer resolution via mesh routing.
9
+ class RemoteAdapter < Igniter::Server::RemoteAdapter
10
+ def call(node:, inputs:, execution: nil)
11
+ super
12
+ rescue Igniter::Cluster::Mesh::DeferredCapabilityError => e
13
+ publish_pending_routing_trace(node, e, execution)
14
+ raise
15
+ rescue Igniter::Cluster::Mesh::IncidentError => e
16
+ publish_failed_routing_trace(node, e, execution)
17
+ raise
18
+ end
19
+
20
+ private
21
+
22
+ def resolve_url(node)
23
+ case node.routing_mode
24
+ when :capability
25
+ resolve_capability_url(node)
26
+ when :pinned
27
+ resolve_pinned_url(node)
28
+ else
29
+ super
30
+ end
31
+ end
32
+
33
+ def resolve_capability_url(node)
34
+ query = node.capability_query || { all_of: [node.capability] }
35
+ deferred = Igniter::Runtime::DeferredResult.build(
36
+ payload: { capability: node.capability, query: query },
37
+ source_node: node.name,
38
+ waiting_on: node.name
39
+ )
40
+ if node.capability_query
41
+ Igniter::Cluster::Mesh.router.find_peer_for_query(node.capability_query, deferred)
42
+ else
43
+ Igniter::Cluster::Mesh.router.find_peer_for(node.capability, deferred)
44
+ end
45
+ end
46
+
47
+ def resolve_pinned_url(node)
48
+ Igniter::Cluster::Mesh.router.resolve_pinned(node.pinned_to)
49
+ end
50
+
51
+ def publish_pending_routing_trace(node, error, execution)
52
+ report = Igniter::Cluster::Diagnostics::RoutingContributor.report_for_trace(
53
+ node_name: node.name,
54
+ path: node.path,
55
+ status: :pending,
56
+ routing_trace: error.explanation,
57
+ token: error.deferred_result.token,
58
+ waiting_on: error.deferred_result.waiting_on || node.name,
59
+ source_node: error.deferred_result.source_node || node.name,
60
+ latest_event_type: :node_pending
61
+ )
62
+
63
+ enrich_and_record_report!(report, execution)
64
+ end
65
+
66
+ def publish_failed_routing_trace(node, error, execution)
67
+ routing_trace = error.context[:routing_trace]
68
+ return unless routing_trace
69
+
70
+ report = Igniter::Cluster::Diagnostics::RoutingContributor.report_for_trace(
71
+ node_name: node.name,
72
+ path: node.path,
73
+ status: :failed,
74
+ routing_trace: routing_trace,
75
+ error: {
76
+ type: error.class.name,
77
+ message: error.message
78
+ },
79
+ latest_event_type: :node_failed
80
+ )
81
+
82
+ enrich_and_record_report!(report, execution)
83
+ end
84
+
85
+ def enrich_and_record_report!(report, execution)
86
+ return unless report.is_a?(Hash)
87
+
88
+ if execution
89
+ report = report.merge(
90
+ graph: execution.compiled_graph.name,
91
+ execution_id: execution.events.execution_id
92
+ )
93
+ end
94
+
95
+ Igniter::Cluster::Mesh.config.record_routing_report!(report)
96
+ rescue StandardError
97
+ nil
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Igniter
4
+ module Cluster
5
+ module Replication
6
+ # Abstract base class for deployment bootstrappers.
7
+ #
8
+ # Subclasses implement three lifecycle methods:
9
+ # install — copy/install the application on the remote
10
+ # start — launch the application process
11
+ # verify — confirm the application is running (default impl provided)
12
+ class Bootstrapper
13
+ BootstrapError = Class.new(Igniter::Error)
14
+
15
+ # Install the application on the remote server.
16
+ #
17
+ # @param session [SSHSession] active SSH session to the remote host
18
+ # @param manifest [Manifest] self-description of the running instance
19
+ # @param env [Hash] environment variables to write on remote
20
+ # @param target_path [String] base directory on the remote server
21
+ def install(session:, manifest:, env: {}, target_path: "/opt/igniter")
22
+ raise NotImplementedError, "#{self.class}#install not implemented"
23
+ end
24
+
25
+ # Start the application on the remote server.
26
+ #
27
+ # @param session [SSHSession] active SSH session to the remote host
28
+ # @param manifest [Manifest] self-description of the running instance
29
+ # @param target_path [String] base directory on the remote server
30
+ def start(session:, manifest:, target_path: "/opt/igniter")
31
+ raise NotImplementedError, "#{self.class}#start not implemented"
32
+ end
33
+
34
+ # Verify the application is running on the remote server.
35
+ # Returns true if Igniter can be loaded, false otherwise.
36
+ #
37
+ # @param session [SSHSession] active SSH session to the remote host
38
+ # @param target_path [String] base directory on the remote server (unused by default impl)
39
+ def verify(session:, target_path: "/opt/igniter") # rubocop:disable Lint/UnusedMethodArgument
40
+ result = session.exec("ruby -e 'require \"igniter\"; puts Igniter::VERSION' 2>/dev/null")
41
+ result[:success] && !result[:stdout].strip.empty?
42
+ rescue SSHSession::SSHError
43
+ false
44
+ end
45
+
46
+ protected
47
+
48
+ # Write environment variables to a shell-sourceable file on the remote.
49
+ #
50
+ # @param session [SSHSession] active SSH session
51
+ # @param env [Hash] key-value pairs to export
52
+ # @param path [String] remote path for the env file
53
+ def write_env_file(session:, env:, path:)
54
+ return if env.nil? || env.empty?
55
+
56
+ require "shellwords"
57
+ lines = env.map { |k, v| "export #{k}=#{v.to_s.shellescape}" }.join("\n")
58
+ session.exec!("printf '%s\\n' #{lines.shellescape} > #{path}")
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shellwords"
4
+
5
+ module Igniter
6
+ module Cluster
7
+ module Replication
8
+ module Bootstrappers
9
+ # Deploys by installing the igniter gem from RubyGems on the remote host.
10
+ #
11
+ # Optionally pins a specific gem version. The startup script defaults to
12
+ # the +igniter-stack+ executable installed with the gem.
13
+ class Gem < Bootstrapper
14
+ def initialize(version: nil, startup_script: nil)
15
+ super()
16
+ @version = version
17
+ @startup_script = startup_script
18
+ end
19
+
20
+ def install(session:, manifest:, env: {}, target_path: "/opt/igniter") # rubocop:disable Lint/UnusedMethodArgument
21
+ ver_flag = @version ? " -v #{@version}" : ""
22
+ session.exec!("gem install igniter#{ver_flag} --no-document")
23
+ session.exec!("mkdir -p #{target_path}")
24
+ write_env_file(session: session, env: env, path: "#{target_path}/.env")
25
+ end
26
+
27
+ def start(session:, manifest:, target_path: "/opt/igniter") # rubocop:disable Lint/UnusedMethodArgument
28
+ log_path = "#{target_path}/igniter.log"
29
+ pid_path = "#{target_path}/igniter.pid"
30
+ script = @startup_script || "igniter-stack"
31
+ session.exec!(
32
+ "sh -lc 'nohup #{script} >> #{Shellwords.escape(log_path)} 2>&1 & echo $! > #{Shellwords.escape(pid_path)}'"
33
+ )
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shellwords"
4
+
5
+ module Igniter
6
+ module Cluster
7
+ module Replication
8
+ module Bootstrappers
9
+ # Deploys by cloning a git repository on the remote host.
10
+ #
11
+ # Requires git to be installed on the remote. After cloning, installs
12
+ # bundler and runs bundle install.
13
+ class Git < Bootstrapper
14
+ DEFAULT_BRANCH = "main"
15
+ DEFAULT_BUNDLE_OPTIONS = "--without development test"
16
+
17
+ def initialize(repo_url:, branch: DEFAULT_BRANCH, bundle_options: DEFAULT_BUNDLE_OPTIONS)
18
+ super()
19
+ @repo_url = repo_url
20
+ @branch = branch
21
+ @bundle_options = bundle_options
22
+ end
23
+
24
+ def install(session:, manifest:, env: {}, target_path: "/opt/igniter") # rubocop:disable Lint/UnusedMethodArgument
25
+ app_path = "#{target_path}/app"
26
+ session.exec!("mkdir -p #{target_path}")
27
+ session.exec!("git clone --branch #{@branch} --depth 1 #{@repo_url} #{app_path}")
28
+ session.exec!("cd #{app_path} && gem install bundler --no-document")
29
+ session.exec!("cd #{app_path} && bundle install #{@bundle_options}")
30
+ write_env_file(session: session, env: env, path: "#{target_path}/.env")
31
+ end
32
+
33
+ def start(session:, manifest:, target_path: "/opt/igniter")
34
+ app_path = "#{target_path}/app"
35
+ log_path = "#{target_path}/igniter.log"
36
+ pid_path = "#{target_path}/igniter.pid"
37
+ cmd = manifest.startup_command
38
+ session.exec!(
39
+ "sh -lc 'cd #{Shellwords.escape(app_path)} && nohup ruby #{cmd} >> #{Shellwords.escape(log_path)} 2>&1 & echo $! > #{Shellwords.escape(pid_path)}'"
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "tmpdir"
4
+ require "fileutils"
5
+ require "shellwords"
6
+
7
+ module Igniter
8
+ module Cluster
9
+ module Replication
10
+ module Bootstrappers
11
+ # Deploys by creating a gzipped tarball of the local source tree,
12
+ # uploading it via SCP, and extracting it on the remote host.
13
+ #
14
+ # This strategy works without git or internet access on the remote,
15
+ # making it suitable for air-gapped or private environments.
16
+ class Tarball < Bootstrapper
17
+ def install(session:, manifest:, env: {}, target_path: "/opt/igniter")
18
+ tarball = create_tarball(manifest)
19
+ begin
20
+ remote_tar = "/tmp/igniter_replication_#{Process.pid}.tar.gz"
21
+ session.upload!(tarball, remote_tar)
22
+ extract_and_install(session, remote_tar, target_path)
23
+ write_env_file(session: session, env: env, path: "#{target_path}/.env")
24
+ ensure
25
+ FileUtils.rm_f(tarball)
26
+ end
27
+ end
28
+
29
+ def start(session:, manifest:, target_path: "/opt/igniter")
30
+ app_path = "#{target_path}/app"
31
+ log_path = "#{target_path}/igniter.log"
32
+ pid_path = "#{target_path}/igniter.pid"
33
+ cmd = File.basename(manifest.startup_command)
34
+ session.exec!(
35
+ "sh -lc 'cd #{Shellwords.escape(app_path)} && nohup ruby #{cmd} >> #{Shellwords.escape(log_path)} 2>&1 & echo $! > #{Shellwords.escape(pid_path)}'"
36
+ )
37
+ end
38
+
39
+ private
40
+
41
+ def extract_and_install(session, remote_tar, target_path)
42
+ app_path = "#{target_path}/app"
43
+ session.exec!("mkdir -p #{app_path}")
44
+ session.exec!("tar -xzf #{remote_tar} -C #{app_path} --strip-components=1")
45
+ session.exec!("cd #{app_path} && gem install bundler --no-document")
46
+ session.exec!("cd #{app_path} && bundle install --without development test")
47
+ session.exec!("rm -f #{remote_tar}")
48
+ end
49
+
50
+ def create_tarball(manifest)
51
+ source = manifest.source_path
52
+ tmpfile = File.join(Dir.tmpdir, "igniter_replication_#{Process.pid}.tar.gz")
53
+ parent = File.dirname(source)
54
+ name = File.basename(source)
55
+ system("tar", "-czf", tmpfile, "-C", parent, name)
56
+ tmpfile
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end