insika 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +145 -17
- data/README.md +7 -1
- data/bin/insika +211 -8
- data/docs/AGENTS.md +377 -2
- data/docs/API.md +56 -0
- data/docs/CHANNELS.md +99 -9
- data/docs/CONTEXT.md +127 -16
- data/docs/DEPLOY.md +5 -2
- data/docs/EVALS.md +19 -0
- data/docs/FACTS.md +135 -0
- data/docs/HARVEST.md +117 -0
- data/docs/LOADTEST.md +14 -8
- data/docs/OBSERVABILITY.md +54 -0
- data/docs/REFINEMENT.md +3 -3
- data/docs/RELEASING.md +27 -0
- data/docs/RUNNING-LOCAL.md +3 -3
- data/docs/SECURITY.md +61 -0
- data/docs/SKILLS.md +2 -2
- data/docs/SOAK.md +127 -0
- data/docs/TOOLS.md +70 -2
- data/docs/domain.md +115 -0
- data/docs/index.md +1 -1
- data/lib/insika/agent_profile.rb +145 -10
- data/lib/insika/balloon_splitter.rb +102 -0
- data/lib/insika/budget_ledger.rb +34 -3
- data/lib/insika/cache_series_store.rb +49 -0
- data/lib/insika/channel_delivery.rb +118 -13
- data/lib/insika/channels/relay.rb +77 -3
- data/lib/insika/channels/web.rb +2 -2
- data/lib/insika/chat_builder.rb +84 -1
- data/lib/insika/checkpoint_store.rb +16 -0
- data/lib/insika/commands/agent_payload.rb +3 -3
- data/lib/insika/commands/cancel_followup.rb +49 -0
- data/lib/insika/commands/delete_tenant_data.rb +95 -0
- data/lib/insika/commands/export_customer_memory.rb +48 -0
- data/lib/insika/commands/forget_customer.rb +117 -0
- data/lib/insika/commands/freeze_funnel_baseline.rb +113 -0
- data/lib/insika/commands/gate_harvest.rb +138 -0
- data/lib/insika/commands/gate_refinement.rb +1 -1
- data/lib/insika/commands/judge_shadow_pairs.rb +124 -0
- data/lib/insika/commands/memory_forget_fact.rb +20 -4
- data/lib/insika/commands/memory_put_fact.rb +23 -4
- data/lib/insika/commands/promote_harvest.rb +130 -0
- data/lib/insika/commands/record_outcome.rb +46 -0
- data/lib/insika/commands/record_shadow_reply.rb +68 -0
- data/lib/insika/commands/reject_harvest.rb +38 -0
- data/lib/insika/commands/resolve_proposal.rb +108 -0
- data/lib/insika/commands/revoke_contact.rb +49 -0
- data/lib/insika/commands/rollback_harvest.rb +86 -0
- data/lib/insika/commands/run_distillation.rb +186 -0
- data/lib/insika/commands/run_harvest.rb +393 -0
- data/lib/insika/commands/send_message.rb +103 -6
- data/lib/insika/commands/session_purge.rb +67 -0
- data/lib/insika/contact_store.rb +183 -0
- data/lib/insika/context/builder.rb +21 -3
- data/lib/insika/context/fragment.rb +7 -3
- data/lib/insika/context/priority.rb +3 -0
- data/lib/insika/context/provider.rb +17 -3
- data/lib/insika/context/providers/briefing.rb +96 -0
- data/lib/insika/context/providers/memory.rb +16 -7
- data/lib/insika/context/providers/prompt.rb +30 -2
- data/lib/insika/context/providers/skill.rb +2 -0
- data/lib/insika/context/providers/tool_search.rb +2 -0
- data/lib/insika/context_trace_store.rb +38 -2
- data/lib/insika/distill.rb +224 -0
- data/lib/insika/distill_engine.rb +169 -0
- data/lib/insika/doctor.rb +716 -6
- data/lib/insika/dsl/runtime.rb +9 -3
- data/lib/insika/dsl/server_boot.rb +70 -1
- data/lib/insika/dsl.rb +83 -3
- data/lib/insika/edge_limiter.rb +28 -7
- data/lib/insika/env_schema.rb +9 -2
- data/lib/insika/errors.rb +11 -0
- data/lib/insika/evals/assertions.rb +3 -2
- data/lib/insika/evals/pairwise.rb +18 -6
- data/lib/insika/evidence.rb +183 -0
- data/lib/insika/executor.rb +687 -70
- data/lib/insika/followup_engine.rb +207 -0
- data/lib/insika/followup_policy.rb +221 -0
- data/lib/insika/followup_store.rb +306 -0
- data/lib/insika/funnel_declaration.rb +106 -0
- data/lib/insika/funnel_fold.rb +179 -0
- data/lib/insika/funnel_store.rb +163 -0
- data/lib/insika/golden_store.rb +1 -1
- data/lib/insika/grounding/matcher.rb +69 -0
- data/lib/insika/grounding.rb +44 -0
- data/lib/insika/harvest/conversion_gate.rb +159 -0
- data/lib/insika/harvest/criterion.rb +98 -0
- data/lib/insika/harvest/gate.rb +194 -0
- data/lib/insika/harvest/negative_list.rb +199 -0
- data/lib/insika/harvest.rb +241 -0
- data/lib/insika/harvest_engine.rb +193 -0
- data/lib/insika/harvest_store.rb +548 -0
- data/lib/insika/media.rb +298 -0
- data/lib/insika/memory_audit_store.rb +85 -0
- data/lib/insika/memory_store.rb +264 -23
- data/lib/insika/message_origin.rb +6 -1
- data/lib/insika/model_visible.rb +87 -0
- data/lib/insika/model_visible_trace_store.rb +66 -0
- data/lib/insika/onboarding.rb +6 -1
- data/lib/insika/outbox_store.rb +42 -4
- data/lib/insika/outcome_store.rb +147 -0
- data/lib/insika/packaging.rb +163 -0
- data/lib/insika/parity/criterion.rb +79 -0
- data/lib/insika/parity/verdict.rb +318 -0
- data/lib/insika/prefix_fingerprint.rb +58 -0
- data/lib/insika/profile_source.rb +22 -1
- data/lib/insika/proposal_store.rb +271 -0
- data/lib/insika/queue_policy.rb +4 -1
- data/lib/insika/refinement/proposer.rb +1 -1
- data/lib/insika/reliability.rb +32 -6
- data/lib/insika/retention.rb +281 -0
- data/lib/insika/routing.rb +101 -0
- data/lib/insika/safety/config.rb +44 -4
- data/lib/insika/safety/corpus.rb +255 -0
- data/lib/insika/safety/detectors.rb +32 -113
- data/lib/insika/safety/factory.rb +15 -2
- data/lib/insika/safety/grounding_enforcer.rb +59 -0
- data/lib/insika/safety/grounding_validator.rb +49 -0
- data/lib/insika/safety/input_guardrail.rb +1 -1
- data/lib/insika/safety/moderator.rb +1 -1
- data/lib/insika/safety/output_filter.rb +9 -5
- data/lib/insika/safety/output_validator.rb +11 -5
- data/lib/insika/schema_guard.rb +35 -0
- data/lib/insika/server/app.rb +144 -4
- data/lib/insika/server/rack_app.rb +16 -0
- data/lib/insika/server/responses.rb +40 -1
- data/lib/insika/session_actor.rb +8 -4
- data/lib/insika/session_store.rb +65 -2
- data/lib/insika/settings_store.rb +10 -0
- data/lib/insika/shadow_pair_store.rb +258 -0
- data/lib/insika/skill_catalog.rb +4 -0
- data/lib/insika/soak/envelope.rb +140 -0
- data/lib/insika/soak/report.rb +392 -0
- data/lib/insika/soak/runner.rb +554 -0
- data/lib/insika/store.rb +10 -1
- data/lib/insika/stores/memory.rb +6 -0
- data/lib/insika/stores/sqlite.rb +8 -0
- data/lib/insika/studio/app.rb +875 -14
- data/lib/insika/studio/assets/dist/application.css +1 -1
- data/lib/insika/studio/assets/dist/application.js +22 -22
- data/lib/insika/studio/assets/dist/favicon.svg +6 -0
- data/lib/insika/studio/forms.rb +262 -5
- data/lib/insika/studio/nav_icons.rb +6 -1
- data/lib/insika/studio/views/agent_detail.erb +627 -84
- data/lib/insika/studio/views/agents.erb +10 -6
- data/lib/insika/studio/views/approvals.erb +4 -1
- data/lib/insika/studio/views/chats.erb +4 -1
- data/lib/insika/studio/views/customer.erb +94 -0
- data/lib/insika/studio/views/customers.erb +32 -0
- data/lib/insika/studio/views/evals.erb +4 -1
- data/lib/insika/studio/views/facts.erb +133 -0
- data/lib/insika/studio/views/followups.erb +125 -0
- data/lib/insika/studio/views/funnel.erb +106 -0
- data/lib/insika/studio/views/harvest.erb +234 -0
- data/lib/insika/studio/views/home.erb +2 -1
- data/lib/insika/studio/views/layout.erb +1 -0
- data/lib/insika/studio/views/parity.erb +147 -0
- data/lib/insika/studio/views/playground.erb +7 -1
- data/lib/insika/studio/views/session.erb +56 -1
- data/lib/insika/studio/views/settings.erb +2 -0
- data/lib/insika/studio/views/skills.erb +0 -1
- data/lib/insika/studio/views/system_files.erb +1 -1
- data/lib/insika/studio/views/task.erb +13 -0
- data/lib/insika/studio/views/tasks.erb +4 -1
- data/lib/insika/studio/views/tools.erb +0 -1
- data/lib/insika/task_store.rb +21 -1
- data/lib/insika/testing/store_contract.rb +27 -6
- data/lib/insika/tick.rb +25 -1
- data/lib/insika/tool_definition.rb +17 -7
- data/lib/insika/tool_envelope.rb +69 -0
- data/lib/insika/tool_manifest.rb +5 -1
- data/lib/insika/tools/data_defined_tool.rb +10 -0
- data/lib/insika/tools/generate_image.rb +44 -0
- data/lib/insika/tools/schedule_followup.rb +164 -0
- data/lib/insika/tools/tts.rb +47 -0
- data/lib/insika/tools/update_briefing.rb +126 -0
- data/lib/insika/turn_state.rb +38 -1
- data/lib/insika/turn_timing.rb +22 -2
- data/lib/insika/version.rb +1 -1
- data/lib/insika/vitals.rb +84 -0
- data/lib/insika/wiring/graph.rb +300 -13
- data/lib/insika.rb +92 -3
- metadata +77 -1
data/lib/insika/wiring/graph.rb
CHANGED
|
@@ -45,6 +45,10 @@ module Insika
|
|
|
45
45
|
pending_action_store = Insika::PendingActionStore.new(store: backend)
|
|
46
46
|
delegation_store = Insika::DelegationStore.new(store: backend)
|
|
47
47
|
memory_store = Insika::MemoryStore.new(store: backend)
|
|
48
|
+
# the append-only, content-free audit of OPERATOR memory
|
|
49
|
+
# mutations. Built unconditionally (empty and free when nothing writes)
|
|
50
|
+
# so a deployment that turns it on later finds its audit already durable.
|
|
51
|
+
memory_audit_store = Insika::MemoryAuditStore.new(store: backend)
|
|
48
52
|
token_store = Insika::TokenStore.new(store: backend)
|
|
49
53
|
budget_ledger = Insika::BudgetLedger.new(store: backend)
|
|
50
54
|
circuit_state = Insika::CircuitState.new(store: backend)
|
|
@@ -54,11 +58,41 @@ module Insika
|
|
|
54
58
|
# (they are empty and free when no channel is registered) so a deployment
|
|
55
59
|
# that turns a channel on later finds its state already durable.
|
|
56
60
|
outbox_store = Insika::OutboxStore.new(store: backend)
|
|
61
|
+
# the shadow pair store — one durable record per mirrored
|
|
62
|
+
# exchange, written by our half and the incumbent's. Built unconditionally
|
|
63
|
+
# (empty and free when shadow is off) so turning it on later finds the
|
|
64
|
+
# state already durable, beside the outbox on the same runtime backend.
|
|
65
|
+
shadow_pair_store = Insika::ShadowPairStore.new(store: backend)
|
|
57
66
|
inbound_log = Insika::InboundLog.new(store: backend)
|
|
67
|
+
# WS7: business outcomes per conversation, recorded by the operator or
|
|
68
|
+
# the integration (POST /v1/outcomes). Built unconditionally (empty and
|
|
69
|
+
# free when nothing records) so the Studio's scorecard always has a store.
|
|
70
|
+
outcome_store = Insika::OutcomeStore.new(store: backend)
|
|
71
|
+
# the funnel's durable aggregates — per-day stage counts,
|
|
72
|
+
# fold cursors and baseline snapshots. Built unconditionally (empty and
|
|
73
|
+
# free when no pack declares a funnel) so the fold, the doctor and the
|
|
74
|
+
# Studio always have a store to read/write.
|
|
75
|
+
funnel_store = Insika::FunnelStore.new(store: backend)
|
|
76
|
+
# the contact-state cells and the follow-up schedule
|
|
77
|
+
# records. Built unconditionally (empty and free when no pack declares
|
|
78
|
+
# followup) so the engine, the tools and the Studio always have stores.
|
|
79
|
+
contact_store = Insika::ContactStore.new(store: backend)
|
|
80
|
+
followup_store = Insika::FollowupStore.new(store: backend)
|
|
81
|
+
# the distilled proposals + the latched dedup ledger +
|
|
82
|
+
# the per-session markers. Built unconditionally (empty and free when
|
|
83
|
+
# no pack declares distill) so the wiki, the engine and the LGPD
|
|
84
|
+
# purges always have a store.
|
|
85
|
+
proposal_store = Insika::ProposalStore.new(store: backend)
|
|
58
86
|
# refinement RUNS (reports over real traffic). Runtime data,
|
|
59
87
|
# same backend as sessions/tasks — the collector and the command that write it
|
|
60
88
|
# are the root's business (deployment-only, like the memory commands).
|
|
61
89
|
refinement_store = Insika::RefinementStore.new(store: backend)
|
|
90
|
+
# the harvest's durable half — mining runs, the per-
|
|
91
|
+
# candidate lifecycle, the append-only promotion log, the snapshots
|
|
92
|
+
# and the per-session markers. Built unconditionally (empty and free
|
|
93
|
+
# when no pack declares harvest) so the engine, the Studio and the
|
|
94
|
+
# LGPD purges always have a store.
|
|
95
|
+
harvest_store = Insika::HarvestStore.new(store: backend)
|
|
62
96
|
|
|
63
97
|
code_tool_registry = Insika::ToolRegistry.new
|
|
64
98
|
workflow_registry = Insika::WorkflowRegistry.new
|
|
@@ -74,9 +108,17 @@ module Insika
|
|
|
74
108
|
session_store: session_store, task_store: task_store,
|
|
75
109
|
checkpoint_store: checkpoint_store, pending_action_store: pending_action_store,
|
|
76
110
|
delegation_store: delegation_store,
|
|
77
|
-
memory_store: memory_store,
|
|
111
|
+
memory_store: memory_store, memory_audit_store: memory_audit_store,
|
|
112
|
+
refinement_store: refinement_store,
|
|
113
|
+
harvest_store: harvest_store,
|
|
78
114
|
token_store: token_store, budget_ledger: budget_ledger, circuit_state: circuit_state,
|
|
79
|
-
outbox_store: outbox_store,
|
|
115
|
+
outbox_store: outbox_store, shadow_pair_store: shadow_pair_store,
|
|
116
|
+
inbound_log: inbound_log,
|
|
117
|
+
outcome_store: outcome_store,
|
|
118
|
+
funnel_store: funnel_store,
|
|
119
|
+
contact_store: contact_store,
|
|
120
|
+
followup_store: followup_store,
|
|
121
|
+
proposal_store: proposal_store,
|
|
80
122
|
code_tool_registry: code_tool_registry,
|
|
81
123
|
workflow_registry: workflow_registry, policy_registry: policy_registry,
|
|
82
124
|
capability_registry: Insika::CapabilityRegistry.new, hooks: Insika::Hooks.new,
|
|
@@ -115,7 +157,8 @@ module Insika
|
|
|
115
157
|
# only production exercises.
|
|
116
158
|
channel_delivery = Insika::ChannelDelivery.new(
|
|
117
159
|
channels: spine.channel_registry, outbox: spine.outbox_store,
|
|
118
|
-
session_store: spine.session_store, event_stream: spine.event_stream
|
|
160
|
+
session_store: spine.session_store, event_stream: spine.event_stream,
|
|
161
|
+
shadow_pairs: spine.shadow_pair_store
|
|
119
162
|
)
|
|
120
163
|
|
|
121
164
|
# WS3 provider reliability (retries/backoff/fallback/breaker) is ALWAYS wired —
|
|
@@ -135,23 +178,118 @@ module Insika
|
|
|
135
178
|
delegation_store: spine.delegation_store, # async delegation durability
|
|
136
179
|
channel_delivery: channel_delivery, # out-of-band reply delivery
|
|
137
180
|
reliability: reliability, # WS3: retries/fallback/breaker (data-gated)
|
|
181
|
+
grounding_enforcer: guardrails.grounding_enforcer, # :enforce cut
|
|
182
|
+
# the follow-up stores — the ChatBuilder wires the
|
|
183
|
+
# schedule/cancel_followup tools on them (parity when no pack declares).
|
|
184
|
+
contact_store: spine.contact_store,
|
|
185
|
+
followup_store: spine.followup_store,
|
|
186
|
+
# the model-visible trace rides executor_extra like the
|
|
187
|
+
# context trace — a module graph that omits it still builds (nil =
|
|
188
|
+
# parity). The base graph wires it over the same backend the context
|
|
189
|
+
# trace uses.
|
|
190
|
+
model_visible_trace_store: Insika::ModelVisibleTraceStore.new(store: spine.backend),
|
|
138
191
|
**executor_extra
|
|
139
192
|
)
|
|
140
193
|
|
|
141
|
-
|
|
194
|
+
# the ONE path that writes proposals, shared by the
|
|
195
|
+
# automatic DistillEngine loop and the bus command behind the Studio's
|
|
196
|
+
# "Run distillation now" button (one code path for both).
|
|
197
|
+
run_distillation = Insika::Commands::RunDistillation.new(
|
|
198
|
+
profiles: profiles, proposal_store: spine.proposal_store,
|
|
199
|
+
session_store: spine.session_store, memory_store: spine.memory_store,
|
|
200
|
+
settings_store: executor_extra[:settings_store],
|
|
201
|
+
event_stream: spine.event_stream
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
bus = build_core_bus(spine: spine, profiles: profiles, executor: executor,
|
|
205
|
+
executor_extra: executor_extra, skill_catalog: skill_catalog,
|
|
206
|
+
run_distillation: run_distillation)
|
|
142
207
|
|
|
143
208
|
# the periodic tick (outbox drain + stale recovery sweep). Built
|
|
144
209
|
# here, after the bus, because its recovery half dispatches resume_task
|
|
145
210
|
# through it; handed to the Executor, which starts it as a child of the
|
|
146
211
|
# turn supervisor in serving mode. `INSIKA_TICK_INTERVAL=0` disables.
|
|
212
|
+
# WS8 retention rides the tick: always built, the settings knob
|
|
213
|
+
# (`retention_days`) gates it — the base graph (no settings_store)
|
|
214
|
+
# reads as OFF.
|
|
147
215
|
executor.tick = Insika::Tick.new(
|
|
148
216
|
store: spine.backend, channel_delivery: channel_delivery,
|
|
149
217
|
recovery: Insika::Recovery.new(
|
|
150
218
|
task_store: spine.task_store, checkpoint_store: spine.checkpoint_store, command_bus: bus
|
|
151
219
|
),
|
|
220
|
+
retention: Insika::Retention.new(
|
|
221
|
+
store: spine.backend, session_store: spine.session_store,
|
|
222
|
+
task_store: spine.task_store, checkpoint_store: spine.checkpoint_store,
|
|
223
|
+
memory_store: spine.memory_store, outcome_store: spine.outcome_store,
|
|
224
|
+
tool_trace_store: executor_extra[:tool_trace_store],
|
|
225
|
+
context_trace_store: executor_extra[:context_trace_store],
|
|
226
|
+
# the model-visible traces die with their checkpoints.
|
|
227
|
+
model_visible_trace_store: Insika::ModelVisibleTraceStore.new(store: spine.backend),
|
|
228
|
+
outbox_store: spine.outbox_store,
|
|
229
|
+
shadow_pair_store: spine.shadow_pair_store,
|
|
230
|
+
settings_store: executor_extra[:settings_store],
|
|
231
|
+
budget_ledger: spine.budget_ledger, # WS2 counter GC (retention-independent)
|
|
232
|
+
funnel_store: spine.funnel_store, # fold dies with its source
|
|
233
|
+
followup_store: spine.followup_store, # records age out too
|
|
234
|
+
contact_store: spine.contact_store, # cells age out too
|
|
235
|
+
proposal_store: spine.proposal_store, # proposals age out too
|
|
236
|
+
harvest_store: spine.harvest_store # candidates/log/snapshots too
|
|
237
|
+
),
|
|
152
238
|
interval: tick_env("INSIKA_TICK_INTERVAL") || Insika::Tick::DEFAULT_INTERVAL,
|
|
153
239
|
stale_after: tick_env("INSIKA_TICK_STALE_AFTER") || Insika::Tick::DEFAULT_STALE_AFTER
|
|
154
240
|
)
|
|
241
|
+
# the tick-driven outcome fold — wired here, after the
|
|
242
|
+
# Tick, because it reads the outcome/funnel stores of the spine and the
|
|
243
|
+
# profiles; the per-pair declaration gates it (nil funnel everywhere =
|
|
244
|
+
# an inert fold). Always built: a pack that declares a funnel later
|
|
245
|
+
# finds its fold already on the tick.
|
|
246
|
+
executor.tick.funnel = Insika::FunnelFold.new(
|
|
247
|
+
outcome_store: spine.outcome_store, funnel_store: spine.funnel_store,
|
|
248
|
+
profiles: profiles, store: spine.backend
|
|
249
|
+
)
|
|
250
|
+
# the tick-driven follow-up firer — the tick's third
|
|
251
|
+
# duty, wired here after the Tick, gated by its own claim window.
|
|
252
|
+
# Always built: a pack that declares followup later finds its firer
|
|
253
|
+
# already on the tick (inert when no profile declares followup).
|
|
254
|
+
executor.tick.followup = Insika::FollowupEngine.new(
|
|
255
|
+
store: spine.backend, followup_store: spine.followup_store,
|
|
256
|
+
contact_store: spine.contact_store, task_store: spine.task_store,
|
|
257
|
+
profiles: profiles, executor: executor, event_stream: spine.event_stream
|
|
258
|
+
)
|
|
259
|
+
# the distillation engine — the tick-duty that finds idle
|
|
260
|
+
# customer sessions and distills them on its own worker fiber (a
|
|
261
|
+
# supervisor child, started in serving mode next to the tick).
|
|
262
|
+
# Always built: a pack that declares `distill:` later finds its engine
|
|
263
|
+
# already wired — and INERT until one does (the engine gates its start
|
|
264
|
+
# and its passes on a declaring profile).
|
|
265
|
+
executor.distill_engine = Insika::DistillEngine.new(
|
|
266
|
+
store: spine.backend, proposal_store: spine.proposal_store,
|
|
267
|
+
session_store: spine.session_store,
|
|
268
|
+
runner: run_distillation,
|
|
269
|
+
profiles: profiles,
|
|
270
|
+
window: Insika::DistillEngine::DEFAULT_WINDOW
|
|
271
|
+
)
|
|
272
|
+
# the harvest engine — the tick-duty that finds idle,
|
|
273
|
+
# unmined sessions whose agent declares `harvest.enabled` and mines
|
|
274
|
+
# them on its own worker fiber (a supervisor child, started in serving
|
|
275
|
+
# mode next to the tick). Always built: INERT until a profile declares
|
|
276
|
+
# harvest (the engine gates its start and its passes on data). The
|
|
277
|
+
# runner is the same RunHarvest the bus serves, so the manual CLI and
|
|
278
|
+
# the automated loop share one code path.
|
|
279
|
+
run_harvest = Insika::Commands::RunHarvest.new(
|
|
280
|
+
profiles: profiles, harvest_store: spine.harvest_store,
|
|
281
|
+
session_store: spine.session_store, task_store: spine.task_store,
|
|
282
|
+
skill_store: skill_catalog.store, # the harvest's dedup reads the authored skills
|
|
283
|
+
tool_trace_store: executor_extra[:tool_trace_store],
|
|
284
|
+
settings_store: executor_extra[:settings_store],
|
|
285
|
+
negative_list: nil, miner_factory: nil,
|
|
286
|
+
event_stream: spine.event_stream
|
|
287
|
+
)
|
|
288
|
+
executor.harvest_engine = Insika::HarvestEngine.new(
|
|
289
|
+
store: spine.backend, harvest_store: spine.harvest_store,
|
|
290
|
+
session_store: spine.session_store, runner: run_harvest,
|
|
291
|
+
profiles: profiles, window: Insika::HarvestEngine::DEFAULT_WINDOW
|
|
292
|
+
)
|
|
155
293
|
# WS6 operator alerts: answers budget_warning / breaker_open /
|
|
156
294
|
# delivery_failed per agent (`alerts.webhook`) via the outbox+claim
|
|
157
295
|
# pipeline. Always wired — the per-agent data gates it (parity).
|
|
@@ -166,8 +304,16 @@ module Insika
|
|
|
166
304
|
session_store: spine.session_store, task_store: spine.task_store,
|
|
167
305
|
checkpoint_store: spine.checkpoint_store, pending_action_store: spine.pending_action_store,
|
|
168
306
|
delegation_store: spine.delegation_store,
|
|
169
|
-
memory_store: spine.memory_store,
|
|
170
|
-
|
|
307
|
+
memory_store: spine.memory_store, memory_audit_store: spine.memory_audit_store,
|
|
308
|
+
refinement_store: spine.refinement_store,
|
|
309
|
+
harvest_store: spine.harvest_store,
|
|
310
|
+
outbox_store: spine.outbox_store, shadow_pair_store: spine.shadow_pair_store,
|
|
311
|
+
inbound_log: spine.inbound_log,
|
|
312
|
+
outcome_store: spine.outcome_store,
|
|
313
|
+
funnel_store: spine.funnel_store,
|
|
314
|
+
contact_store: spine.contact_store,
|
|
315
|
+
followup_store: spine.followup_store,
|
|
316
|
+
proposal_store: spine.proposal_store,
|
|
171
317
|
token_store: spine.token_store, budget_ledger: spine.budget_ledger,
|
|
172
318
|
circuit_state: spine.circuit_state,
|
|
173
319
|
channel_registry: spine.channel_registry, channel_delivery: channel_delivery,
|
|
@@ -184,7 +330,8 @@ module Insika
|
|
|
184
330
|
# The CORE command surface every root needs — turn essentials + the operator
|
|
185
331
|
# controls (pause/approve) the Studio dispatches. Registering pause_task/
|
|
186
332
|
# approve_action HERE is the crux of: it retires the config.ru:28-34 patch.
|
|
187
|
-
def build_core_bus(spine:, profiles:, executor:
|
|
333
|
+
def build_core_bus(spine:, profiles:, executor:, executor_extra: {}, skill_catalog: nil,
|
|
334
|
+
run_distillation: nil)
|
|
188
335
|
bus = Insika::CommandBus.new
|
|
189
336
|
bus.register(:create_session,
|
|
190
337
|
Insika::Commands::CreateSession.new(session_store: spine.session_store, event_stream: spine.event_stream))
|
|
@@ -198,7 +345,10 @@ module Insika
|
|
|
198
345
|
bus.register(:send_message,
|
|
199
346
|
Insika::Commands::SendMessage.new(profiles: profiles, session_store: spine.session_store,
|
|
200
347
|
task_store: spine.task_store, executor: executor,
|
|
201
|
-
inbound_log: spine.inbound_log
|
|
348
|
+
inbound_log: spine.inbound_log,
|
|
349
|
+
contact_store: spine.contact_store,
|
|
350
|
+
followup_store: spine.followup_store,
|
|
351
|
+
store: spine.backend))
|
|
202
352
|
bus.register(:resume_task,
|
|
203
353
|
Insika::Commands::ResumeTask.new(profiles: profiles, task_store: spine.task_store,
|
|
204
354
|
checkpoint_store: spine.checkpoint_store, executor: executor))
|
|
@@ -214,6 +364,135 @@ module Insika
|
|
|
214
364
|
bus.register(:rotate_tenant_token,
|
|
215
365
|
Insika::Commands::RotateTenantToken.new(token_store: spine.token_store,
|
|
216
366
|
event_stream: spine.event_stream))
|
|
367
|
+
# WS7: a business outcome per conversation (operator or integration).
|
|
368
|
+
bus.register(:record_outcome,
|
|
369
|
+
Insika::Commands::RecordOutcome.new(outcome_store: spine.outcome_store,
|
|
370
|
+
event_stream: spine.event_stream))
|
|
371
|
+
# the incumbent's half of a shadow pair, one command behind
|
|
372
|
+
# both mirror shapes (the mirror call itself + the follow-up route).
|
|
373
|
+
bus.register(:record_shadow_reply,
|
|
374
|
+
Insika::Commands::RecordShadowReply.new(shadow_pairs: spine.shadow_pair_store,
|
|
375
|
+
event_stream: spine.event_stream))
|
|
376
|
+
# WS8 (LGPD): purge one customer's memory + the whole footprint of their
|
|
377
|
+
# sessions (traces, tasks, checkpoints, outbox). The trace stores are
|
|
378
|
+
# deployment components (nil at the base — skipped). the
|
|
379
|
+
# audit collaborator records a content-free purge line.
|
|
380
|
+
bus.register(:forget_customer,
|
|
381
|
+
Insika::Commands::ForgetCustomer.new(
|
|
382
|
+
memory_store: spine.memory_store, session_store: spine.session_store,
|
|
383
|
+
tool_trace_store: executor_extra[:tool_trace_store],
|
|
384
|
+
context_trace_store: executor_extra[:context_trace_store],
|
|
385
|
+
# the model-visible traces die with the
|
|
386
|
+
# checkpoints (the same SessionPurge list).
|
|
387
|
+
model_visible_trace_store: Insika::ModelVisibleTraceStore.new(store: spine.backend),
|
|
388
|
+
task_store: spine.task_store, checkpoint_store: spine.checkpoint_store,
|
|
389
|
+
outbox_store: spine.outbox_store,
|
|
390
|
+
shadow_pairs: spine.shadow_pair_store,
|
|
391
|
+
audit_store: spine.memory_audit_store,
|
|
392
|
+
followup_store: spine.followup_store,
|
|
393
|
+
contact_store: spine.contact_store,
|
|
394
|
+
proposal_store: spine.proposal_store,
|
|
395
|
+
event_stream: spine.event_stream
|
|
396
|
+
))
|
|
397
|
+
# the LGPD access right — export one customer's memory
|
|
398
|
+
# cell as content (the Studio download); the event stays counts-only.
|
|
399
|
+
bus.register(:export_customer_memory,
|
|
400
|
+
Insika::Commands::ExportCustomerMemory.new(
|
|
401
|
+
memory_store: spine.memory_store, event_stream: spine.event_stream
|
|
402
|
+
))
|
|
403
|
+
# WS8 (LGPD): purge ONE TENANT's data — sessions and their footprint,
|
|
404
|
+
# memory cells and outcomes. Operator-only by construction (ingress).
|
|
405
|
+
bus.register(:delete_tenant_data,
|
|
406
|
+
Insika::Commands::DeleteTenantData.new(
|
|
407
|
+
memory_store: spine.memory_store, session_store: spine.session_store,
|
|
408
|
+
tool_trace_store: executor_extra[:tool_trace_store],
|
|
409
|
+
context_trace_store: executor_extra[:context_trace_store],
|
|
410
|
+
# the model-visible traces die with the tenant.
|
|
411
|
+
model_visible_trace_store: Insika::ModelVisibleTraceStore.new(store: spine.backend),
|
|
412
|
+
outcome_store: spine.outcome_store,
|
|
413
|
+
funnel_store: spine.funnel_store, # the fold dies with the tenant
|
|
414
|
+
followup_store: spine.followup_store,
|
|
415
|
+
contact_store: spine.contact_store,
|
|
416
|
+
proposal_store: spine.proposal_store,
|
|
417
|
+
harvest_store: spine.harvest_store,
|
|
418
|
+
task_store: spine.task_store, checkpoint_store: spine.checkpoint_store,
|
|
419
|
+
outbox_store: spine.outbox_store,
|
|
420
|
+
shadow_pairs: spine.shadow_pair_store,
|
|
421
|
+
token_store: spine.token_store, # revoked BEFORE the sweep
|
|
422
|
+
event_stream: spine.event_stream
|
|
423
|
+
))
|
|
424
|
+
# the operator's baseline freeze — the number
|
|
425
|
+
# read. Synchronous control command, dispatched from the Studio.
|
|
426
|
+
bus.register(:freeze_funnel_baseline,
|
|
427
|
+
Insika::Commands::FreezeFunnelBaseline.new(
|
|
428
|
+
funnel_store: spine.funnel_store, profiles: profiles,
|
|
429
|
+
event_stream: spine.event_stream
|
|
430
|
+
))
|
|
431
|
+
# the follow-up mutations — the Studio's Cancel button
|
|
432
|
+
# and the channel opt-out event (a tenant principal never reaches the
|
|
433
|
+
# generic command ingress; these ride the same operator-grade path).
|
|
434
|
+
bus.register(:cancel_followup,
|
|
435
|
+
Insika::Commands::CancelFollowup.new(followup_store: spine.followup_store,
|
|
436
|
+
event_stream: spine.event_stream))
|
|
437
|
+
bus.register(:revoke_contact,
|
|
438
|
+
Insika::Commands::RevokeContact.new(contact_store: spine.contact_store,
|
|
439
|
+
followup_store: spine.followup_store,
|
|
440
|
+
store: spine.backend,
|
|
441
|
+
event_stream: spine.event_stream))
|
|
442
|
+
# the human's answer on a distilled proposal — the ONLY
|
|
443
|
+
# mutation behind the Facts (wiki) page. Synchronous control command.
|
|
444
|
+
bus.register(:resolve_proposal,
|
|
445
|
+
Insika::Commands::ResolveProposal.new(
|
|
446
|
+
proposal_store: spine.proposal_store,
|
|
447
|
+
memory_store: spine.memory_store,
|
|
448
|
+
event_stream: spine.event_stream
|
|
449
|
+
))
|
|
450
|
+
# /C10: the gated harvest — the mining pass, the double
|
|
451
|
+
# gate, the human's promote/rollback/dismiss. The BASE graph wires the
|
|
452
|
+
# nil factories (no eval surface, no criterion, no funnel): every flow
|
|
453
|
+
# refuses with a named reason or skips (parity). The deployment root
|
|
454
|
+
# re-registers with the real gate/criterion/negative list.
|
|
455
|
+
bus.register(:run_harvest,
|
|
456
|
+
Insika::Commands::RunHarvest.new(
|
|
457
|
+
profiles: profiles, harvest_store: spine.harvest_store,
|
|
458
|
+
session_store: spine.session_store, task_store: spine.task_store,
|
|
459
|
+
skill_store: skill_catalog.store,
|
|
460
|
+
tool_trace_store: executor_extra[:tool_trace_store],
|
|
461
|
+
settings_store: executor_extra[:settings_store],
|
|
462
|
+
negative_list: nil, miner_factory: nil,
|
|
463
|
+
event_stream: spine.event_stream
|
|
464
|
+
))
|
|
465
|
+
bus.register(:gate_harvest,
|
|
466
|
+
Insika::Commands::GateHarvest.new(
|
|
467
|
+
harvest_store: spine.harvest_store, gate: nil,
|
|
468
|
+
conversion_gate: nil, criterion: nil,
|
|
469
|
+
event_stream: spine.event_stream
|
|
470
|
+
))
|
|
471
|
+
bus.register(:promote_harvest,
|
|
472
|
+
Insika::Commands::PromoteHarvest.new(
|
|
473
|
+
harvest_store: spine.harvest_store,
|
|
474
|
+
skill_store: skill_catalog.store,
|
|
475
|
+
skill_catalog: skill_catalog,
|
|
476
|
+
profile_source: profiles, criterion: nil, conversion_gate: nil,
|
|
477
|
+
event_stream: spine.event_stream
|
|
478
|
+
))
|
|
479
|
+
bus.register(:rollback_harvest,
|
|
480
|
+
Insika::Commands::RollbackHarvest.new(
|
|
481
|
+
harvest_store: spine.harvest_store,
|
|
482
|
+
skill_store: skill_catalog.store,
|
|
483
|
+
skill_catalog: skill_catalog,
|
|
484
|
+
profile_source: profiles, event_stream: spine.event_stream
|
|
485
|
+
))
|
|
486
|
+
bus.register(:reject_harvest,
|
|
487
|
+
Insika::Commands::RejectHarvest.new(
|
|
488
|
+
harvest_store: spine.harvest_store, event_stream: spine.event_stream
|
|
489
|
+
))
|
|
490
|
+
# the ONE path that writes proposals, served to the
|
|
491
|
+
# Studio's "Run distillation now" button. The same instance the
|
|
492
|
+
# DistillEngine's loop uses, so the manual and the automatic share one
|
|
493
|
+
# code path; the engine keeps the automatic pass when the root does
|
|
494
|
+
# not pass a runner here (nil = the command is not on the bus).
|
|
495
|
+
bus.register(:run_distillation, run_distillation) if run_distillation
|
|
217
496
|
bus
|
|
218
497
|
end
|
|
219
498
|
|
|
@@ -221,9 +500,13 @@ module Insika
|
|
|
221
500
|
# them to their historic public constants (SESSION_STORE, REGISTRY, ...).
|
|
222
501
|
Spine = Struct.new(
|
|
223
502
|
:backend, :event_stream, :session_store, :task_store, :checkpoint_store,
|
|
224
|
-
:pending_action_store, :delegation_store, :memory_store, :
|
|
225
|
-
:
|
|
226
|
-
:
|
|
503
|
+
:pending_action_store, :delegation_store, :memory_store, :memory_audit_store,
|
|
504
|
+
:refinement_store,
|
|
505
|
+
:harvest_store,
|
|
506
|
+
:token_store, :budget_ledger, :circuit_state, :outbox_store, :shadow_pair_store,
|
|
507
|
+
:inbound_log, :outcome_store, :funnel_store,
|
|
508
|
+
:contact_store, :followup_store, :proposal_store,
|
|
509
|
+
:code_tool_registry, :workflow_registry, :policy_registry, :capability_registry, :hooks,
|
|
227
510
|
:channel_registry, keyword_init: true
|
|
228
511
|
)
|
|
229
512
|
|
|
@@ -233,8 +516,12 @@ module Insika
|
|
|
233
516
|
Result = Struct.new(
|
|
234
517
|
:backend, :event_stream,
|
|
235
518
|
:session_store, :task_store, :checkpoint_store, :pending_action_store, :delegation_store,
|
|
236
|
-
:memory_store, :
|
|
237
|
-
:
|
|
519
|
+
:memory_store, :memory_audit_store, :refinement_store, :outbox_store, :shadow_pair_store,
|
|
520
|
+
:inbound_log, :token_store,
|
|
521
|
+
:budget_ledger, :circuit_state, :outcome_store, :funnel_store,
|
|
522
|
+
:contact_store, :followup_store, :proposal_store,
|
|
523
|
+
:harvest_store,
|
|
524
|
+
:channel_registry, :channel_delivery,
|
|
238
525
|
:code_tool_registry, :tool_registry, :workflow_registry, :policy_registry, :capability_registry,
|
|
239
526
|
:tool_catalog, :skill_catalog, :prompt_catalog,
|
|
240
527
|
:hooks, :guardrails, :middleware,
|
data/lib/insika.rb
CHANGED
|
@@ -2,12 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "insika/version"
|
|
4
4
|
require_relative "insika/errors"
|
|
5
|
+
# the payload selection + the domain-boundary audit yardstick.
|
|
6
|
+
# Pure module — loaded by the gemspec too, so it carries no app requires.
|
|
7
|
+
require_relative "insika/packaging"
|
|
5
8
|
require_relative "insika/provider_error_classifier"
|
|
6
9
|
require_relative "insika/token_store"
|
|
7
10
|
require_relative "insika/budget_ledger"
|
|
8
11
|
require_relative "insika/circuit_state"
|
|
9
12
|
require_relative "insika/reliability"
|
|
13
|
+
require_relative "insika/routing"
|
|
14
|
+
require_relative "insika/media"
|
|
10
15
|
require_relative "insika/alert_dispatcher"
|
|
16
|
+
require_relative "insika/outcome_store"
|
|
17
|
+
require_relative "insika/retention"
|
|
18
|
+
require_relative "insika/funnel_declaration"
|
|
19
|
+
require_relative "insika/funnel_store"
|
|
20
|
+
require_relative "insika/funnel_fold"
|
|
21
|
+
# the parsed follow-up policy of ONE agent — the ONLY shape the
|
|
22
|
+
# engine accepts (tool/engine/doctor/Studio share it). Pure value object.
|
|
23
|
+
require_relative "insika/followup_policy"
|
|
24
|
+
# the contact-state cells and the follow-up schedule records.
|
|
25
|
+
# Both are dumb domain stores over the injected backend.
|
|
26
|
+
require_relative "insika/contact_store"
|
|
27
|
+
require_relative "insika/followup_store"
|
|
28
|
+
# the tick-driven firer — rides the same tick as retention/funnel.
|
|
29
|
+
require_relative "insika/followup_engine"
|
|
30
|
+
require_relative "insika/commands/freeze_funnel_baseline"
|
|
11
31
|
require_relative "insika/channels/webhook"
|
|
12
32
|
require_relative "insika/coercion"
|
|
13
33
|
require_relative "insika/message_origin"
|
|
@@ -21,6 +41,9 @@ require_relative "insika/model_selection"
|
|
|
21
41
|
require_relative "insika/model_resolver"
|
|
22
42
|
require_relative "insika/tool_definition"
|
|
23
43
|
require_relative "insika/tool_manifest"
|
|
44
|
+
# the pack's grounding policy (Insika::Grounding + the
|
|
45
|
+
# GroundingMatcher it wraps). Pure Ruby — profile data, parsed per turn.
|
|
46
|
+
require_relative "insika/grounding"
|
|
24
47
|
require_relative "insika/frontmatter"
|
|
25
48
|
require_relative "insika/token_estimator"
|
|
26
49
|
require_relative "insika/checkpoint"
|
|
@@ -33,9 +56,12 @@ require_relative "insika/usage_ledger"
|
|
|
33
56
|
require_relative "insika/budget_ledger"
|
|
34
57
|
require_relative "insika/edge_limiter"
|
|
35
58
|
require_relative "insika/tool_output_compressor"
|
|
36
|
-
# Content safety / guardrails.
|
|
37
|
-
#
|
|
38
|
-
#
|
|
59
|
+
# Content safety / guardrails. The pattern SOURCE is the
|
|
60
|
+
# language-tagged data in safety/corpus.rb; detectors.rb compiles it. Both are
|
|
61
|
+
# self-contained (the eval requires detectors.rb directly); the rest hang off
|
|
62
|
+
# Middleware/hooks seams. No ruby_llm at load-time — Factory requires the gem
|
|
63
|
+
# lazily, like the Executor's create_chat.
|
|
64
|
+
require_relative "insika/safety/corpus"
|
|
39
65
|
require_relative "insika/safety/detectors"
|
|
40
66
|
require_relative "insika/safety/safe_responses"
|
|
41
67
|
require_relative "insika/safety/config"
|
|
@@ -56,6 +82,11 @@ require_relative "insika/context/providers/skill_trigger"
|
|
|
56
82
|
require_relative "insika/context/providers/tool_search"
|
|
57
83
|
require_relative "insika/context/providers/memory"
|
|
58
84
|
require_relative "insika/context/providers/session"
|
|
85
|
+
require_relative "insika/context/providers/briefing"
|
|
86
|
+
# the cache-prefix hash chain + the per-agent cache-hit series.
|
|
87
|
+
# Both are referenced by the Executor at runtime, so they load before it.
|
|
88
|
+
require_relative "insika/prefix_fingerprint"
|
|
89
|
+
require_relative "insika/cache_series_store"
|
|
59
90
|
require_relative "insika/policy/policy"
|
|
60
91
|
require_relative "insika/policy/engine"
|
|
61
92
|
require_relative "insika/registry"
|
|
@@ -78,8 +109,12 @@ require_relative "insika/delegation_store"
|
|
|
78
109
|
# Channels: the outbound record + the inbound retry window. Both are
|
|
79
110
|
# plain stores; the channel objects themselves come after the HTTP client.
|
|
80
111
|
require_relative "insika/outbox_store"
|
|
112
|
+
require_relative "insika/shadow_pair_store"
|
|
81
113
|
require_relative "insika/inbound_log"
|
|
82
114
|
require_relative "insika/memory_store"
|
|
115
|
+
# the operator-mutation audit trail. After memory_store (no
|
|
116
|
+
# mutual deps). Pure stdlib — `load_guard_spec` stays green.
|
|
117
|
+
require_relative "insika/memory_audit_store"
|
|
83
118
|
require_relative "insika/config_store"
|
|
84
119
|
require_relative "insika/profile_source"
|
|
85
120
|
require_relative "insika/agent_file_store"
|
|
@@ -88,6 +123,10 @@ require_relative "insika/secret_masking"
|
|
|
88
123
|
require_relative "insika/tool_store"
|
|
89
124
|
require_relative "insika/tool_trace_store"
|
|
90
125
|
require_relative "insika/context_trace_store"
|
|
126
|
+
# the model-visible payload of one ask + its durable trace —
|
|
127
|
+
# "model-visible means logged" (the conformance suite's reconstruction half).
|
|
128
|
+
require_relative "insika/model_visible"
|
|
129
|
+
require_relative "insika/model_visible_trace_store"
|
|
91
130
|
# Refinement: the run record + the evidence half of the loop.
|
|
92
131
|
# Reads sessions/tasks/traces above; requires Safety::Detectors (loaded earlier) for
|
|
93
132
|
# the PII redaction of the snippets it puts in a report.
|
|
@@ -101,6 +140,9 @@ require_relative "insika/refinement/candidate"
|
|
|
101
140
|
require_relative "insika/refinement/proposer"
|
|
102
141
|
require_relative "insika/egress_guard"
|
|
103
142
|
require_relative "insika/schema_guard"
|
|
143
|
+
# the evidence contract (Spec + Processor + EvidenceLedger). Pure Ruby.
|
|
144
|
+
# Required BEFORE tool_envelope.rb — the envelope references it at runtime.
|
|
145
|
+
require_relative "insika/evidence"
|
|
104
146
|
require_relative "insika/sandbox"
|
|
105
147
|
require_relative "insika/http_client"
|
|
106
148
|
# Channels: the registry, the bundled relay adapter and the
|
|
@@ -130,6 +172,10 @@ require_relative "insika/evals/runner"
|
|
|
130
172
|
require_relative "insika/evals/report"
|
|
131
173
|
require_relative "insika/evals/baseline"
|
|
132
174
|
require_relative "insika/evals/transport"
|
|
175
|
+
# shadow parity: the frozen criterion and the mechanical
|
|
176
|
+
# fold over the pair store (C6). Pure — no store, no provider gem.
|
|
177
|
+
require_relative "insika/parity/criterion"
|
|
178
|
+
require_relative "insika/parity/verdict"
|
|
133
179
|
# Authored eval cases: the corpus becomes editable without a
|
|
134
180
|
# checkout. Requires the loader above (it is the one validator).
|
|
135
181
|
require_relative "insika/golden_store"
|
|
@@ -177,6 +223,42 @@ require_relative "insika/commands/delete_llm_provider"
|
|
|
177
223
|
require_relative "insika/commands/issue_tenant_token"
|
|
178
224
|
require_relative "insika/commands/revoke_token"
|
|
179
225
|
require_relative "insika/commands/rotate_tenant_token"
|
|
226
|
+
require_relative "insika/commands/record_outcome"
|
|
227
|
+
require_relative "insika/commands/record_shadow_reply"
|
|
228
|
+
require_relative "insika/commands/judge_shadow_pairs"
|
|
229
|
+
require_relative "insika/commands/session_purge"
|
|
230
|
+
require_relative "insika/commands/forget_customer"
|
|
231
|
+
require_relative "insika/commands/delete_tenant_data"
|
|
232
|
+
# the LGPD access right — export one customer's memory cell as
|
|
233
|
+
# content (the Studio download); the event stays counts-only.
|
|
234
|
+
require_relative "insika/commands/export_customer_memory"
|
|
235
|
+
# the operator/integration follow-up mutations (cancel one
|
|
236
|
+
# record; revoke a contact + fall its pending records atomically).
|
|
237
|
+
require_relative "insika/commands/cancel_followup"
|
|
238
|
+
require_relative "insika/commands/revoke_contact"
|
|
239
|
+
# session distillation — the distiller (pure, injected ask)
|
|
240
|
+
# and the proposal store (proposals + the latched dedup ledger + the
|
|
241
|
+
# per-session distilled marker).
|
|
242
|
+
require_relative "insika/distill"
|
|
243
|
+
require_relative "insika/proposal_store"
|
|
244
|
+
require_relative "insika/commands/run_distillation"
|
|
245
|
+
require_relative "insika/distill_engine"
|
|
246
|
+
require_relative "insika/commands/resolve_proposal"
|
|
247
|
+
# the gated harvest — the miner (pure, injected ask), the
|
|
248
|
+
# frozen conversion criterion and the versioned negative list. The provider
|
|
249
|
+
# touch stays inside MinerFactory's lazy ask (load_guard stays green).
|
|
250
|
+
require_relative "insika/harvest"
|
|
251
|
+
require_relative "insika/harvest/criterion"
|
|
252
|
+
require_relative "insika/harvest/negative_list"
|
|
253
|
+
require_relative "insika/harvest/conversion_gate"
|
|
254
|
+
require_relative "insika/harvest/gate"
|
|
255
|
+
require_relative "insika/harvest_store"
|
|
256
|
+
require_relative "insika/commands/run_harvest"
|
|
257
|
+
require_relative "insika/commands/gate_harvest"
|
|
258
|
+
require_relative "insika/commands/promote_harvest"
|
|
259
|
+
require_relative "insika/commands/rollback_harvest"
|
|
260
|
+
require_relative "insika/commands/reject_harvest"
|
|
261
|
+
require_relative "insika/harvest_engine"
|
|
180
262
|
require_relative "insika/commands/upsert_mcp"
|
|
181
263
|
require_relative "insika/commands/delete_mcp"
|
|
182
264
|
require_relative "insika/commands/write_system_file"
|
|
@@ -195,6 +277,7 @@ require_relative "insika/skill_catalog"
|
|
|
195
277
|
require_relative "insika/tool_catalog"
|
|
196
278
|
require_relative "insika/steer_injector"
|
|
197
279
|
require_relative "insika/loop_detector"
|
|
280
|
+
require_relative "insika/balloon_splitter"
|
|
198
281
|
require_relative "insika/turn_output"
|
|
199
282
|
require_relative "insika/turn_state"
|
|
200
283
|
require_relative "insika/turn_timing"
|
|
@@ -211,6 +294,12 @@ require_relative "insika/telemetry"
|
|
|
211
294
|
# Strict config + diagnosis. Doctor reads the config stores above;
|
|
212
295
|
# EnvSchema (required at the top) is its env layer.
|
|
213
296
|
require_relative "insika/doctor"
|
|
297
|
+
# Soak: the 72h uptime-degradation harness. Pure stdlib — the
|
|
298
|
+
# envelope and the report fold are deterministic, the runner only talks Net::HTTP.
|
|
299
|
+
require_relative "insika/soak/envelope"
|
|
300
|
+
require_relative "insika/soak/report"
|
|
301
|
+
require_relative "insika/soak/runner"
|
|
302
|
+
require_relative "insika/vitals"
|
|
214
303
|
# Shared composition core for both roots (config/wiring.rb + config/deployment.rb).
|
|
215
304
|
# Only references the classes above at call-time, so require order is unconstrained.
|
|
216
305
|
require_relative "insika/wiring/graph"
|