insika 0.3.0 → 0.7.0

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 (190) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +180 -0
  3. data/README.md +45 -10
  4. data/bin/insika +684 -0
  5. data/bin/insika-router +87 -0
  6. data/docs/AGENTS.md +94 -403
  7. data/docs/API.md +5 -5
  8. data/docs/ARCHITECTURE.md +3 -2
  9. data/docs/ARTIFACTS.md +95 -0
  10. data/docs/BENCHMARK.md +2 -2
  11. data/docs/CHANNELS.md +14 -14
  12. data/docs/CONTEXT.md +9 -7
  13. data/docs/DEMO.md +80 -0
  14. data/docs/DEPLOY.md +71 -3
  15. data/docs/EMBEDDING.md +1 -1
  16. data/docs/EVALS.md +128 -3
  17. data/docs/FACTS.md +3 -3
  18. data/docs/HARVEST.md +5 -6
  19. data/docs/KNOWLEDGE.md +290 -0
  20. data/docs/LOADTEST.md +2 -2
  21. data/docs/MEDIA.md +128 -0
  22. data/docs/OBSERVABILITY.md +15 -10
  23. data/docs/OUTCOMES.md +137 -0
  24. data/docs/PLUGINS.md +51 -6
  25. data/docs/POLICY.md +216 -0
  26. data/docs/REFINEMENT.md +14 -9
  27. data/docs/RELEASING.md +4 -4
  28. data/docs/ROUTER.md +213 -0
  29. data/docs/RUNNING-LOCAL.md +3 -3
  30. data/docs/SCHEDULING.md +121 -0
  31. data/docs/SECURITY.md +22 -6
  32. data/docs/SKILLS.md +11 -2
  33. data/docs/SOAK.md +2 -2
  34. data/docs/TEMPLATES.md +134 -0
  35. data/docs/TOOLS.md +152 -27
  36. data/docs/WHY.md +1 -1
  37. data/docs/WORKFLOWS.md +2 -2
  38. data/docs/_includes/head_custom.html +5 -0
  39. data/docs/_includes/title.html +13 -0
  40. data/docs/_sass/color_schemes/insika.scss +32 -0
  41. data/docs/_sass/custom/custom.scss +199 -0
  42. data/docs/_sass/custom/setup.scss +26 -0
  43. data/docs/assets/img/favicon.svg +7 -0
  44. data/docs/assets/img/insika-mark.svg +7 -0
  45. data/docs/core-concepts.md +21 -0
  46. data/docs/domain.md +4 -4
  47. data/docs/improve.md +20 -0
  48. data/docs/index.md +8 -5
  49. data/docs/integrate.md +20 -0
  50. data/docs/operate.md +13 -6
  51. data/docs/prompts/ADD-TOOL.md +118 -0
  52. data/docs/prompts/DIAGNOSE-TURN.md +65 -0
  53. data/docs/prompts/GO-LIVE.md +138 -0
  54. data/docs/prompts/RUN-EXAMPLES.md +70 -0
  55. data/docs/reference.md +19 -0
  56. data/docs/ship.md +10 -2
  57. data/docs/start-here.md +18 -0
  58. data/lib/insika/agent_profile.rb +73 -16
  59. data/lib/insika/artifact_signing.rb +82 -0
  60. data/lib/insika/artifact_store.rb +160 -0
  61. data/lib/insika/channel_delivery.rb +1 -1
  62. data/lib/insika/chat_builder.rb +22 -2
  63. data/lib/insika/commands/agent_payload.rb +2 -2
  64. data/lib/insika/commands/backfill_knowledge.rb +145 -0
  65. data/lib/insika/commands/delete_artifact.rb +35 -0
  66. data/lib/insika/commands/delete_concept.rb +34 -0
  67. data/lib/insika/commands/delete_mcp.rb +6 -2
  68. data/lib/insika/commands/delete_tenant_data.rb +15 -3
  69. data/lib/insika/commands/gate_refinement.rb +1 -1
  70. data/lib/insika/commands/refresh_mcp_tools.rb +47 -0
  71. data/lib/insika/commands/restore_concept.rb +34 -0
  72. data/lib/insika/commands/seed_demo_data.rb +31 -0
  73. data/lib/insika/commands/upsert_mcp.rb +6 -3
  74. data/lib/insika/commands/write_concept.rb +57 -0
  75. data/lib/insika/context/priority.rb +2 -0
  76. data/lib/insika/context/providers/knowledge.rb +108 -0
  77. data/lib/insika/context/providers/prompt.rb +30 -24
  78. data/lib/insika/cron.rb +189 -0
  79. data/lib/insika/demo/agent_attrs.rb +43 -0
  80. data/lib/insika/demo/golden_cases.rb +81 -0
  81. data/lib/insika/demo/seeder.rb +336 -0
  82. data/lib/insika/doctor.rb +176 -8
  83. data/lib/insika/dsl/definition.rb +3 -2
  84. data/lib/insika/dsl/runtime.rb +60 -79
  85. data/lib/insika/dsl/server_boot.rb +23 -1
  86. data/lib/insika/dsl/system.rb +10 -2
  87. data/lib/insika/dsl.rb +103 -2
  88. data/lib/insika/env_schema.rb +16 -1
  89. data/lib/insika/evals/golden.rb +41 -4
  90. data/lib/insika/evals/judge.rb +47 -2
  91. data/lib/insika/evals/pairwise.rb +11 -0
  92. data/lib/insika/evals/persona.rb +98 -0
  93. data/lib/insika/evals/runner.rb +9 -0
  94. data/lib/insika/evals/simulator.rb +225 -0
  95. data/lib/insika/evals/transport.rb +83 -1
  96. data/lib/insika/event_stream.rb +10 -0
  97. data/lib/insika/executor.rb +231 -55
  98. data/lib/insika/followup_policy.rb +2 -25
  99. data/lib/insika/golden_store.rb +16 -1
  100. data/lib/insika/grounding/matcher.rb +1 -1
  101. data/lib/insika/knowledge.rb +680 -0
  102. data/lib/insika/knowledge_store.rb +140 -0
  103. data/lib/insika/mcp_client.rb +94 -0
  104. data/lib/insika/mcp_json.rb +74 -0
  105. data/lib/insika/mcp_live_tool.rb +43 -0
  106. data/lib/insika/mcp_store.rb +98 -26
  107. data/lib/insika/mcp_tool_ingestor.rb +30 -8
  108. data/lib/insika/mcp_tool_registry.rb +100 -0
  109. data/lib/insika/media.rb +115 -31
  110. data/lib/insika/message_origin.rb +1 -1
  111. data/lib/insika/middleware.rb +9 -0
  112. data/lib/insika/onboarding.rb +17 -1
  113. data/lib/insika/outcome_store.rb +1 -1
  114. data/lib/insika/overlay_tool_registry.rb +37 -17
  115. data/lib/insika/packaging.rb +2 -2
  116. data/lib/insika/profile_source.rb +8 -1
  117. data/lib/insika/prompt_catalog.rb +10 -0
  118. data/lib/insika/retention.rb +36 -1
  119. data/lib/insika/router/app.rb +157 -0
  120. data/lib/insika/router/backend_pool.rb +98 -0
  121. data/lib/insika/router/hash_ring.rb +55 -0
  122. data/lib/insika/router/proxy_body.rb +34 -0
  123. data/lib/insika/router/session_key.rb +54 -0
  124. data/lib/insika/router.rb +18 -0
  125. data/lib/insika/schedule.rb +177 -0
  126. data/lib/insika/schedule_engine.rb +314 -0
  127. data/lib/insika/schedule_store.rb +208 -0
  128. data/lib/insika/server/app.rb +105 -15
  129. data/lib/insika/server/rack_app.rb +5 -1
  130. data/lib/insika/server/responses.rb +1 -1
  131. data/lib/insika/skill_catalog.rb +12 -0
  132. data/lib/insika/steer_injector.rb +21 -10
  133. data/lib/insika/studio/app.rb +567 -45
  134. data/lib/insika/studio/assets/dist/application.css +1 -1
  135. data/lib/insika/studio/assets/dist/application.js +21 -21
  136. data/lib/insika/studio/forms.rb +46 -5
  137. data/lib/insika/studio/nav_icons.rb +14 -1
  138. data/lib/insika/studio/views/_agent_tab_cache.erb +25 -0
  139. data/lib/insika/studio/views/_agent_tab_config.erb +514 -0
  140. data/lib/insika/studio/views/_agent_tab_history.erb +24 -0
  141. data/lib/insika/studio/views/_agent_tab_loops.erb +54 -0
  142. data/lib/insika/studio/views/_agent_tab_memory.erb +51 -0
  143. data/lib/insika/studio/views/_agent_tab_outcomes.erb +31 -0
  144. data/lib/insika/studio/views/_agent_tab_prompts.erb +108 -0
  145. data/lib/insika/studio/views/_agent_tab_skills.erb +38 -0
  146. data/lib/insika/studio/views/_agents_master.erb +44 -0
  147. data/lib/insika/studio/views/_message.erb +49 -32
  148. data/lib/insika/studio/views/agent_detail.erb +61 -820
  149. data/lib/insika/studio/views/agents.erb +70 -57
  150. data/lib/insika/studio/views/artifact.erb +23 -0
  151. data/lib/insika/studio/views/artifacts.erb +59 -0
  152. data/lib/insika/studio/views/evals.erb +2 -2
  153. data/lib/insika/studio/views/facts.erb +1 -1
  154. data/lib/insika/studio/views/funnel.erb +1 -1
  155. data/lib/insika/studio/views/home.erb +106 -67
  156. data/lib/insika/studio/views/knowledge.erb +123 -0
  157. data/lib/insika/studio/views/layout.erb +14 -11
  158. data/lib/insika/studio/views/mcp.erb +174 -80
  159. data/lib/insika/studio/views/session.erb +231 -177
  160. data/lib/insika/studio/views/settings.erb +39 -1
  161. data/lib/insika/studio/views/skills.erb +1 -1
  162. data/lib/insika/studio/views/tools.erb +24 -9
  163. data/lib/insika/templates/browser-agent/README.md +36 -0
  164. data/lib/insika/templates/browser-agent/agent.rb +49 -0
  165. data/lib/insika/templates/daily-digest/README.md +38 -0
  166. data/lib/insika/templates/daily-digest/agent.rb +77 -0
  167. data/lib/insika/templates/repo-explorer/README.md +36 -0
  168. data/lib/insika/templates/repo-explorer/agent.rb +45 -0
  169. data/lib/insika/templates/research-analyst/README.md +26 -0
  170. data/lib/insika/templates/research-analyst/agent.rb +58 -0
  171. data/lib/insika/templates/review-panel/README.md +20 -0
  172. data/lib/insika/templates/review-panel/agent.rb +50 -0
  173. data/lib/insika/templates/travel-planner/README.md +35 -0
  174. data/lib/insika/templates/travel-planner/agent.rb +87 -0
  175. data/lib/insika/templates.rb +112 -0
  176. data/lib/insika/tick.rb +24 -12
  177. data/lib/insika/timezone.rb +45 -0
  178. data/lib/insika/tools/generate_image.rb +52 -7
  179. data/lib/insika/tools/load_knowledge.rb +74 -0
  180. data/lib/insika/tools/run_persona_eval.rb +328 -0
  181. data/lib/insika/tools/save_artifact.rb +95 -0
  182. data/lib/insika/turn_output.rb +1 -1
  183. data/lib/insika/turn_state.rb +15 -4
  184. data/lib/insika/version.rb +1 -1
  185. data/lib/insika/wiring/graph.rb +184 -12
  186. data/lib/insika/wiring/graph_chat.rb +102 -0
  187. data/lib/insika.rb +57 -0
  188. metadata +105 -5
  189. data/docs/build.md +0 -14
  190. data/docs/understand.md +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9ac198fc4ba91d6f3d3b55ebdf782b326bee455d45be766befaff3fc761009ff
4
- data.tar.gz: e315b3f30cbe8365bbb3c6db6477209935ac71f5d0cadca26b6a5bc3458fa1cb
3
+ metadata.gz: 5c2b2fbe064af45aa132f93de00954b24dc504e052db2e059b4f6daa151e248b
4
+ data.tar.gz: 50cabcc10d82eabdfd08de562bd61feddf1a9de68ee6427343c80c5cf6ad9d8c
5
5
  SHA512:
6
- metadata.gz: 985b9924a6996aeb9a180ae6c800191029aaaad48ea55c18ffb35e8df159b14fbbc801bf7fc7cc33dc2291c6f8e80ffba078578f715ee062410c0504579819d3
7
- data.tar.gz: a3a7dd5ff765f9fd652b116f7a8b03c05d3fb29cc582e1a14508e5e0ee5afb088b2d755a194da9e378b262871f84a884adbbc18a8e5e65f8af36b49706b76047
6
+ metadata.gz: 3004e30a234349bcb91db185fcc31f9b52cbdeb7660c613b1fc229adf6bbbe717d9abc8ebcdc5bf9ecc125986694c0d2f3a82e1d48eb83105ff74db0467e4d91
7
+ data.tar.gz: ca4bec6a8b8cd03ee1a5c2df627e7da778d3dd157f30f848c70f8077ac467570284bf934e3a4c8040fb223503855d9cdcad111b9139ed093c702b6a8850ea1ff
data/CHANGELOG.md CHANGED
@@ -8,6 +8,186 @@ it is released. Entries land with the pull request that makes the change.
8
8
 
9
9
  ## [Unreleased]
10
10
 
11
+ ## [0.7.0] - 2026-08-29
12
+
13
+ The pre-1.0 consolidation: MCP servers as first-class tools, a template gallery,
14
+ the knowledge layer (extract → consolidate → retrieve → export), a session-sticky
15
+ router for N>1 capacity, and the Studio brought to visual parity. The `/v1`
16
+ contract is unchanged. The version jumps from 0.3 to 0.7 to say what the code
17
+ already says — the surface is the 1.0 surface; what remains is operational proof,
18
+ not features.
19
+
20
+ ### Fixed
21
+
22
+ - **An agent's identity never falls back to another agent's.** An agent with
23
+ neither `prompt_files` nor `base_prompt` silently inherited the deployment-wide
24
+ default identity, so one agent could answer as another's persona (seen live,
25
+ deterministic, previously misdiagnosed as a concurrency bug). It now raises
26
+ `Insika::ContextError` and aborts the turn instead.
27
+ - **A text-only turn absorbs a burst of messages instead of leaking a follow-up.**
28
+ Steering only drained the mailbox at a tool-batch boundary; a turn with no tool
29
+ calls never had one, so a customer who sent four messages in a row got one
30
+ answer that only saw the first. The executor now runs one extra round in the
31
+ same turn when the mailbox is not empty.
32
+ - **The turn supervisor starts at boot, not on the first served turn** — a
33
+ deployment whose only agents are scheduled never fired tick/alert/distill
34
+ workers until unrelated traffic arrived.
35
+ - **Every Linux/Docker build was failing** on two independent packaging gaps:
36
+ `Gemfile.lock` only listed `arm64-darwin` (#185), and the Dockerfile's builder
37
+ stage did not copy `lib/insika/packaging.rb`, which the gemspec requires (#184;
38
+ a spec now parses the Dockerfile against the gemspec's `require_relative`s).
39
+ - **MCP**: `refresh` reused a permanently broken memoized client, so an edited
40
+ server config needed a full process restart; and ruby_llm-mcp sent a
41
+ spec-invalid `Origin` header (URL with a path) that Origin-checking servers
42
+ (GitHub, Grafana, Metabase) rejected on every request — now stripped.
43
+ - **Media**: STT and image-generation calls always raised past the RubyLLM
44
+ boundary (raw bytes where a path was expected, `assume_model_exists` with no
45
+ provider). Found live-validating against real audio/PDF fixtures; a contract
46
+ spec now guards the boundary.
47
+ - **`insika harvest`/`knowledge:backfill` never wired the CLI's provider
48
+ keys** — both build their own miner/extractor `ask` outside a full app
49
+ boot (no `LlmConfigurator`), so `RubyLLM.config` was empty and a real run
50
+ raised `RubyLLM::ConfigurationError` on the first live call, no matter how
51
+ the agent was configured. Found running `knowledge:backfill` against real
52
+ staging traffic for the first time. `configure_eval_llm!` (added for
53
+ `evals:simulate`, PR #190) is now `configure_cli_llm!` and both commands
54
+ call it before building their factory.
55
+
56
+ ### Added
57
+
58
+ - **MCP servers are first-class tools** (#178–#182). `Insika::McpClient` builds a
59
+ real stdio/http/sse client (ruby_llm-mcp, lazy-loaded) from an `McpStore`
60
+ record; `McpToolRegistry` executes live through it, merged into the overlay
61
+ registry as a third source (base > data-tools > mcp) so allowlists, traces,
62
+ budgets and checkpoints work unchanged. Config surfaces: JSON import/export in
63
+ the `mcpServers` format, `insika mcp list|add|remove|import|test|refresh`, the
64
+ `mcp` DSL declaration (which auto-grants `mcp:<name>` on the agent's allowlist),
65
+ `/v1/mcp`, and a transport-aware `/studio/mcp` page with per-instance status and
66
+ "Test connection". stdio is arbitrary command execution by config and stays
67
+ behind `INSIKA_MCP_STDIO=1`.
68
+ - **Template gallery** (#183). Six example agents ship inside the gem
69
+ (`lib/insika/templates/<name>/agent.rb` + README) — one DSL file is both doors:
70
+ `insika new` copies it, the Studio gallery instantiates it. Starter
71
+ (travel-planner, keyless public APIs), Advanced (research-analyst fan-out),
72
+ Always-on (daily-digest: schedule + artifact), Teams (review-panel) and more.
73
+ - **Session-sticky router** — `insika-router`, a standalone Async/Falcon proxy that
74
+ runs N engine backends (`WEB_CONCURRENCY=1` each) behind a consistent-hash ring
75
+ keyed on the session id, so per-session FIFO/collect/steer guarantees hold at
76
+ N>1 capacity with no change to the executor. Static (Railway) and DNS
77
+ (Kubernetes headless Service) backend discovery; an unreachable backend answers
78
+ the retry envelope. Opt-in.
79
+ - **Studio visual parity** — view transitions and motion (CSS only, reduced-motion
80
+ aware), the transcript as product (mono label rows, tool calls as pill chips,
81
+ three-zone session viewer), a live home over `/studio/events`, master-detail
82
+ lists.
83
+ - **`queue_mode` and `steer_max_messages` editable per agent** in the Studio
84
+ Config form — operations can switch steering on/off without touching the store.
85
+ Blank inherits the platform default; `steer_max_messages: 0` never steers.
86
+ - **Paste-prompt journeys for coding agents** — four skill-shaped prompts under
87
+ `docs/prompts/`, served at `GET /docs/<name>.md` next to `start.md`:
88
+ run-examples, add-tool, diagnose-turn and go-live.
89
+ - **`run_persona_eval` swaps side-effect tools instead of refusing** — a target
90
+ agent with a reachable POST tool gets a throwaway executor whose registry
91
+ resolves every side-effect name to a recorder, sharing every other collaborator
92
+ of the real graph.
93
+ - **`examples/analytics`** — MCP wired to a real, key-authenticated server
94
+ (OpenSEO over http, bearer via `OPENSEO_API_KEY`).
95
+ - **`insika knowledge:export`** — writes one `<name>.md` per learned concept
96
+ under a directory (`KnowledgeStore#export_dir`). The storage format IS the
97
+ export format, so it's a dump, not a converter, directly consumable by
98
+ okf-gem/graphify. Idempotent — nothing here is lossy, so there's no
99
+ `--force` to reason about. `--format graphml` writes one combined
100
+ `knowledge.graphml` instead — a node per concept, an edge per `[[link]]`
101
+ resolved against the same export set (a dangling link is dropped, never a
102
+ broken edge) — hand-built, hand-escaped XML, no new dependency.
103
+
104
+ - **Knowledge retrieval** — with `knowledge: {retrieve: true}`, every turn
105
+ the engine now searches the agent's learned concepts for the ones
106
+ relevant to the customer's message (`Insika::Knowledge::Index::Scan` —
107
+ pure term overlap × confidence × recency, no embeddings, no network call)
108
+ and injects the top few as a level-1 `<knowledge>` block (name/
109
+ description/confidence/provenance, new `Context::Priority::KNOWLEDGE =
110
+ 77`, between skills and memory), expanding one hop through a concept's
111
+ `[[links]]`. A `load_knowledge` tool — outside `tools_allow`, wired
112
+ exactly like `load_skill` — loads a concept's full body on demand;
113
+ calling it fires `:knowledge_retrieved`, the adoption metric that
114
+ actually matters (a concept sitting unread in the prompt taught nothing).
115
+ `knowledge.index: "fts5"` is accepted but falls back to the built-in scan
116
+ index — deliberately not built yet: `scripts/bench_knowledge_index.rb`
117
+ measured `Index::Scan` at hundreds of milliseconds per search before a
118
+ read-cache fix (re-parsing a concept's frontmatter on every search was
119
+ ~90% of the cost, not the store I/O); after the fix it's sub-1.5ms at the
120
+ concept counts this feature targets, and building the SQLite adapter is
121
+ deferred to a real, documented latency trigger (~1000 concepts/agent)
122
+ instead of being built speculatively.
123
+
124
+ - **Knowledge consolidation + the Studio page** — a repeat concept name no
125
+ longer blindly overwrites. The engine now decides same claim (bumps
126
+ occurrences/sources/confidence — `min(0.95, 0.5 + 0.1 × distinct_sources)`,
127
+ no model call), related claim (one extra model call merges the two
128
+ bodies — `Insika::Knowledge::Consolidator`/`ConsolidatorFactory`), or
129
+ contradicting claim (never merged — appended under a `## Contradiction`
130
+ heading, confidence dropped to `0.4`, `:knowledge_conflict` emitted). No
131
+ consolidator configured, or an unusable answer, defaults to contradicting —
132
+ the conservative choice. `/studio/knowledge` (single-agent-scoped like
133
+ Harvest) lists every concept with a conflict filter, the same CodeMirror
134
+ editor Skills uses (also how an operator hand-promotes `provenance:
135
+ observed` to `policy`), version history/restore, and delete — all through
136
+ three new bus commands (`write_concept`/`delete_concept`/`restore_concept`,
137
+ wired through every composition root).
138
+
139
+ - **Knowledge, layer 1 (extraction)** — the engine can now learn durable
140
+ **concepts** (facts, procedures, policies, objections) from finished
141
+ conversations, opt-in per agent via `knowledge extract: true`. After a turn
142
+ completes, off the critical path, the platform `utility_model` proposes
143
+ candidate concepts; the engine schema-validates the answer, drops any
144
+ model-authored `provenance`/`confidence`/`sources` (stamped by the engine
145
+ instead — every extracted concept is `provenance: observed`, never
146
+ `policy`), redacts the body for PII, and persists it as a markdown+
147
+ frontmatter record in the new `KnowledgeStore` (`Insika::KnowledgeStore`,
148
+ scoped per agent/tenant like `MemoryStore`, versioned like `SkillStore`).
149
+ Emits `:knowledge_learned` (name/type/agent only, never content). The
150
+ recovery path is `insika knowledge:backfill --agent ID [--since DATE]`,
151
+ replaying stored sessions through the same extractor. No retrieval into a
152
+ turn's prompt yet — see `docs/KNOWLEDGE.md` for what's shipped and what's
153
+ still planned.
154
+
155
+ - **Plugin loading is on in every root** — `Server::Boot`'s `load_plugins`
156
+ step was a no-op in both composition roots, so the tested
157
+ `Insika::Plugin::Loader` never ran outside the `insika-code`
158
+ example. It now runs at boot in the minimal wiring, the demo deployment
159
+ and DSL-run agents, via a shared `Wiring::Graph.load_plugins`. Discovery
160
+ roots: announced gems (default-enabled), `INSIKA_PLUGIN_DIR` (workspace)
161
+ and the repo's `plugins/` — the latter two gated by `INSIKA_PLUGINS`,
162
+ with `INSIKA_PLUGINS_DISABLED` as the absolute veto. Plugin skills and
163
+ prompts join the catalogs at the lowest precedence (a workspace or
164
+ authored skill still wins). The dead `OPENCLAW_PLUGIN_DIR` env spec
165
+ (nothing ever read it) is replaced by the three new keys.
166
+
167
+ - **Media parity** — three transport gaps closed, all additive:
168
+ `generate_image` can now EDIT as well as generate — `source_image_urls`
169
+ (or, absent those, the turn's own inbound photo by default) ride
170
+ `RubyLLM.paint(with:)`, an optional `mask_url` rides `paint(mask:)`; a
171
+ fourth inbound part type, `document` (`{ "type": "document", "url": … }`,
172
+ capped at 10 MB), attaches to the ask like an image and deposits
173
+ `{{ctx.document_url}}` for data tools; and audio transcription now carries
174
+ a vocabulary `prompt:` (per-agent `stt_prompt`, falling back to the
175
+ deployment-wide `INSIKA_STT_PROMPT`) so domain terms (product names, brand
176
+ terms) transcribe correctly instead of phonetically. Text-to-image and
177
+ plain audio transcription stay byte-identical when neither feature is used.
178
+ - **Demo data** — `insika demo:seed` (and a matching "Seed demo data" button
179
+ under Studio Settings) provisions a bundled `demo-store` agent and writes
180
+ enough realistic data to see every loop working at once: a funnel with a
181
+ frozen baseline, follow-ups in all four states, refinement runs across the
182
+ lifecycle, pending and resolved approvals, distillation proposals and a
183
+ memory fact, and a golden set with a mixed-result baseline. One code path
184
+ (`Insika::Demo::Seeder`) behind both front doors, same discipline as every
185
+ other Studio button. Fixed two pre-existing gaps this surfaced: `config.ru`
186
+ never wired `proposal_store`/`budget_ledger` into the Studio (the Facts page
187
+ and the funnel's spend pill were unreachable in production), and
188
+ `scripts/serve_real.rb` never wired the outcome/funnel/follow-up/proposal
189
+ stores at all.
190
+
11
191
  ## [0.3.0] - 2026-08-19
12
192
 
13
193
  The proof-and-consultant wave: shadow parity against a frozen criterion, the
data/README.md CHANGED
@@ -80,42 +80,77 @@ served — no secrets) and **`GET /docs`** + **`GET /docs/<name>.md`** (these do
80
80
  markdown). Public and on by default when you `serve`; opt-in in production
81
81
  (`INSIKA_ONBOARDING=1`).
82
82
 
83
+ Three more paste-prompts cover the steps after that, served and structured the same way
84
+ (one file each under `docs/prompts/`):
85
+
86
+ ```
87
+ Read http://localhost:9292/docs/add-tool.md then add a currency tool to my agent
88
+ Read http://localhost:9292/docs/diagnose-turn.md — this turn failed, investigate
89
+ Read http://localhost:9292/docs/run-examples.md then run every example for me
90
+ Read http://localhost:9292/docs/go-live.md then take this agent to production
91
+ ```
92
+
83
93
  ## Docs by goal
84
94
 
85
- **Understand the idea**
95
+ The groups below are the same six the [site](https://guizaols.github.io/insika/)
96
+ navigates by.
97
+
98
+ **Start here**
86
99
 
87
100
  - [Why Insika](docs/WHY.md) — a runtime vs a DIY loop, an assembled framework, or a hosted gateway.
101
+ - [Running locally](docs/RUNNING-LOCAL.md) — the local demo, the control UI, wiring tools to your own backend.
88
102
  - [Architecture](docs/ARCHITECTURE.md) — the turn pipeline, the tool-loop, checkpoint recovery, composition roots, diagrams.
103
+ - [Demo data](docs/DEMO.md) — `insika demo:seed` populates one agent with a funnel, follow-ups, refinement runs, approvals, facts and evals at once, so a fresh instance shows every loop working before you build your own.
89
104
 
90
- **Build an agent**
105
+ **Core concepts**
91
106
 
92
- - [Agents](docs/AGENTS.md) — the AgentProfile and its five access layers; create and edit at runtime.
107
+ - [Agents](docs/AGENTS.md) — the AgentProfile and every key on it; create and edit at runtime.
108
+ - [Limits and policy](docs/POLICY.md) — the five layers: allowed tools, approvals, guardrails, edge limits, reasoning.
93
109
  - [Tools](docs/TOOLS.md) — code vs data vs MCP tools, manifests, egress troubleshooting.
94
110
  - [Skills](docs/SKILLS.md) — the SKILL.md format and progressive loading.
95
111
  - [Context](docs/CONTEXT.md) — what fills a turn's prompt; budget, eviction, memory.
96
112
  - [Workflows](docs/WORKFLOWS.md) — deterministic orchestration of several agents: the five patterns, and when to let the model choose instead.
113
+ - [examples/](examples/) — one small runnable project per capability.
114
+
115
+ **Integrate**
116
+
117
+ - [The /v1 API](docs/API.md) — the frozen compatibility contract: the surface, the additive-only rule, the version gate.
97
118
  - [Channels](docs/CHANNELS.md) — how people reach the agent: a widget on your site in one `<script>` tag, or keep your own WhatsApp/Slack stack (relay).
119
+ - [Media](docs/MEDIA.md) — photos, voice notes and documents through the message contract; generated images back out.
120
+ - [Embedding](docs/EMBEDDING.md) — mount Insika into the Ruby app you already have: `Insika.embed(backend:)` and a Rack app for your router.
98
121
  - [Plugins](docs/PLUGINS.md) — the two extension tiers: config-only, or a gem the engine loads.
99
- - [Running locally](docs/RUNNING-LOCAL.md) — the local demo, the control UI, wiring tools to your own backend.
100
- - [examples/](examples/) — one small runnable project per capability.
122
+ - [Templates](docs/TEMPLATES.md) — example agents shipped in the gem: `insika new <name>` or a Studio click gets you a running, editable app in one command.
101
123
 
102
124
  **Ship it**
103
125
 
104
126
  - [Security](docs/SECURITY.md) — guardrails, egress, approvals, edge limits, secrets.
105
127
  - [Sandbox](docs/SANDBOX.md) — the confined-execution primitive.
106
- - [Deploy](docs/DEPLOY.md) — Falcon, a durable SQLite volume, tokens.
107
- - [Embedding](docs/EMBEDDING.md) — mount Insika into the Ruby app you already have: `Insika.embed(backend:)` and a Rack app for your router.
128
+ - [Deploy](docs/DEPLOY.md) — Falcon, a durable SQLite volume, tokens, the process model.
129
+ - [Router](docs/ROUTER.md) — the session-sticky proxy that keeps per-session guarantees past one worker.
130
+ - [Releasing](docs/RELEASING.md) — how the gem is cut, and the install proof that runs before it is published.
108
131
 
109
- **Operate & prove it**
132
+ **Operate**
110
133
 
111
- - [Observability](docs/OBSERVABILITY.md) — OpenTelemetry (opt-in): turns as traces and metrics, the attribute convention, dashboard recipes.
112
- - [Benchmark](docs/BENCHMARK.md) — the neutral, reproducible, provider-free engine benchmark.
134
+ - [Observability](docs/OBSERVABILITY.md) — the event stream, plus opt-in OpenTelemetry: turns as traces and metrics, the attribute convention, dashboard recipes.
135
+ - [Schedules](docs/SCHEDULING.md) — recurring turns the engine fires on its own tick, with no cron on another box.
136
+ - [Artifacts](docs/ARTIFACTS.md) — a report the agent can hand you a URL to.
113
137
  - [Load test](docs/LOADTEST.md) — load-testing and data topology.
138
+ - [Soak](docs/SOAK.md) — the long run that finds what a short one cannot.
139
+ - [Benchmark](docs/BENCHMARK.md) — the neutral, reproducible, provider-free engine benchmark.
140
+
141
+ **Improve**
142
+
114
143
  - [Evals](docs/EVALS.md) — the cases that grade an agent: rubrics, the judge panel, and the pre-merge gate.
115
144
  - [Refinement](docs/REFINEMENT.md) — read an agent's own traffic back as a ranked report of what broke.
145
+ - [Outcomes and follow-ups](docs/OUTCOMES.md) — what the traffic was worth in business terms, and the tool that comes back on a promise.
146
+ - [Knowledge](docs/KNOWLEDGE.md) — extract durable concepts from finished conversations into a per-agent knowledge base; provenance-stamped, PII-redacted, best-effort with a re-scan recovery path (retrieval and consolidation are not shipped yet).
116
147
  - [Facts](docs/FACTS.md) — distill finished customer conversations into proposed facts; a human approves them into memory (nothing is ever applied automatically).
117
148
  - [Harvest](docs/HARVEST.md) — mine real traffic for SKILL proposals; the negative list, the evidence-ledger grounding filter and the double gate hold every proposal to a human approval and the append-only log (nothing is ever applied automatically).
118
149
 
150
+ **Reference**
151
+
152
+ - [The domain-free core](docs/domain.md) — what the gem ships, what a deployment declares, and how to clear it.
153
+
119
154
  All of the above is also browsable, searchable and cross-linked at
120
155
  **[guizaols.github.io/insika](https://guizaols.github.io/insika/)** — the same files,
121
156
  rendered. Reading this repo as an agent? [llms.txt](llms.txt) indexes the docs;