iris-harness 0.1.0__py3-none-any.whl

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 (964) hide show
  1. iris_harness/__init__.py +5 -0
  2. iris_harness/_data/config/behaviors/reminders.default.md +42 -0
  3. iris_harness/_data/config/channels.yaml +29 -0
  4. iris_harness/_data/config/cron/audit-compact.cron +8 -0
  5. iris_harness/_data/config/digest.yaml +238 -0
  6. iris_harness/_data/config/docs_search.yaml +40 -0
  7. iris_harness/_data/config/doctor.yaml +45 -0
  8. iris_harness/_data/config/escalation.yaml +74 -0
  9. iris_harness/_data/config/governance/egress.yaml +26 -0
  10. iris_harness/_data/config/governance/identity.yaml +49 -0
  11. iris_harness/_data/config/governance/mcp-serve.yaml +18 -0
  12. iris_harness/_data/config/governance/mcp-signing.yaml +11 -0
  13. iris_harness/_data/config/governance/mcp-trust.yaml +12 -0
  14. iris_harness/_data/config/governance/sandbox.yaml +13 -0
  15. iris_harness/_data/config/governance/taint-policy.yaml +18 -0
  16. iris_harness/_data/config/governance/threat-detection.yaml +60 -0
  17. iris_harness/_data/config/governance/tool-access.yaml +16 -0
  18. iris_harness/_data/config/governor/policy.yaml +112 -0
  19. iris_harness/_data/config/health_watch.yaml +72 -0
  20. iris_harness/_data/config/heartbeats.yaml +327 -0
  21. iris_harness/_data/config/identity/active.default.md +9 -0
  22. iris_harness/_data/config/identity/episodic.default.md +37 -0
  23. iris_harness/_data/config/identity/soul.default.md +43 -0
  24. iris_harness/_data/config/identity/soul_layers.yaml +26 -0
  25. iris_harness/_data/config/intent_anchors.yaml +145 -0
  26. iris_harness/_data/config/intent_keywords.yaml +310 -0
  27. iris_harness/_data/config/intercepts.yaml +188 -0
  28. iris_harness/_data/config/knowledge/wiki_schema.yaml +35 -0
  29. iris_harness/_data/config/learning/strategies.yaml +50 -0
  30. iris_harness/_data/config/llm_tiers.yaml +232 -0
  31. iris_harness/_data/config/memory/entity_aliases.yaml +74 -0
  32. iris_harness/_data/config/memory/extraction.yaml +114 -0
  33. iris_harness/_data/config/memory/learning.yaml +71 -0
  34. iris_harness/_data/config/memory/mappings.yaml +149 -0
  35. iris_harness/_data/config/memory/ontology.yaml +95 -0
  36. iris_harness/_data/config/memory/recall.yaml +34 -0
  37. iris_harness/_data/config/memory/retention.yaml +98 -0
  38. iris_harness/_data/config/memory/shapes.yaml +49 -0
  39. iris_harness/_data/config/memory/summary.yaml +54 -0
  40. iris_harness/_data/config/multi_step.yaml +28 -0
  41. iris_harness/_data/config/notifications.yaml +62 -0
  42. iris_harness/_data/config/outcomes.yaml +21 -0
  43. iris_harness/_data/config/playground/README.md +57 -0
  44. iris_harness/_data/config/playground/core-deterministic.yaml +50 -0
  45. iris_harness/_data/config/playground/injection-pressure.yaml +48 -0
  46. iris_harness/_data/config/playground/intercepts-live.yaml.example +49 -0
  47. iris_harness/_data/config/playground/memory-continuity.yaml +94 -0
  48. iris_harness/_data/config/playground/memory-graph.yaml +103 -0
  49. iris_harness/_data/config/playground/routing-breadth.yaml +108 -0
  50. iris_harness/_data/config/profiles/default.yaml +25 -0
  51. iris_harness/_data/config/profiles/email.yaml +28 -0
  52. iris_harness/_data/config/profiles/minimal.yaml +7 -0
  53. iris_harness/_data/config/search_providers.yaml +22 -0
  54. iris_harness/_data/config/skills/builtin/daily-repo-brief/manifest.yaml +36 -0
  55. iris_harness/_data/config/skills/builtin/iris-core/manifest.yaml +24 -0
  56. iris_harness/_data/config/skills/builtin/iris-core/tools.py +87 -0
  57. iris_harness/_data/config/skills/builtin/iris-tasks/manifest.yaml +101 -0
  58. iris_harness/_data/config/skills/builtin/iris-tasks/tools.py +294 -0
  59. iris_harness/_data/config/skills/builtin/morning-briefing/manifest.yaml +400 -0
  60. iris_harness/_data/config/skills/builtin/sample-brief/manifest.yaml +49 -0
  61. iris_harness/_data/config/skills/builtin/web-fetch/manifest.yaml +61 -0
  62. iris_harness/_data/config/skills/builtin/web-fetch/tools.py +580 -0
  63. iris_harness/_data/config/skills/email/email-followup/agent.md +46 -0
  64. iris_harness/_data/config/skills/email/email-followup/manifest.yaml +62 -0
  65. iris_harness/_data/config/skills/email/email-followup/tools.py +143 -0
  66. iris_harness/_data/config/skills/email/email-triage/agent.md +58 -0
  67. iris_harness/_data/config/skills/email/email-triage/manifest.yaml +130 -0
  68. iris_harness/_data/config/skills/email/email-triage/tools.py +349 -0
  69. iris_harness/_data/config/skills/email/gmail-inbox/agent.md +41 -0
  70. iris_harness/_data/config/skills/email/gmail-inbox/manifest.yaml +54 -0
  71. iris_harness/_data/config/skills/email/gmail-inbox/tools.py +49 -0
  72. iris_harness/_data/config/skills/rag/docs-search/agent.md +16 -0
  73. iris_harness/_data/config/skills/rag/docs-search/manifest.yaml +37 -0
  74. iris_harness/_data/config/skills/rag/docs-search/tools.py +44 -0
  75. iris_harness/_data/config/skills/system/system-status/agent.md +15 -0
  76. iris_harness/_data/config/skills/system/system-status/manifest.yaml +27 -0
  77. iris_harness/_data/config/skills/system/system-status/tools.py +44 -0
  78. iris_harness/_data/config/webui/nav.yaml +227 -0
  79. iris_harness/_data/config/welcome.yaml +22 -0
  80. iris_harness/_data/config/write_claims.yaml +87 -0
  81. iris_harness/agent/__init__.py +24 -0
  82. iris_harness/agent/agent_executor.py +272 -0
  83. iris_harness/agent/agent_metadata.py +96 -0
  84. iris_harness/agent/agentic_core.py +3017 -0
  85. iris_harness/agent/answer_guard.py +211 -0
  86. iris_harness/agent/context_budget.py +136 -0
  87. iris_harness/agent/context_health.py +87 -0
  88. iris_harness/agent/dateparse.py +163 -0
  89. iris_harness/agent/escalation.py +350 -0
  90. iris_harness/agent/heartbeat.py +68 -0
  91. iris_harness/agent/intent_router.py +897 -0
  92. iris_harness/agent/outcomes.py +184 -0
  93. iris_harness/agent/provenance.py +76 -0
  94. iris_harness/agent/response_curator.py +1384 -0
  95. iris_harness/agent/run_review.py +68 -0
  96. iris_harness/agent/task_planner.py +217 -0
  97. iris_harness/agent/task_spec.py +283 -0
  98. iris_harness/agent/tool_runner.py +1301 -0
  99. iris_harness/cli/__init__.py +8 -0
  100. iris_harness/cli/api_client.py +87 -0
  101. iris_harness/cli/approvals.py +310 -0
  102. iris_harness/cli/behaviors.py +120 -0
  103. iris_harness/cli/commands.py +2385 -0
  104. iris_harness/cli/context_health.py +84 -0
  105. iris_harness/cli/device.py +176 -0
  106. iris_harness/cli/docs.py +239 -0
  107. iris_harness/cli/doctor.py +173 -0
  108. iris_harness/cli/facts.py +688 -0
  109. iris_harness/cli/governance.py +457 -0
  110. iris_harness/cli/health.py +140 -0
  111. iris_harness/cli/intentions.py +140 -0
  112. iris_harness/cli/interactive.py +84 -0
  113. iris_harness/cli/learning.py +207 -0
  114. iris_harness/cli/logs.py +66 -0
  115. iris_harness/cli/mcp.py +183 -0
  116. iris_harness/cli/memory.py +649 -0
  117. iris_harness/cli/mission.py +95 -0
  118. iris_harness/cli/modes.py +187 -0
  119. iris_harness/cli/ontology.py +136 -0
  120. iris_harness/cli/playground.py +167 -0
  121. iris_harness/cli/plugin_scaffold.py +249 -0
  122. iris_harness/cli/plugins.py +240 -0
  123. iris_harness/cli/push.py +119 -0
  124. iris_harness/cli/queue.py +192 -0
  125. iris_harness/cli/render.py +336 -0
  126. iris_harness/cli/repl.py +477 -0
  127. iris_harness/cli/run_inspect.py +271 -0
  128. iris_harness/cli/serve.py +95 -0
  129. iris_harness/cli/session.py +115 -0
  130. iris_harness/cli/setup.py +398 -0
  131. iris_harness/cli/signals.py +78 -0
  132. iris_harness/cli/templates/plugin/_common/pyproject.toml.tmpl +46 -0
  133. iris_harness/cli/templates/plugin/_common/src/__tmpl_package/__init__.py +1 -0
  134. iris_harness/cli/templates/plugin/_common/tests/test_stable_tier.py +19 -0
  135. iris_harness/cli/templates/plugin/channel/README.md +34 -0
  136. iris_harness/cli/templates/plugin/channel/src/__tmpl_package/manifest.yaml +10 -0
  137. iris_harness/cli/templates/plugin/channel/src/__tmpl_package/plugin.py +70 -0
  138. iris_harness/cli/templates/plugin/channel/tests/test_plugin.py +65 -0
  139. iris_harness/cli/templates/plugin/kinds.yaml +24 -0
  140. iris_harness/cli/templates/plugin/mail-provider/README.md +40 -0
  141. iris_harness/cli/templates/plugin/mail-provider/src/__tmpl_package/manifest.yaml +16 -0
  142. iris_harness/cli/templates/plugin/mail-provider/src/__tmpl_package/plugin.py +169 -0
  143. iris_harness/cli/templates/plugin/mail-provider/tests/test_plugin.py +96 -0
  144. iris_harness/cli/templates/plugin/research-provider/README.md +39 -0
  145. iris_harness/cli/templates/plugin/research-provider/src/__tmpl_package/manifest.yaml +17 -0
  146. iris_harness/cli/templates/plugin/research-provider/src/__tmpl_package/plugin.py +67 -0
  147. iris_harness/cli/templates/plugin/research-provider/tests/model_script.yaml +13 -0
  148. iris_harness/cli/templates/plugin/research-provider/tests/test_plugin.py +51 -0
  149. iris_harness/cli/templates/plugin/skill/README.md +40 -0
  150. iris_harness/cli/templates/plugin/skill/src/__tmpl_package/functions.py +30 -0
  151. iris_harness/cli/templates/plugin/skill/src/__tmpl_package/manifest.yaml +45 -0
  152. iris_harness/cli/templates/plugin/skill/tests/model_script.yaml +23 -0
  153. iris_harness/cli/templates/plugin/skill/tests/test_plugin.py +65 -0
  154. iris_harness/cli/templates/plugin/tool/README.md +35 -0
  155. iris_harness/cli/templates/plugin/tool/src/__tmpl_package/manifest.yaml +20 -0
  156. iris_harness/cli/templates/plugin/tool/src/__tmpl_package/plugin.py +48 -0
  157. iris_harness/cli/templates/plugin/tool/tests/model_script.yaml +13 -0
  158. iris_harness/cli/templates/plugin/tool/tests/test_plugin.py +49 -0
  159. iris_harness/cli/web_commands.py +297 -0
  160. iris_harness/cli/welcome.py +35 -0
  161. iris_harness/foundation/__init__.py +11 -0
  162. iris_harness/foundation/activity.py +62 -0
  163. iris_harness/foundation/auth.py +210 -0
  164. iris_harness/foundation/capabilities.py +351 -0
  165. iris_harness/foundation/capability_fields.py +463 -0
  166. iris_harness/foundation/clock.py +101 -0
  167. iris_harness/foundation/console.py +21 -0
  168. iris_harness/foundation/data/__init__.py +10 -0
  169. iris_harness/foundation/data/dues_vocabulary.py +46 -0
  170. iris_harness/foundation/env.py +74 -0
  171. iris_harness/foundation/eventbus/__init__.py +13 -0
  172. iris_harness/foundation/eventbus/bus.py +138 -0
  173. iris_harness/foundation/eventbus/topics.py +19 -0
  174. iris_harness/foundation/ids.py +82 -0
  175. iris_harness/foundation/logsafe.py +24 -0
  176. iris_harness/foundation/observability/__init__.py +14 -0
  177. iris_harness/foundation/observability/audit_view.py +88 -0
  178. iris_harness/foundation/observability/host_pressure.py +67 -0
  179. iris_harness/foundation/observability/instruments.py +114 -0
  180. iris_harness/foundation/observability/logging_setup.py +137 -0
  181. iris_harness/foundation/observability/metrics_summary.py +123 -0
  182. iris_harness/foundation/observability/otlp_setup.py +264 -0
  183. iris_harness/foundation/observability/session_log.py +675 -0
  184. iris_harness/foundation/observability/trace_builder.py +1248 -0
  185. iris_harness/foundation/observability/tracer.py +122 -0
  186. iris_harness/foundation/paths.py +254 -0
  187. iris_harness/foundation/persistence/__init__.py +30 -0
  188. iris_harness/foundation/persistence/embedding.py +76 -0
  189. iris_harness/foundation/persistence/sqlite.py +248 -0
  190. iris_harness/foundation/plugin_dirs.py +107 -0
  191. iris_harness/foundation/process_state.py +144 -0
  192. iris_harness/foundation/public_url.py +40 -0
  193. iris_harness/foundation/settings/__init__.py +7 -0
  194. iris_harness/foundation/settings/catalog.py +190 -0
  195. iris_harness/foundation/settings/catalog.yaml +1636 -0
  196. iris_harness/foundation/settings/env_overrides.py +144 -0
  197. iris_harness/foundation/settings/restart.py +93 -0
  198. iris_harness/foundation/settings/store.py +241 -0
  199. iris_harness/kernel/AGENTS.md +22 -0
  200. iris_harness/kernel/__init__.py +11 -0
  201. iris_harness/kernel/governance/__init__.py +49 -0
  202. iris_harness/kernel/governance/approvals/__init__.py +31 -0
  203. iris_harness/kernel/governance/approvals/channels/__init__.py +22 -0
  204. iris_harness/kernel/governance/approvals/channels/base.py +78 -0
  205. iris_harness/kernel/governance/approvals/channels/cli_channel.py +86 -0
  206. iris_harness/kernel/governance/approvals/channels/web_channel.py +58 -0
  207. iris_harness/kernel/governance/approvals/events.py +74 -0
  208. iris_harness/kernel/governance/approvals/gate.py +98 -0
  209. iris_harness/kernel/governance/approvals/queue.py +212 -0
  210. iris_harness/kernel/governance/approvals/router.py +203 -0
  211. iris_harness/kernel/governance/approvals/schema.sql +24 -0
  212. iris_harness/kernel/governance/approvals/service.py +445 -0
  213. iris_harness/kernel/governance/approvals/store.py +528 -0
  214. iris_harness/kernel/governance/audit/__init__.py +11 -0
  215. iris_harness/kernel/governance/audit/archive/__init__.py +26 -0
  216. iris_harness/kernel/governance/audit/archive/compact.py +243 -0
  217. iris_harness/kernel/governance/audit/archive/markers.py +327 -0
  218. iris_harness/kernel/governance/audit/archive/query.py +226 -0
  219. iris_harness/kernel/governance/audit/archive/writer.py +298 -0
  220. iris_harness/kernel/governance/audit/digest.py +194 -0
  221. iris_harness/kernel/governance/audit/log.py +906 -0
  222. iris_harness/kernel/governance/audit/proof_bundle.py +757 -0
  223. iris_harness/kernel/governance/audit/proof_bundle.schema.json +136 -0
  224. iris_harness/kernel/governance/audit/replay.py +1046 -0
  225. iris_harness/kernel/governance/audit/sequence.py +293 -0
  226. iris_harness/kernel/governance/audit/spool.py +220 -0
  227. iris_harness/kernel/governance/audit/view.py +110 -0
  228. iris_harness/kernel/governance/audit/write_health.py +30 -0
  229. iris_harness/kernel/governance/call_context.py +150 -0
  230. iris_harness/kernel/governance/caller_policy.py +61 -0
  231. iris_harness/kernel/governance/cost/__init__.py +53 -0
  232. iris_harness/kernel/governance/cost/pricing.py +152 -0
  233. iris_harness/kernel/governance/cost/store.py +237 -0
  234. iris_harness/kernel/governance/cost/summary.py +188 -0
  235. iris_harness/kernel/governance/devices/__init__.py +39 -0
  236. iris_harness/kernel/governance/devices/schema.sql +19 -0
  237. iris_harness/kernel/governance/devices/service.py +302 -0
  238. iris_harness/kernel/governance/devices/store.py +235 -0
  239. iris_harness/kernel/governance/devices/throttle.py +91 -0
  240. iris_harness/kernel/governance/disclosure.py +92 -0
  241. iris_harness/kernel/governance/display_mask.py +106 -0
  242. iris_harness/kernel/governance/egress_policy.py +109 -0
  243. iris_harness/kernel/governance/evaluator/__init__.py +47 -0
  244. iris_harness/kernel/governance/evaluator/client.py +183 -0
  245. iris_harness/kernel/governance/evaluator/drift_exemptions.py +240 -0
  246. iris_harness/kernel/governance/evaluator/embeddings.py +126 -0
  247. iris_harness/kernel/governance/evaluator/flagged_runs.py +114 -0
  248. iris_harness/kernel/governance/evaluator/hook.py +248 -0
  249. iris_harness/kernel/governance/evaluator/judge.py +310 -0
  250. iris_harness/kernel/governance/evaluator/judge_template.py +117 -0
  251. iris_harness/kernel/governance/evaluator/registry.py +104 -0
  252. iris_harness/kernel/governance/evaluator/signals/__init__.py +48 -0
  253. iris_harness/kernel/governance/evaluator/signals/action_repeat.py +69 -0
  254. iris_harness/kernel/governance/evaluator/signals/classification_violation.py +57 -0
  255. iris_harness/kernel/governance/evaluator/signals/cost_budget.py +101 -0
  256. iris_harness/kernel/governance/evaluator/signals/goal_drift.py +358 -0
  257. iris_harness/kernel/governance/evaluator/signals/loop_detect.py +194 -0
  258. iris_harness/kernel/governance/evaluator/signals/step_cap.py +58 -0
  259. iris_harness/kernel/governance/evaluator/signals/tool_failure_streak.py +69 -0
  260. iris_harness/kernel/governance/evaluator/types.py +87 -0
  261. iris_harness/kernel/governance/external_content.py +590 -0
  262. iris_harness/kernel/governance/external_content_allow.py +350 -0
  263. iris_harness/kernel/governance/file_scan.py +57 -0
  264. iris_harness/kernel/governance/hooks/__init__.py +28 -0
  265. iris_harness/kernel/governance/hooks/response_payload.py +88 -0
  266. iris_harness/kernel/governance/hooks/tool_payload.py +247 -0
  267. iris_harness/kernel/governance/hooks/types.py +105 -0
  268. iris_harness/kernel/governance/identity_config.py +243 -0
  269. iris_harness/kernel/governance/identity_redaction.py +413 -0
  270. iris_harness/kernel/governance/kernel.py +429 -0
  271. iris_harness/kernel/governance/mcp_clients.py +45 -0
  272. iris_harness/kernel/governance/mcp_signing/__init__.py +47 -0
  273. iris_harness/kernel/governance/mcp_signing/config.py +44 -0
  274. iris_harness/kernel/governance/mcp_signing/keys.py +48 -0
  275. iris_harness/kernel/governance/mcp_signing/spec.py +60 -0
  276. iris_harness/kernel/governance/mcp_signing/trust.py +69 -0
  277. iris_harness/kernel/governance/mcp_signing/verifier.py +76 -0
  278. iris_harness/kernel/governance/owner_identity.py +244 -0
  279. iris_harness/kernel/governance/owner_matchers.py +320 -0
  280. iris_harness/kernel/governance/owner_pii.py +214 -0
  281. iris_harness/kernel/governance/plugin_egress.py +437 -0
  282. iris_harness/kernel/governance/plugins/__init__.py +60 -0
  283. iris_harness/kernel/governance/plugins/caller_policy.py +58 -0
  284. iris_harness/kernel/governance/plugins/capability_redaction.py +145 -0
  285. iris_harness/kernel/governance/plugins/classifier.py +120 -0
  286. iris_harness/kernel/governance/plugins/command_sandbox.py +285 -0
  287. iris_harness/kernel/governance/plugins/cost_limiter.py +240 -0
  288. iris_harness/kernel/governance/plugins/credential_broker.py +187 -0
  289. iris_harness/kernel/governance/plugins/destructive_approval.py +302 -0
  290. iris_harness/kernel/governance/plugins/egress_gate.py +175 -0
  291. iris_harness/kernel/governance/plugins/external_content_floor.py +255 -0
  292. iris_harness/kernel/governance/plugins/fs_jail.py +428 -0
  293. iris_harness/kernel/governance/plugins/input_safety.py +114 -0
  294. iris_harness/kernel/governance/plugins/mcp_allowlist.py +264 -0
  295. iris_harness/kernel/governance/plugins/mcp_client_egress.py +70 -0
  296. iris_harness/kernel/governance/plugins/network_egress.py +314 -0
  297. iris_harness/kernel/governance/plugins/output_classifier.py +119 -0
  298. iris_harness/kernel/governance/plugins/owner_pii_shadow.py +518 -0
  299. iris_harness/kernel/governance/plugins/persona_surface.py +226 -0
  300. iris_harness/kernel/governance/plugins/plugin_egress.py +106 -0
  301. iris_harness/kernel/governance/plugins/post_tool_use_ledger.py +333 -0
  302. iris_harness/kernel/governance/plugins/pre_tool_use_ledger.py +159 -0
  303. iris_harness/kernel/governance/plugins/prompt_guard.py +317 -0
  304. iris_harness/kernel/governance/plugins/redaction.py +115 -0
  305. iris_harness/kernel/governance/plugins/regex_packs.py +178 -0
  306. iris_harness/kernel/governance/plugins/response_safety.py +167 -0
  307. iris_harness/kernel/governance/plugins/tool_policy.py +117 -0
  308. iris_harness/kernel/governance/public_suffix.py +64 -0
  309. iris_harness/kernel/governance/public_suffix_icann.dat +6958 -0
  310. iris_harness/kernel/governance/reentry.py +455 -0
  311. iris_harness/kernel/governance/side_effects/__init__.py +31 -0
  312. iris_harness/kernel/governance/side_effects/probes.py +213 -0
  313. iris_harness/kernel/governance/side_effects/schema.sql +39 -0
  314. iris_harness/kernel/governance/side_effects/store.py +430 -0
  315. iris_harness/kernel/governance/taint_policy.py +93 -0
  316. iris_harness/kernel/governance/threat/__init__.py +66 -0
  317. iris_harness/kernel/governance/threat/availability.py +105 -0
  318. iris_harness/kernel/governance/threat/backends.py +272 -0
  319. iris_harness/kernel/governance/threat/battery.py +157 -0
  320. iris_harness/kernel/governance/threat/config.py +208 -0
  321. iris_harness/kernel/governance/threat/detector.py +166 -0
  322. iris_harness/kernel/governance/threat/types.py +107 -0
  323. iris_harness/kernel/governance/turn_label.py +113 -0
  324. iris_harness/kernel/governance/unmask_grants.py +47 -0
  325. iris_harness/kernel/governance/vault/__init__.py +31 -0
  326. iris_harness/kernel/governance/vault/credentials.py +138 -0
  327. iris_harness/kernel/governance/vault/handle.py +118 -0
  328. iris_harness/kernel/governance/vault/keys.py +189 -0
  329. iris_harness/kernel/governance/vault/secret_store.py +214 -0
  330. iris_harness/kernel/governance/vault/store.py +250 -0
  331. iris_harness/kernel/governance/wiring.py +1226 -0
  332. iris_harness/kernel/governor/__init__.py +43 -0
  333. iris_harness/kernel/governor/audit.py +199 -0
  334. iris_harness/kernel/governor/exceptions.py +19 -0
  335. iris_harness/kernel/governor/models.py +99 -0
  336. iris_harness/kernel/governor/policy.py +130 -0
  337. iris_harness/kernel/governor/rate_limiter.py +56 -0
  338. iris_harness/kernel/governor/service.py +117 -0
  339. iris_harness/llm/__init__.py +5 -0
  340. iris_harness/llm/arbiter.py +349 -0
  341. iris_harness/llm/budget.py +72 -0
  342. iris_harness/llm/client.py +1276 -0
  343. iris_harness/llm/copilot_auth.py +356 -0
  344. iris_harness/llm/egress.py +43 -0
  345. iris_harness/llm/embeddings.py +157 -0
  346. iris_harness/llm/errors.py +59 -0
  347. iris_harness/llm/fake.py +476 -0
  348. iris_harness/llm/locality.py +124 -0
  349. iris_harness/llm/model_metadata.py +163 -0
  350. iris_harness/llm/narrate.py +63 -0
  351. iris_harness/llm/providers.py +451 -0
  352. iris_harness/llm/tier_edits.py +204 -0
  353. iris_harness/llm/tier_router.py +591 -0
  354. iris_harness/main.py +2818 -0
  355. iris_harness/memory/__init__.py +32 -0
  356. iris_harness/memory/coherence.py +130 -0
  357. iris_harness/memory/compactor.py +473 -0
  358. iris_harness/memory/coordinator.py +237 -0
  359. iris_harness/memory/export.py +269 -0
  360. iris_harness/memory/fact_extractor.py +267 -0
  361. iris_harness/memory/fact_keys.py +245 -0
  362. iris_harness/memory/fact_statements.py +810 -0
  363. iris_harness/memory/fact_validation.py +311 -0
  364. iris_harness/memory/gate_audit.py +325 -0
  365. iris_harness/memory/gate_audit_corpus.py +96 -0
  366. iris_harness/memory/graph.py +677 -0
  367. iris_harness/memory/graph_context.py +371 -0
  368. iris_harness/memory/identity/__init__.py +88 -0
  369. iris_harness/memory/identity/loader.py +1430 -0
  370. iris_harness/memory/knowledge/__init__.py +21 -0
  371. iris_harness/memory/knowledge/connectors/__init__.py +1 -0
  372. iris_harness/memory/knowledge/connectors/base.py +26 -0
  373. iris_harness/memory/knowledge/connectors/obsidian.py +48 -0
  374. iris_harness/memory/knowledge/entity_extractor.py +296 -0
  375. iris_harness/memory/knowledge/event_subscribers.py +77 -0
  376. iris_harness/memory/knowledge/models.py +89 -0
  377. iris_harness/memory/knowledge/page_manager.py +146 -0
  378. iris_harness/memory/knowledge/wiki_engine.py +381 -0
  379. iris_harness/memory/knowledge/wiki_index.py +93 -0
  380. iris_harness/memory/lessons.py +160 -0
  381. iris_harness/memory/log_archive.py +281 -0
  382. iris_harness/memory/map_exclusions.py +77 -0
  383. iris_harness/memory/ontology.py +107 -0
  384. iris_harness/memory/profile.py +62 -0
  385. iris_harness/memory/profile_recall.py +67 -0
  386. iris_harness/memory/removal.py +415 -0
  387. iris_harness/memory/resolution.py +64 -0
  388. iris_harness/memory/retention.py +836 -0
  389. iris_harness/memory/retriever.py +557 -0
  390. iris_harness/memory/semantic_index.py +649 -0
  391. iris_harness/memory/standing_instructions.py +211 -0
  392. iris_harness/memory/state/__init__.py +36 -0
  393. iris_harness/memory/state/chat.py +58 -0
  394. iris_harness/memory/state/continuations.py +411 -0
  395. iris_harness/memory/state/store.py +357 -0
  396. iris_harness/memory/statement_migration.py +917 -0
  397. iris_harness/memory/store.py +1251 -0
  398. iris_harness/memory/triage.py +342 -0
  399. iris_harness/memory/vocabulary.py +211 -0
  400. iris_harness/playground/__init__.py +29 -0
  401. iris_harness/playground/assertions.py +156 -0
  402. iris_harness/playground/baseline.py +78 -0
  403. iris_harness/playground/drift.py +278 -0
  404. iris_harness/playground/loader.py +57 -0
  405. iris_harness/playground/models.py +146 -0
  406. iris_harness/playground/runner.py +155 -0
  407. iris_harness/playground/service.py +111 -0
  408. iris_harness/plugins_builtin/AGENTS.md +24 -0
  409. iris_harness/plugins_builtin/__init__.py +7 -0
  410. iris_harness/plugins_builtin/code_exec/__init__.py +7 -0
  411. iris_harness/plugins_builtin/code_exec/handler.py +1285 -0
  412. iris_harness/plugins_builtin/code_exec/manifest.yaml +49 -0
  413. iris_harness/plugins_builtin/code_exec/plugin.py +72 -0
  414. iris_harness/plugins_builtin/graphiti_import/__init__.py +1 -0
  415. iris_harness/plugins_builtin/graphiti_import/cli.py +97 -0
  416. iris_harness/plugins_builtin/graphiti_import/graphiti.yaml +27 -0
  417. iris_harness/plugins_builtin/graphiti_import/manifest.yaml +14 -0
  418. iris_harness/plugins_builtin/graphiti_import/mappings.yaml +38 -0
  419. iris_harness/plugins_builtin/graphiti_import/plugin.py +18 -0
  420. iris_harness/plugins_builtin/graphiti_import/reader.py +168 -0
  421. iris_harness/plugins_builtin/research/__init__.py +21 -0
  422. iris_harness/plugins_builtin/research/cache.py +196 -0
  423. iris_harness/plugins_builtin/research/engine.py +276 -0
  424. iris_harness/plugins_builtin/research/extract.py +303 -0
  425. iris_harness/plugins_builtin/research/guard.py +67 -0
  426. iris_harness/plugins_builtin/research/language.py +70 -0
  427. iris_harness/plugins_builtin/research/manifest.yaml +117 -0
  428. iris_harness/plugins_builtin/research/models.py +133 -0
  429. iris_harness/plugins_builtin/research/news_policy.py +110 -0
  430. iris_harness/plugins_builtin/research/news_sources.yaml +85 -0
  431. iris_harness/plugins_builtin/research/plugin.py +53 -0
  432. iris_harness/plugins_builtin/research/privacy.py +128 -0
  433. iris_harness/plugins_builtin/research/providers/__init__.py +56 -0
  434. iris_harness/plugins_builtin/research/providers/base.py +52 -0
  435. iris_harness/plugins_builtin/research/providers/brave.py +116 -0
  436. iris_harness/plugins_builtin/research/providers/duckduckgo.py +144 -0
  437. iris_harness/plugins_builtin/research/providers/exa.py +120 -0
  438. iris_harness/plugins_builtin/research/providers/searxng.py +137 -0
  439. iris_harness/plugins_builtin/research/providers/tavily.py +103 -0
  440. iris_harness/plugins_builtin/research/rank.py +297 -0
  441. iris_harness/plugins_builtin/research/rerank.py +111 -0
  442. iris_harness/plugins_builtin/research/tool.py +232 -0
  443. iris_harness/plugins_builtin/research/tools.py +64 -0
  444. iris_harness/plugins_builtin/system/__init__.py +1 -0
  445. iris_harness/plugins_builtin/system/manifest.yaml +26 -0
  446. iris_harness/plugins_builtin/system/plugin.py +106 -0
  447. iris_harness/plugins_builtin/telegram_channel/__init__.py +6 -0
  448. iris_harness/plugins_builtin/telegram_channel/manifest.yaml +14 -0
  449. iris_harness/plugins_builtin/telegram_channel/plugin.py +38 -0
  450. iris_harness/plugins_builtin/web_channel/__init__.py +8 -0
  451. iris_harness/plugins_builtin/web_channel/connector.py +59 -0
  452. iris_harness/plugins_builtin/web_channel/manifest.yaml +28 -0
  453. iris_harness/plugins_builtin/web_channel/plugin.py +32 -0
  454. iris_harness/plugins_builtin/web_push_channel/__init__.py +0 -0
  455. iris_harness/plugins_builtin/web_push_channel/manifest.yaml +14 -0
  456. iris_harness/plugins_builtin/web_push_channel/plugin.py +77 -0
  457. iris_harness/py.typed +0 -0
  458. iris_harness/runtime/__init__.py +11 -0
  459. iris_harness/runtime/action_center.py +204 -0
  460. iris_harness/runtime/activity_notices.py +185 -0
  461. iris_harness/runtime/agent_console.py +287 -0
  462. iris_harness/runtime/agent_panels.py +51 -0
  463. iris_harness/runtime/agent_settings_store.py +132 -0
  464. iris_harness/runtime/api_routes.py +92 -0
  465. iris_harness/runtime/bootstrap.py +958 -0
  466. iris_harness/runtime/brief_tools.py +92 -0
  467. iris_harness/runtime/capabilities.py +118 -0
  468. iris_harness/runtime/channel_wiring.py +143 -0
  469. iris_harness/runtime/classifiers.py +123 -0
  470. iris_harness/runtime/client_config.py +124 -0
  471. iris_harness/runtime/confirmations.py +269 -0
  472. iris_harness/runtime/continuations.py +409 -0
  473. iris_harness/runtime/egress_access.py +30 -0
  474. iris_harness/runtime/egress_transport.py +265 -0
  475. iris_harness/runtime/escalation_actions.py +373 -0
  476. iris_harness/runtime/eval_runtime.py +42 -0
  477. iris_harness/runtime/external_text.py +37 -0
  478. iris_harness/runtime/external_tools.py +49 -0
  479. iris_harness/runtime/facade.py +1556 -0
  480. iris_harness/runtime/governance_judge.py +310 -0
  481. iris_harness/runtime/governed_http.py +630 -0
  482. iris_harness/runtime/handlers/__init__.py +1 -0
  483. iris_harness/runtime/handlers/brief_formats.py +706 -0
  484. iris_harness/runtime/handlers/brief_prefs.py +157 -0
  485. iris_harness/runtime/handlers/general.py +472 -0
  486. iris_harness/runtime/handlers/general_invoke.py +545 -0
  487. iris_harness/runtime/handlers/general_support.py +160 -0
  488. iris_harness/runtime/handlers/general_tools.py +306 -0
  489. iris_harness/runtime/handlers/local_skills.py +472 -0
  490. iris_harness/runtime/handlers/react.py +1135 -0
  491. iris_harness/runtime/handlers/skill_brief.py +1091 -0
  492. iris_harness/runtime/handlers/ticks.py +519 -0
  493. iris_harness/runtime/harness_services.py +266 -0
  494. iris_harness/runtime/identity_redaction.py +227 -0
  495. iris_harness/runtime/intercept_dispatch.py +224 -0
  496. iris_harness/runtime/intercepts.py +325 -0
  497. iris_harness/runtime/judges.py +414 -0
  498. iris_harness/runtime/learning_builders.py +100 -0
  499. iris_harness/runtime/learning_controls.py +662 -0
  500. iris_harness/runtime/mcp_serve.py +371 -0
  501. iris_harness/runtime/mission_proposals.py +146 -0
  502. iris_harness/runtime/nlu_parsing.py +112 -0
  503. iris_harness/runtime/plugin_host/__init__.py +61 -0
  504. iris_harness/runtime/plugin_host/api.py +659 -0
  505. iris_harness/runtime/plugin_host/declarative.py +130 -0
  506. iris_harness/runtime/plugin_host/dump.py +110 -0
  507. iris_harness/runtime/plugin_host/harness_topics.py +78 -0
  508. iris_harness/runtime/plugin_host/inventory.py +317 -0
  509. iris_harness/runtime/plugin_host/loader.py +638 -0
  510. iris_harness/runtime/plugin_host/manifest.py +857 -0
  511. iris_harness/runtime/plugin_host/nav.py +259 -0
  512. iris_harness/runtime/plugin_host/profile.py +393 -0
  513. iris_harness/runtime/plugin_host/registry.py +973 -0
  514. iris_harness/runtime/react_tools.py +1031 -0
  515. iris_harness/runtime/replies.py +116 -0
  516. iris_harness/runtime/rollout_flags.py +53 -0
  517. iris_harness/runtime/router_audit.py +168 -0
  518. iris_harness/runtime/routine_authoring.py +1996 -0
  519. iris_harness/runtime/self_learning_loop.py +322 -0
  520. iris_harness/runtime/session_memory.py +629 -0
  521. iris_harness/runtime/settings_catalog.py +82 -0
  522. iris_harness/runtime/shadow.py +134 -0
  523. iris_harness/runtime/skill_matching.py +192 -0
  524. iris_harness/runtime/skill_tool_specs.py +62 -0
  525. iris_harness/runtime/tool_access.py +90 -0
  526. iris_harness/runtime/tool_call_parsing.py +320 -0
  527. iris_harness/runtime/tool_service.py +360 -0
  528. iris_harness/runtime/turn/__init__.py +16 -0
  529. iris_harness/runtime/turn/host.py +154 -0
  530. iris_harness/runtime/turn/pipeline.py +215 -0
  531. iris_harness/runtime/turn/stages/__init__.py +49 -0
  532. iris_harness/runtime/turn/stages/classify.py +180 -0
  533. iris_harness/runtime/turn/stages/curate.py +69 -0
  534. iris_harness/runtime/turn/stages/execute.py +154 -0
  535. iris_harness/runtime/turn/stages/guard.py +89 -0
  536. iris_harness/runtime/turn/stages/intercept.py +99 -0
  537. iris_harness/runtime/turn/stages/notice.py +30 -0
  538. iris_harness/runtime/turn/stages/opener.py +69 -0
  539. iris_harness/runtime/turn/stages/plan.py +266 -0
  540. iris_harness/runtime/turn/stages/record.py +172 -0
  541. iris_harness/runtime/turn/stages/resolve.py +53 -0
  542. iris_harness/runtime/turn/stages/route.py +48 -0
  543. iris_harness/runtime/turn/stages/screen.py +103 -0
  544. iris_harness/runtime/turn/state.py +103 -0
  545. iris_harness/runtime/turn_capture.py +917 -0
  546. iris_harness/runtime/turn_context.py +46 -0
  547. iris_harness/runtime/types.py +57 -0
  548. iris_harness/runtime/welcome.py +338 -0
  549. iris_harness/sdk/AGENTS.md +21 -0
  550. iris_harness/sdk/__init__.py +43 -0
  551. iris_harness/sdk/activities.py +25 -0
  552. iris_harness/sdk/activity.py +13 -0
  553. iris_harness/sdk/approvals.py +38 -0
  554. iris_harness/sdk/audit.py +15 -0
  555. iris_harness/sdk/capabilities.py +61 -0
  556. iris_harness/sdk/channels.py +41 -0
  557. iris_harness/sdk/cli.py +171 -0
  558. iris_harness/sdk/config.py +31 -0
  559. iris_harness/sdk/content.py +110 -0
  560. iris_harness/sdk/digest.py +36 -0
  561. iris_harness/sdk/docs.py +18 -0
  562. iris_harness/sdk/events.py +14 -0
  563. iris_harness/sdk/health.py +56 -0
  564. iris_harness/sdk/heartbeat.py +44 -0
  565. iris_harness/sdk/http.py +51 -0
  566. iris_harness/sdk/identity.py +39 -0
  567. iris_harness/sdk/learning.py +17 -0
  568. iris_harness/sdk/llm.py +74 -0
  569. iris_harness/sdk/logging.py +36 -0
  570. iris_harness/sdk/memory.py +37 -0
  571. iris_harness/sdk/parsing.py +36 -0
  572. iris_harness/sdk/pending_actions.py +33 -0
  573. iris_harness/sdk/persistence.py +41 -0
  574. iris_harness/sdk/process_state.py +22 -0
  575. iris_harness/sdk/rag.py +61 -0
  576. iris_harness/sdk/reminders.py +28 -0
  577. iris_harness/sdk/research.py +44 -0
  578. iris_harness/sdk/sandbox.py +20 -0
  579. iris_harness/sdk/services.py +37 -0
  580. iris_harness/sdk/stable_tier.yaml +158 -0
  581. iris_harness/sdk/tasks.py +44 -0
  582. iris_harness/sdk/time.py +22 -0
  583. iris_harness/sdk/tools.py +35 -0
  584. iris_harness/sdk/types.py +74 -0
  585. iris_harness/sdk/vault.py +40 -0
  586. iris_harness/server/__init__.py +16 -0
  587. iris_harness/server/auth.py +335 -0
  588. iris_harness/server/channel_gateway/__init__.py +8 -0
  589. iris_harness/server/channel_gateway/main.py +433 -0
  590. iris_harness/server/channel_gateway/main_types.py +14 -0
  591. iris_harness/server/channel_gateway/telegram.py +352 -0
  592. iris_harness/server/evaluator/__init__.py +8 -0
  593. iris_harness/server/evaluator/main.py +134 -0
  594. iris_harness/server/governor/__init__.py +1 -0
  595. iris_harness/server/governor/main.py +124 -0
  596. iris_harness/server/iris_api/__init__.py +5 -0
  597. iris_harness/server/iris_api/action_center_routes.py +245 -0
  598. iris_harness/server/iris_api/agent_routes.py +245 -0
  599. iris_harness/server/iris_api/chat_routes.py +298 -0
  600. iris_harness/server/iris_api/detached_turns.py +139 -0
  601. iris_harness/server/iris_api/device_routes.py +261 -0
  602. iris_harness/server/iris_api/digest_feedback_routes.py +57 -0
  603. iris_harness/server/iris_api/digest_routes.py +61 -0
  604. iris_harness/server/iris_api/governance_routes.py +390 -0
  605. iris_harness/server/iris_api/health_routes.py +252 -0
  606. iris_harness/server/iris_api/learning_routes.py +373 -0
  607. iris_harness/server/iris_api/main.py +731 -0
  608. iris_harness/server/iris_api/mcp_server.py +215 -0
  609. iris_harness/server/iris_api/memory_routes.py +1244 -0
  610. iris_harness/server/iris_api/ops_routes.py +177 -0
  611. iris_harness/server/iris_api/playground_routes.py +100 -0
  612. iris_harness/server/iris_api/push_routes.py +120 -0
  613. iris_harness/server/iris_api/routines_routes.py +184 -0
  614. iris_harness/server/iris_api/runtime_access.py +22 -0
  615. iris_harness/server/iris_api/session_routes.py +596 -0
  616. iris_harness/server/iris_api/settings_routes.py +598 -0
  617. iris_harness/server/iris_api/static_ui.py +197 -0
  618. iris_harness/server/iris_api/webui_dist/apple-touch-icon.png +0 -0
  619. iris_harness/server/iris_api/webui_dist/assets/ActionCenter-DWR_1l0z.js +2 -0
  620. iris_harness/server/iris_api/webui_dist/assets/ActivityFeed-ZWGTVQSF.js +1 -0
  621. iris_harness/server/iris_api/webui_dist/assets/AgentDashboard-BI84kZoM.js +1 -0
  622. iris_harness/server/iris_api/webui_dist/assets/Agents-D18zaw_r.js +1 -0
  623. iris_harness/server/iris_api/webui_dist/assets/CallTrace-BylIUQ-O.js +1 -0
  624. iris_harness/server/iris_api/webui_dist/assets/Card-CXQcUgWe.js +1 -0
  625. iris_harness/server/iris_api/webui_dist/assets/Chat-PLyyCR6A.js +3 -0
  626. iris_harness/server/iris_api/webui_dist/assets/ConfirmDialog-Ljt4-aGA.js +1 -0
  627. iris_harness/server/iris_api/webui_dist/assets/CopyBlock-B9Rb1MjP.js +1 -0
  628. iris_harness/server/iris_api/webui_dist/assets/Devices-DPzcdVTl.js +1 -0
  629. iris_harness/server/iris_api/webui_dist/assets/Digest-D3OwOWjA.js +1 -0
  630. iris_harness/server/iris_api/webui_dist/assets/DigitalTwin-CU6j7EyE.js +1 -0
  631. iris_harness/server/iris_api/webui_dist/assets/Governance-D2Llo8hR.js +2 -0
  632. iris_harness/server/iris_api/webui_dist/assets/Health-DQHc4_Q4.js +1 -0
  633. iris_harness/server/iris_api/webui_dist/assets/Heartbeats-DBoBDCFI.js +1 -0
  634. iris_harness/server/iris_api/webui_dist/assets/Inbox-BZQIPizq.js +1 -0
  635. iris_harness/server/iris_api/webui_dist/assets/Knowledge-Dxqd_5DZ.js +1 -0
  636. iris_harness/server/iris_api/webui_dist/assets/Learning-CMNYMHjx.js +1 -0
  637. iris_harness/server/iris_api/webui_dist/assets/Markdown-BWcvdIi3.js +14 -0
  638. iris_harness/server/iris_api/webui_dist/assets/Memory-CChaApjv.js +1 -0
  639. iris_harness/server/iris_api/webui_dist/assets/More-3m9-PYFH.js +1 -0
  640. iris_harness/server/iris_api/webui_dist/assets/Onboarding-C7f9VU2K.js +1 -0
  641. iris_harness/server/iris_api/webui_dist/assets/Overview-DseVboze.js +1 -0
  642. iris_harness/server/iris_api/webui_dist/assets/Pair-DhdOmphI.js +1 -0
  643. iris_harness/server/iris_api/webui_dist/assets/Playground-Cxfb4LaM.js +1 -0
  644. iris_harness/server/iris_api/webui_dist/assets/PluginDetail-lkeBj-tU.js +1 -0
  645. iris_harness/server/iris_api/webui_dist/assets/Portfolio-DRoNXSTM.js +1 -0
  646. iris_harness/server/iris_api/webui_dist/assets/Rag-DB1xDRLF.js +1 -0
  647. iris_harness/server/iris_api/webui_dist/assets/ReconnectSheet-Dt58ouRo.js +1 -0
  648. iris_harness/server/iris_api/webui_dist/assets/Reminder-DTWdt4Kk.js +1 -0
  649. iris_harness/server/iris_api/webui_dist/assets/Routines-lV-5E3oI.js +1 -0
  650. iris_harness/server/iris_api/webui_dist/assets/Sessions-z01Guqrs.js +1 -0
  651. iris_harness/server/iris_api/webui_dist/assets/Settings-Cl7q1Nt7.js +1 -0
  652. iris_harness/server/iris_api/webui_dist/assets/Setup-D45UEQSW.js +1 -0
  653. iris_harness/server/iris_api/webui_dist/assets/Switch-BH9PZxoY.js +1 -0
  654. iris_harness/server/iris_api/webui_dist/assets/SystemCheck-CBeccZLp.js +2 -0
  655. iris_harness/server/iris_api/webui_dist/assets/breakpoint-CLJTHGon.js +1 -0
  656. iris_harness/server/iris_api/webui_dist/assets/check-Beu2NZZN.js +1 -0
  657. iris_harness/server/iris_api/webui_dist/assets/dagre-DLioOiRN.css +1 -0
  658. iris_harness/server/iris_api/webui_dist/assets/dagre-JZRyA1Pn.js +7 -0
  659. iris_harness/server/iris_api/webui_dist/assets/dialog-C6a95R8r.js +1 -0
  660. iris_harness/server/iris_api/webui_dist/assets/es2015-CO7dZbVE.js +41 -0
  661. iris_harness/server/iris_api/webui_dist/assets/http-BUcIPk9n.js +1 -0
  662. iris_harness/server/iris_api/webui_dist/assets/index-B9EGVml8.css +1 -0
  663. iris_harness/server/iris_api/webui_dist/assets/index-C7tnPEHM.js +14 -0
  664. iris_harness/server/iris_api/webui_dist/assets/input-DSk1NoDn.js +1 -0
  665. iris_harness/server/iris_api/webui_dist/assets/layout-DNsTceCW.js +1 -0
  666. iris_harness/server/iris_api/webui_dist/assets/nodeMeta-TQaGURWg.js +1 -0
  667. iris_harness/server/iris_api/webui_dist/assets/parts-BYEWLm3P.js +1 -0
  668. iris_harness/server/iris_api/webui_dist/assets/parts-DedGbiW5.js +1 -0
  669. iris_harness/server/iris_api/webui_dist/assets/thumbs-down-DBEA3SX_.js +1 -0
  670. iris_harness/server/iris_api/webui_dist/assets/useQuery-CXR1pn6x.js +1 -0
  671. iris_harness/server/iris_api/webui_dist/icon-192.png +0 -0
  672. iris_harness/server/iris_api/webui_dist/icon-512-maskable.png +0 -0
  673. iris_harness/server/iris_api/webui_dist/icon-512.png +0 -0
  674. iris_harness/server/iris_api/webui_dist/index.html +37 -0
  675. iris_harness/server/iris_api/webui_dist/manifest.webmanifest +17 -0
  676. iris_harness/server/iris_api/webui_dist/offline.html +40 -0
  677. iris_harness/server/iris_api/webui_dist/sw.js +228 -0
  678. iris_harness/server/iris_api/write_guard.py +27 -0
  679. iris_harness/services/__init__.py +8 -0
  680. iris_harness/services/activities/__init__.py +42 -0
  681. iris_harness/services/activities/events.py +65 -0
  682. iris_harness/services/activities/models.py +84 -0
  683. iris_harness/services/activities/runner.py +104 -0
  684. iris_harness/services/activities/store.py +378 -0
  685. iris_harness/services/channels/__init__.py +14 -0
  686. iris_harness/services/channels/approval_commands.py +192 -0
  687. iris_harness/services/channels/approval_delivery.py +139 -0
  688. iris_harness/services/channels/channel_config.py +109 -0
  689. iris_harness/services/channels/connectors/__init__.py +7 -0
  690. iris_harness/services/channels/connectors/console.py +32 -0
  691. iris_harness/services/channels/connectors/telegram.py +167 -0
  692. iris_harness/services/channels/connectors/telegram_poller.py +557 -0
  693. iris_harness/services/channels/connectors/ws_client.py +121 -0
  694. iris_harness/services/channels/gateway.py +64 -0
  695. iris_harness/services/channels/models.py +37 -0
  696. iris_harness/services/channels/protocol.py +24 -0
  697. iris_harness/services/channels/reminder_commands.py +447 -0
  698. iris_harness/services/channels/web_push/__init__.py +18 -0
  699. iris_harness/services/channels/web_push/connector.py +217 -0
  700. iris_harness/services/channels/web_push/encryption.py +123 -0
  701. iris_harness/services/channels/web_push/keys.py +105 -0
  702. iris_harness/services/channels/web_push/store.py +153 -0
  703. iris_harness/services/channels/web_push/vapid.py +66 -0
  704. iris_harness/services/digest/__init__.py +5 -0
  705. iris_harness/services/digest/edits.py +154 -0
  706. iris_harness/services/digest/expiry.py +540 -0
  707. iris_harness/services/digest/footer.py +63 -0
  708. iris_harness/services/digest/learned.py +179 -0
  709. iris_harness/services/digest/run_first.py +175 -0
  710. iris_harness/services/digest/settings.py +1152 -0
  711. iris_harness/services/digests/__init__.py +22 -0
  712. iris_harness/services/digests/store.py +235 -0
  713. iris_harness/services/docs_search/__init__.py +18 -0
  714. iris_harness/services/docs_search/corpus.py +611 -0
  715. iris_harness/services/docs_search/search.py +180 -0
  716. iris_harness/services/health/__init__.py +56 -0
  717. iris_harness/services/health/checks.py +470 -0
  718. iris_harness/services/health/credentials.py +158 -0
  719. iris_harness/services/health/governance.py +155 -0
  720. iris_harness/services/health/heartbeat.py +78 -0
  721. iris_harness/services/health/incidents.py +203 -0
  722. iris_harness/services/health/jobs.py +154 -0
  723. iris_harness/services/health/models.py +170 -0
  724. iris_harness/services/health/pending_actions.py +79 -0
  725. iris_harness/services/health/repair.py +198 -0
  726. iris_harness/services/health/service.py +153 -0
  727. iris_harness/services/health/skills.py +52 -0
  728. iris_harness/services/health/watch.py +499 -0
  729. iris_harness/services/health/watch_edits.py +121 -0
  730. iris_harness/services/heartbeat/__init__.py +17 -0
  731. iris_harness/services/heartbeat/config.py +109 -0
  732. iris_harness/services/heartbeat/diagnostics.py +206 -0
  733. iris_harness/services/heartbeat/models.py +69 -0
  734. iris_harness/services/heartbeat/run_store.py +360 -0
  735. iris_harness/services/heartbeat/schedule_text.py +118 -0
  736. iris_harness/services/heartbeat/scheduler.py +715 -0
  737. iris_harness/services/heartbeat/slots.py +358 -0
  738. iris_harness/services/learning/__init__.py +40 -0
  739. iris_harness/services/learning/analyst.py +383 -0
  740. iris_harness/services/learning/behavior_miner.py +198 -0
  741. iris_harness/services/learning/crystallizer.py +337 -0
  742. iris_harness/services/learning/dedup.py +67 -0
  743. iris_harness/services/learning/engine.py +215 -0
  744. iris_harness/services/learning/escalation_priors.py +78 -0
  745. iris_harness/services/learning/eval_adapter.py +118 -0
  746. iris_harness/services/learning/eval_docker.py +191 -0
  747. iris_harness/services/learning/eval_harness.py +275 -0
  748. iris_harness/services/learning/eval_preflight.py +107 -0
  749. iris_harness/services/learning/eval_replay_cli.py +153 -0
  750. iris_harness/services/learning/eval_runtime.py +63 -0
  751. iris_harness/services/learning/eval_workload.py +109 -0
  752. iris_harness/services/learning/experiment_loop.py +148 -0
  753. iris_harness/services/learning/intelligence.py +379 -0
  754. iris_harness/services/learning/intention_rollup.py +141 -0
  755. iris_harness/services/learning/lesson_capture.py +334 -0
  756. iris_harness/services/learning/metrics.py +25 -0
  757. iris_harness/services/learning/models.py +60 -0
  758. iris_harness/services/learning/preflight.py +252 -0
  759. iris_harness/services/learning/promote.py +203 -0
  760. iris_harness/services/learning/proposal_quality.py +79 -0
  761. iris_harness/services/learning/retriever.py +148 -0
  762. iris_harness/services/learning/signals.py +285 -0
  763. iris_harness/services/learning/store.py +791 -0
  764. iris_harness/services/learning/strategies.py +106 -0
  765. iris_harness/services/learning/suppression.py +528 -0
  766. iris_harness/services/missions/__init__.py +15 -0
  767. iris_harness/services/missions/engine.py +144 -0
  768. iris_harness/services/missions/handlers.py +47 -0
  769. iris_harness/services/missions/models.py +70 -0
  770. iris_harness/services/missions/proposer.py +82 -0
  771. iris_harness/services/missions/store.py +169 -0
  772. iris_harness/services/notifications/__init__.py +45 -0
  773. iris_harness/services/notifications/bills.py +325 -0
  774. iris_harness/services/notifications/channels.py +364 -0
  775. iris_harness/services/notifications/events.py +112 -0
  776. iris_harness/services/notifications/health.py +52 -0
  777. iris_harness/services/notifications/models.py +76 -0
  778. iris_harness/services/notifications/recurrence.py +150 -0
  779. iris_harness/services/notifications/snooze.py +322 -0
  780. iris_harness/services/notifications/store.py +971 -0
  781. iris_harness/services/notifications/targets.py +64 -0
  782. iris_harness/services/rag/__init__.py +55 -0
  783. iris_harness/services/rag/chunker.py +71 -0
  784. iris_harness/services/rag/documents.py +135 -0
  785. iris_harness/services/rag/index.py +270 -0
  786. iris_harness/services/rag/ingest.py +543 -0
  787. iris_harness/services/rag/ingest_gate.py +162 -0
  788. iris_harness/services/rag/ingest_source.py +153 -0
  789. iris_harness/services/rag/loaders.py +77 -0
  790. iris_harness/services/rag/models.py +122 -0
  791. iris_harness/services/rag/obsidian.py +120 -0
  792. iris_harness/services/rag/ocr.py +55 -0
  793. iris_harness/services/rag/qa.py +113 -0
  794. iris_harness/services/rag/retrieve.py +96 -0
  795. iris_harness/services/rag/sensitivity.py +102 -0
  796. iris_harness/services/rag/store.py +326 -0
  797. iris_harness/services/research/__init__.py +7 -0
  798. iris_harness/services/research/providers.py +345 -0
  799. iris_harness/services/routines/__init__.py +81 -0
  800. iris_harness/services/routines/authoring.py +1489 -0
  801. iris_harness/services/routines/models.py +290 -0
  802. iris_harness/services/routines/reflection.py +117 -0
  803. iris_harness/services/routines/seeded.py +172 -0
  804. iris_harness/services/routines/store.py +569 -0
  805. iris_harness/services/system/__init__.py +26 -0
  806. iris_harness/services/system/doctor.py +809 -0
  807. iris_harness/services/system/inventory.py +126 -0
  808. iris_harness/services/system/setup_state.py +163 -0
  809. iris_harness/services/system/status.py +185 -0
  810. iris_harness/services/system/telegram_pairing.py +101 -0
  811. iris_harness/services/tasks/__init__.py +96 -0
  812. iris_harness/services/tasks/brief_view.py +96 -0
  813. iris_harness/services/tasks/events.py +103 -0
  814. iris_harness/services/tasks/models.py +258 -0
  815. iris_harness/services/tasks/pending_actions.py +305 -0
  816. iris_harness/services/tasks/store.py +568 -0
  817. iris_harness/testing/__init__.py +245 -0
  818. iris_harness/testing/conformance.py +520 -0
  819. iris_harness/testing/harness.py +618 -0
  820. iris_harness/testing/network_imports.py +177 -0
  821. iris_harness/testing/proof_bundle.py +50 -0
  822. iris_harness/testing/stable.py +185 -0
  823. iris_harness/tools/__init__.py +33 -0
  824. iris_harness/tools/mcp/__init__.py +18 -0
  825. iris_harness/tools/mcp/server.py +270 -0
  826. iris_harness/tools/mcp_bridge.py +1267 -0
  827. iris_harness/tools/propose_skill_from_sandbox.py +127 -0
  828. iris_harness/tools/sandbox/Dockerfile +42 -0
  829. iris_harness/tools/sandbox/Dockerfile.eval +47 -0
  830. iris_harness/tools/sandbox/__init__.py +55 -0
  831. iris_harness/tools/sandbox/config.py +60 -0
  832. iris_harness/tools/sandbox/docker_sandbox.py +302 -0
  833. iris_harness/tools/sandbox/egress.py +192 -0
  834. iris_harness/tools/sandbox/egress_proxy.py +181 -0
  835. iris_harness/tools/sandbox/exceptions.py +19 -0
  836. iris_harness/tools/sandbox/models.py +42 -0
  837. iris_harness/tools/sandbox/runtime.py +161 -0
  838. iris_harness/tools/sandbox/workspace.py +46 -0
  839. iris_harness/tools/sandbox_tools.py +156 -0
  840. iris_harness/tools/skills/__init__.py +41 -0
  841. iris_harness/tools/skills/hot_reload.py +100 -0
  842. iris_harness/tools/skills/loader.py +455 -0
  843. iris_harness/tools/skills/models.py +409 -0
  844. iris_harness/tools/skills/registry.py +166 -0
  845. iris_harness/tools/skills/semantic_router.py +147 -0
  846. iris_harness/tools/skills/skill_synthesizer.py +139 -0
  847. iris_harness/tools/stock_quote.py +126 -0
  848. iris_harness-0.1.0.dist-info/METADATA +249 -0
  849. iris_harness-0.1.0.dist-info/RECORD +964 -0
  850. iris_harness-0.1.0.dist-info/WHEEL +4 -0
  851. iris_harness-0.1.0.dist-info/entry_points.txt +8 -0
  852. iris_harness-0.1.0.dist-info/licenses/LICENSE +190 -0
  853. iris_personal/__init__.py +10 -0
  854. iris_personal/connections/__init__.py +7 -0
  855. iris_personal/connections/google.py +911 -0
  856. iris_personal/connections/google_routes.py +102 -0
  857. iris_personal/email/__init__.py +27 -0
  858. iris_personal/email/accounts.py +335 -0
  859. iris_personal/email/agent_tools.py +1277 -0
  860. iris_personal/email/analysis.py +152 -0
  861. iris_personal/email/categories.py +160 -0
  862. iris_personal/email/category_store.py +528 -0
  863. iris_personal/email/contracts.py +153 -0
  864. iris_personal/email/digest.py +186 -0
  865. iris_personal/email/events.py +75 -0
  866. iris_personal/email/feedback_keys.py +78 -0
  867. iris_personal/email/provider_api.py +133 -0
  868. iris_personal/email/providers.py +321 -0
  869. iris_personal/email/semantic_index.py +406 -0
  870. iris_personal/email/send_tools.py +291 -0
  871. iris_personal/email/store.py +1215 -0
  872. iris_personal/email/sweep.py +200 -0
  873. iris_personal/email/sweep_gate.py +157 -0
  874. iris_personal/email/trash_tools.py +375 -0
  875. iris_personal/email/write_approvals.py +320 -0
  876. iris_personal/plugins/__init__.py +7 -0
  877. iris_personal/plugins/email_workflows/__init__.py +8 -0
  878. iris_personal/plugins/email_workflows/agent.py +407 -0
  879. iris_personal/plugins/email_workflows/cli.py +1692 -0
  880. iris_personal/plugins/email_workflows/cli_setup.py +283 -0
  881. iris_personal/plugins/email_workflows/cli_writes.py +190 -0
  882. iris_personal/plugins/email_workflows/demo/__init__.py +10 -0
  883. iris_personal/plugins/email_workflows/demo/corpus.json +3819 -0
  884. iris_personal/plugins/email_workflows/demo/corpus.py +871 -0
  885. iris_personal/plugins/email_workflows/demo/fake_model.yaml +112 -0
  886. iris_personal/plugins/email_workflows/demo/home.py +144 -0
  887. iris_personal/plugins/email_workflows/demo/provider.py +330 -0
  888. iris_personal/plugins/email_workflows/demo/run.py +416 -0
  889. iris_personal/plugins/email_workflows/digest_focus.py +181 -0
  890. iris_personal/plugins/email_workflows/discovery.py +673 -0
  891. iris_personal/plugins/email_workflows/first_digest.py +112 -0
  892. iris_personal/plugins/email_workflows/followup.py +507 -0
  893. iris_personal/plugins/email_workflows/holdout.py +216 -0
  894. iris_personal/plugins/email_workflows/inbox_mix.py +88 -0
  895. iris_personal/plugins/email_workflows/job_watch.py +300 -0
  896. iris_personal/plugins/email_workflows/job_watch.yaml +46 -0
  897. iris_personal/plugins/email_workflows/judge.py +668 -0
  898. iris_personal/plugins/email_workflows/judge.yaml +228 -0
  899. iris_personal/plugins/email_workflows/judge_api.py +174 -0
  900. iris_personal/plugins/email_workflows/judge_cards.py +241 -0
  901. iris_personal/plugins/email_workflows/judge_chat.py +269 -0
  902. iris_personal/plugins/email_workflows/judge_config.py +185 -0
  903. iris_personal/plugins/email_workflows/judge_corrections.py +59 -0
  904. iris_personal/plugins/email_workflows/judge_digest.py +191 -0
  905. iris_personal/plugins/email_workflows/judge_labels.py +288 -0
  906. iris_personal/plugins/email_workflows/judge_surfaces.py +106 -0
  907. iris_personal/plugins/email_workflows/judge_view.py +119 -0
  908. iris_personal/plugins/email_workflows/judge_wiring.py +235 -0
  909. iris_personal/plugins/email_workflows/judge_words.py +153 -0
  910. iris_personal/plugins/email_workflows/judgments.py +354 -0
  911. iris_personal/plugins/email_workflows/knn_gate.py +503 -0
  912. iris_personal/plugins/email_workflows/manifest.yaml +198 -0
  913. iris_personal/plugins/email_workflows/map_exclusions.py +123 -0
  914. iris_personal/plugins/email_workflows/memory_map.yaml +18 -0
  915. iris_personal/plugins/email_workflows/onboarding.py +1843 -0
  916. iris_personal/plugins/email_workflows/onboarding.yaml +65 -0
  917. iris_personal/plugins/email_workflows/onboarding_api.py +221 -0
  918. iris_personal/plugins/email_workflows/plugin.py +178 -0
  919. iris_personal/plugins/email_workflows/semantic_heartbeat.py +76 -0
  920. iris_personal/plugins/email_workflows/sweep_health.py +55 -0
  921. iris_personal/plugins/email_workflows/tools.py +52 -0
  922. iris_personal/plugins/email_workflows/triage.py +797 -0
  923. iris_personal/plugins/email_workflows/wiki_ingestion.py +111 -0
  924. iris_personal/plugins/email_workflows/writes_health.py +64 -0
  925. iris_personal/plugins/gmail/__init__.py +6 -0
  926. iris_personal/plugins/gmail/cli.py +198 -0
  927. iris_personal/plugins/gmail/gmail_attachments.py +157 -0
  928. iris_personal/plugins/gmail/gmail_fetch.py +858 -0
  929. iris_personal/plugins/gmail/gmail_oauth.py +252 -0
  930. iris_personal/plugins/gmail/manifest.yaml +40 -0
  931. iris_personal/plugins/gmail/plugin.py +94 -0
  932. iris_personal/plugins/gmail/provider.py +195 -0
  933. iris_personal/plugins/gmail/vendor_categories.py +55 -0
  934. iris_personal/plugins/gmail/vendor_categories.yaml +16 -0
  935. iris_personal/plugins/imap/__init__.py +7 -0
  936. iris_personal/plugins/imap/account.py +156 -0
  937. iris_personal/plugins/imap/cli.py +261 -0
  938. iris_personal/plugins/imap/connection.py +412 -0
  939. iris_personal/plugins/imap/health.py +102 -0
  940. iris_personal/plugins/imap/keywords.py +75 -0
  941. iris_personal/plugins/imap/manifest.yaml +22 -0
  942. iris_personal/plugins/imap/mime.py +239 -0
  943. iris_personal/plugins/imap/plugin.py +42 -0
  944. iris_personal/plugins/imap/provider.py +661 -0
  945. iris_personal/plugins/imap/state.py +259 -0
  946. iris_personal/py.typed +0 -0
  947. memris/__init__.py +42 -0
  948. memris/graph.py +978 -0
  949. memris/interchange/__init__.py +48 -0
  950. memris/interchange/__main__.py +55 -0
  951. memris/interchange/jsonld.py +474 -0
  952. memris/interchange/mapping.py +258 -0
  953. memris/learn.py +230 -0
  954. memris/model/__init__.py +208 -0
  955. memris/ontology/__init__.py +52 -0
  956. memris/ontology/__main__.py +34 -0
  957. memris/ontology/compiler.py +761 -0
  958. memris/ontology/learned.py +96 -0
  959. memris/ontology/loader.py +238 -0
  960. memris/ontology/spec.py +141 -0
  961. memris/resolve.py +169 -0
  962. memris/store/__init__.py +107 -0
  963. memris/store/memory.py +121 -0
  964. memris/store/sqlite.py +646 -0
@@ -0,0 +1,5 @@
1
+ """IRIS package root."""
2
+
3
+ __all__ = ["__version__"]
4
+
5
+ __version__ = "0.1.0"
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: reminders
3
+ description: How IRIS handles requests to remember, schedule, or follow up on something later.
4
+ match_intents: [calendar]
5
+ match_keywords: [remind, reminder, reminders, follow up, follow-up, schedule, deadline, by sunday, by monday, by tuesday, by wednesday, by thursday, by friday, by saturday]
6
+ ---
7
+
8
+ # Behavior — Reminders
9
+
10
+ When the user asks to be reminded of something, scheduled for something, or
11
+ followed up on by a date, treat it as a durable commitment — not a passing
12
+ chat turn. The reminder must survive process restarts and be findable in a
13
+ future session.
14
+
15
+ ## Recipe
16
+
17
+ 1. **Confirm the intent in one short sentence.** No preamble; state what
18
+ you're capturing and the date/time you parsed. If the time is ambiguous,
19
+ ask exactly one question, then stop.
20
+ 2. **Call `add_reminder`** (or the `create_reminder` tool in the loop). It
21
+ writes the reminder to the one reminder store: a calendar reminder event
22
+ plus its delivery row, delivered on the user's channels at that time.
23
+ Dates and times are the user's local time.
24
+ 3. **Use the calendar event tools only for events.** `add_calendar_event`,
25
+ `edit_calendar_event` and `delete_calendar_event` manage standalone
26
+ events; a reminder is never written by hand or to a file.
27
+ 4. **Tell the user when it will fire.** One line: the reminder text and its
28
+ local date and time. Do not bury this in a long response.
29
+ 5. **Do not invent recurrence.** If the user did not say how often it
30
+ repeats, create a one-time reminder and state that assumption briefly.
31
+
32
+ ## What to avoid
33
+
34
+ - Writing a reminder to any file (a markdown table, `~/.iris/reminders/`,
35
+ `~/.iris/sandbox/<random-hash>/`) — the reminder store is the only place a
36
+ reminder lives, and only `add_reminder` / `create_reminder` write it.
37
+ - Silently dropping the reminder into chat history with no persistence.
38
+ - Long acknowledgement messages. The user wants the commitment captured,
39
+ not a recap.
40
+ - Asking more than one clarifying question. If multiple things are unclear,
41
+ pick the most blocking one and proceed with sensible defaults for the
42
+ rest, then state the assumptions you made.
@@ -0,0 +1,29 @@
1
+ # Channel Gateway configuration.
2
+ # Each channel maps a logical name to a connector type and parameters.
3
+ # Environment-style placeholders (e.g. ${TELEGRAM_BOT_TOKEN}) are resolved
4
+ # from os.environ at runtime. Channels with unresolved required vars are
5
+ # silently skipped.
6
+ #
7
+ # default: name of the channel used for heartbeats and proactive notifications.
8
+ # Falls back to "console" if the named channel fails to register. The check runs
9
+ # after the channel plugins mount, so naming a plugin-provided surface here works.
10
+ #
11
+ # Which connector serves a row: `console` is core (the guaranteed fallback);
12
+ # `telegram` comes from the telegram_channel plugin and `web` from web_channel, so
13
+ # a profile that does not mount them simply has no such surface (OSS plan M4.5).
14
+ default: telegram
15
+
16
+ channels:
17
+ - name: console
18
+ type: console
19
+ description: Local development sink that writes to stdout.
20
+
21
+ - name: telegram
22
+ type: telegram
23
+ description: Personal Telegram bot for proactive notifications.
24
+ bot_token: ${TELEGRAM_BOT_TOKEN}
25
+ default_chat_id: ${TELEGRAM_CHAT_ID}
26
+
27
+ - name: web
28
+ type: web
29
+ description: The web UI's chat — a proactive notice lands in its session history.
@@ -0,0 +1,8 @@
1
+ # IRIS audit compaction (Phase 5)
2
+ # Runs every day at 02:30 local time.
3
+ #
4
+ # Install example:
5
+ # crontab -e
6
+ # 30 2 * * * /path/to/.venv/bin/iris audit compact >> /var/log/iris-audit-compact.log 2>&1
7
+
8
+ 30 2 * * * iris audit compact
@@ -0,0 +1,238 @@
1
+ # The morning digest's defaults (loop-proof plan D3-D5, ADR-0122).
2
+ #
3
+ # This file is the DEFAULT. The owner's changes from Settings -> Digest (or from chat:
4
+ # "add X to my digest") are saved on the data volume (settings.db, section `digest`,
5
+ # ADR-0120) and laid over it by `load_digest_settings`
6
+ # (src/iris_harness/services/digest/settings.py). A deploy that changes this file
7
+ # changes every field the owner has not changed.
8
+
9
+ # Send the morning digest at all.
10
+ enabled: true
11
+
12
+ # Local time the digest goes out, HH:MM in IRIS_TZ (UTC when IRIS_TZ is unset).
13
+ time: "07:00"
14
+
15
+ # Jobs the digest runs, in order, right before it renders (loop-proof PR 5): mail is
16
+ # swept and judged first so the digest never shows a stale or half-judged inbox. Each
17
+ # runs like the Heartbeats screen's "Run now" (a kept run the job checks count), on the
18
+ # scheduled digest and on a manual "run the digest now" alike. `if_setting` names an
19
+ # on/off setting, read with its declared default; the job runs only while it is on. A
20
+ # job that is not registered or is turned off is skipped (logged); one already running
21
+ # is waited for, not started twice. Once `run_first_budget_seconds` is spent no further
22
+ # job starts. A job that fails never stops the digest. Not edited from the app.
23
+ run_first:
24
+ - heartbeat: email_sweep
25
+ if_setting: IRIS_EMAIL_JUDGE # only while the email judge is on
26
+ - heartbeat: email_judge
27
+ if_setting: IRIS_EMAIL_JUDGE
28
+ # 240 s keeps the digest on time: it fires 5 minutes early, and by then the 06:15 / 06:30
29
+ # runs have done most of the work; mail not reached waits and the digest says so.
30
+ run_first_budget_seconds: 240
31
+
32
+ # Where it goes: `all` = every rendering (web stored, Telegram chunked, push
33
+ # headline), or a comma-separated list of channel names.
34
+ channel: all
35
+
36
+ # The brief's tool-slot names, in the order they appear: the groups' order below, then
37
+ # the sections in no group, `learned_yesterday` last. A slot the brief skill does not
38
+ # have is skipped at render time. A section added here later reaches an owner who
39
+ # reordered their digest too: it slots in after the section it follows here (last if
40
+ # last). Within a group, sections show in this (the owner's) order.
41
+ sections:
42
+ - todays_plan
43
+ - todays_events
44
+ - due_today
45
+ - overdue
46
+ - missed_reminders
47
+ - reminders
48
+ - open_tasks
49
+ - bills_due
50
+ - unusual_spend
51
+ - portfolio
52
+ - needs_reply
53
+ - focus
54
+ - judged_yesterday
55
+ - email_summary
56
+ - open_followups
57
+ - resolved_followups
58
+ - indexes
59
+ - stocks
60
+ - news_ai
61
+ - news_global
62
+ - news_local
63
+ - active_items
64
+ - routines
65
+ - learned_yesterday
66
+
67
+ # Sections the digest knows but leaves off until the owner turns them on in Settings ->
68
+ # Digest (the brief skill keeps the slot). Trending GitHub repos are opt-in.
69
+ sections_off:
70
+ - top_repos
71
+
72
+ # Always shown, always last, whatever the owner's list says: the footer that says what
73
+ # IRIS learned yesterday (D17) is never omitted, and is in no group.
74
+ locked_sections:
75
+ - learned_yesterday
76
+
77
+ # The digest's layout (digest v5, prototype signed off 2026-09-25): the sections under
78
+ # a few headed groups, in this order. A section in no group (active_items, routines,
79
+ # top_repos when on) goes in a last group, "More". `push` is the group's line in the
80
+ # phone notification: a format string over the number of items each of its sections
81
+ # has ({bills_due} = how many bills are due); a group with no `push` has no line.
82
+ # Owner-facing wording; change it here, not in code.
83
+ groups:
84
+ - id: today
85
+ title: Today
86
+ icon: "☀️"
87
+ sections: [todays_plan, todays_events, due_today, overdue, missed_reminders, reminders, open_tasks]
88
+ push: "Events {todays_events} · Due today {due_today} · Tasks {open_tasks}"
89
+ - id: money
90
+ title: Money
91
+ icon: "💳"
92
+ sections: [bills_due, unusual_spend, portfolio]
93
+ push: "Bills {bills_due}"
94
+ - id: inbox
95
+ title: Inbox
96
+ icon: "📬"
97
+ sections: [needs_reply, focus, judged_yesterday, email_summary, open_followups, resolved_followups]
98
+ push: "Focus {focus}"
99
+ - id: markets
100
+ title: Markets
101
+ icon: "📈"
102
+ sections: [indexes, stocks]
103
+ - id: news
104
+ title: News
105
+ icon: "📰"
106
+ sections: [news_ai, news_global, news_local]
107
+
108
+ # How each channel renders the groups.
109
+ # web every group, a sub-heading per section; empty sections fold into one
110
+ # "nothing ..." line; links on the source name.
111
+ # telegram one message per group, a card (quote block) per section, news in
112
+ # expandable cards; empty sections and empty groups are not sent; the last
113
+ # message has buttons to the full digest and Settings. `rule` is an optional
114
+ # line under each group heading ("" = none, the default: on a phone a
115
+ # fixed-length rule wraps at larger text sizes — owner 2026-09-25).
116
+ # web_push a glance: one line per group from its `push`, at most `lines`, never the
117
+ # excluded groups; tapping opens the web copy.
118
+ channels:
119
+ web: {layout: grouped, empty: fold, links: source}
120
+ telegram:
121
+ layout: message_per_group
122
+ section: card
123
+ news: expandable_card
124
+ empty: hide
125
+ links: source
126
+ buttons: [full_digest, settings]
127
+ rule: ""
128
+ web_push: {layout: headline, lines: 3, exclude_groups: [news, markets]}
129
+
130
+ # When dated items leave the digest (owner rule 2026-09-25): every dated item ends
131
+ # CLOSED (done, paid or dismissed by the owner) or EXPIRED (aged out, below). The
132
+ # digest shows only open, unexpired items; an expired task stays in the store with
133
+ # status `expired` and the reason. Days are the owner's local days (IRIS_TZ): a task
134
+ # due Sep 22 with task_overdue_days 3 shows as Overdue Sep 23-25, expired from Sep 26.
135
+ # prep_after_event minutes after its meeting ends, a prep task expires
136
+ # event_after_end minutes after it ends, a calendar event leaves the digest
137
+ # task_overdue_days days a dated task shows under Overdue, then expires
138
+ # bill_ask_days days after its due date an unpaid bill is asked about
139
+ # ("Did you pay?"), then
140
+ # bill_overdue_digest_days days it stays in the digest before it expires
141
+ # inbox_notice_days days a dated inbox notice stays in the digest
142
+ # reminder_missed_digests digests a missed reminder is carried into
143
+ # A plugin's own kinds are tuned here too, by the key its manifest declares under
144
+ # `expiry:` (default and range are there): the email plugin's needs_reply_days (3) and
145
+ # unsure_card_days (7), for example. A key no installed plugin declares is refused.
146
+ expiry:
147
+ prep_after_event: 0
148
+ event_after_end: 0
149
+ task_overdue_days: 3
150
+ bill_ask_days: 3
151
+ bill_overdue_digest_days: 7
152
+ inbox_notice_days: 3
153
+ reminder_missed_digests: 1
154
+
155
+ # Per-section knobs, e.g. {bills_due: {within_days: 7, line_cap: 5}}. `line_cap` is how
156
+ # many lines a section shows (Settings -> Digest writes it); chat writes the dues
157
+ # window and categories.
158
+ section_config:
159
+ # Top 3 per news group (9 headlines), top 5 for the other long lists; change any of
160
+ # them in Settings -> Digest ("lines").
161
+ news_ai: {line_cap: 3}
162
+ news_global: {line_cap: 3}
163
+ news_local: {line_cap: 3}
164
+ stocks: {line_cap: 5}
165
+ indexes: {line_cap: 5}
166
+ top_repos: {line_cap: 5}
167
+
168
+ # The digest's news, one section per group. Each topic becomes one research query
169
+ # ("<topic> news"); a title or topic may say {news_local_area}. Settings -> Digest edits
170
+ # each group's topics. `news_sources` and `news_language` below apply to all of them.
171
+ news_groups:
172
+ news_ai:
173
+ title: AI / Tech
174
+ topics: [AI, technology]
175
+ news_global:
176
+ title: Global
177
+ topics: [world]
178
+ news_local:
179
+ title: "Local — {news_local_area}"
180
+ topics: ["{news_local_area}"]
181
+
182
+ # The place the local news is about (Settings -> Digest).
183
+ news_local_area: St. Louis
184
+
185
+ # Topics for a news fetch that names no group (an ad-hoc `digest-topics` fetch); the
186
+ # digest's own news uses `news_groups` above.
187
+ news_topics:
188
+ - AI
189
+ - world
190
+
191
+ # Preferred source domains, ranked first when they have a story. Never a strict
192
+ # allowlist (D4): a topic with no story from these still shows the best others.
193
+ news_sources: []
194
+
195
+ # The language the news is in: a two-letter ISO 639-1 code, or `any`. Asked of the
196
+ # search provider where it can (DuckDuckGo region, SearXNG/Brave language) and checked
197
+ # on every headline (its writing script), so a Japanese headline never lands in an
198
+ # English digest. A topic whose every result is in another language counts as failed,
199
+ # so the digest names the section instead of printing it empty.
200
+ news_language: en
201
+
202
+ # Focus: the newest emails in these triage categories (ADR-0017 topic paths; a path
203
+ # matches itself and everything under it), minus senders marked "not useful". The
204
+ # newest `focus_per_account` from each inbox, then newest first across them, at most
205
+ # `focus_limit` in all (Settings -> Digest edits both).
206
+ focus_categories:
207
+ - email/personal
208
+ - email/family
209
+ - email/finance
210
+ - email/community
211
+ focus_limit: 10
212
+ focus_per_account: 5
213
+
214
+ # An old section name -> the section(s) that replaced it. Applies to the owner's saved
215
+ # settings whenever they are read (a saved `news` is the three news groups, on or off
216
+ # together) and to the brief_prefs.json move below. A section split into several
217
+ # leaves its per-section settings (lines) behind: each part takes this file's.
218
+ renamed_sections:
219
+ news: [news_ai, news_global, news_local]
220
+ ai_news: news_ai
221
+ global_news: news_global
222
+
223
+ # The one-time move of data/brief_prefs.json into the settings store.
224
+ # new_sections did not exist when that file was written, so its silence about them
225
+ # is not the owner turning them off.
226
+ # dropped_sections left off even when that file had them on (the old tool wrote
227
+ # every section on); the owner turns them back on in Settings.
228
+ brief_prefs_migration:
229
+ new_sections:
230
+ - focus
231
+ - judged_yesterday
232
+ - learned_yesterday
233
+ - missed_reminders
234
+ - needs_reply
235
+ - news_local
236
+ - overdue
237
+ dropped_sections:
238
+ - top_repos
@@ -0,0 +1,40 @@
1
+ # The corpus the `search_docs` tool may search (services/docs_search/). It is an
2
+ # ALLOW-LIST: the tool reads these directories and nothing else, and every path it
3
+ # opens is resolved and checked to sit inside one of them (symlinks and `..` refused).
4
+ # Nothing here can name the identity files (SOUL/USER/AGENTS), the vault, a .env, the
5
+ # user's data directories or any store: they are not under these roots, and a root that
6
+ # overlaps IRIS_HOME / the data or governance directories is refused at load.
7
+ #
8
+ # This shipped file is the allow-list. A docs_search.yaml under IRIS_CONFIG_DIR can only
9
+ # NARROW it (roots and extensions intersect, limits take the smaller value); a root it adds
10
+ # is ignored. Every root must be a plain relative path under docs/.
11
+ #
12
+ # Roots are relative to the source checkout and are shipped documentation only. The docs
13
+ # are not package data, so on an installed wheel none of them exist and the tool says
14
+ # "docs not present on this install" instead of searching anywhere else. Adding a root is
15
+ # a security decision: it must hold nothing the owner would not publish.
16
+ roots:
17
+ - docs/architecture # includes docs/architecture/adrs/ where present
18
+ - docs/concepts
19
+ - docs/guides
20
+ - docs/reference
21
+ - docs/usage-guides
22
+
23
+ # Only these file types are read, from inside the roots.
24
+ extensions:
25
+ - .md
26
+
27
+ # Bounded work: a runaway tree costs a capped, deterministic amount.
28
+ limits:
29
+ max_files: 400 # documents indexed; more are ignored (the result says so)
30
+ max_file_bytes: 400000 # a larger file is skipped, not truncated
31
+ max_total_bytes: 8000000 # across all documents
32
+ max_query_chars: 200
33
+ max_query_terms: 8
34
+ default_results: 5
35
+ max_results: 10
36
+ snippet_chars: 240
37
+ max_output_chars: 4000
38
+ scan_chunk_chars: 4000 # the secret scan sees a document in pieces of this size
39
+ scan_budget_ms: 2000 # a document that uses this up scanning is withheld
40
+ scan_total_ms: 10000 # per call; documents not yet scanned wait for the next call
@@ -0,0 +1,45 @@
1
+ # `iris doctor` -- the install preflight (OSS plan R5, milestone L1).
2
+ #
3
+ # Thresholds and the starter model set live here, not in code. The supported Python
4
+ # range is not repeated: doctor reads it from the installed package's metadata
5
+ # (pyproject's `python = ">=3.12,<3.14"`).
6
+
7
+ # Host memory, total (not free). Below `demo_gb` IRIS cannot run; between the two it
8
+ # runs the synthetic demo on the scripted model but not local models for real use.
9
+ ram:
10
+ floor_gb: 16
11
+ demo_gb: 8
12
+
13
+ # Where IRIS runs (platform.system() / platform.machine(), lowercased). Anything else
14
+ # is a warning; native Windows is refused with a pointer to WSL2.
15
+ platforms:
16
+ darwin: [arm64]
17
+ linux: [x86_64, amd64, aarch64, arm64]
18
+
19
+ # Free space on the volume under IRIS_HOME: the missing starter models' size (below)
20
+ # plus this much for data (mail stores, indexes, the audit ledger). Below that is a
21
+ # failure; below `warn_free_gb` a warning.
22
+ disk:
23
+ data_headroom_gb: 2
24
+ warn_free_gb: 20
25
+
26
+ # The starter model set: what `iris doctor --fix` pulls when it is missing. R5 plans a
27
+ # single-model `starter` set gated on the models-by-capability ADR's proof (draft, not
28
+ # merged); until that lands the fallback starter is `qwen2.5:7b-instruct` alone.
29
+ # `size_gb` is the download size shown before a pull (Ollama's API cannot say it before
30
+ # the pull starts).
31
+ starter_models:
32
+ - name: qwen2.5:7b-instruct
33
+ size_gb: 4.7
34
+
35
+ # Optional extras: reported as information, never a failure. `module` is what is
36
+ # importable when the extra is installed.
37
+ optional_extras:
38
+ # Without it the Gmail plugin does not load, so an unnamed run stays on the `default`
39
+ # profile and there is no `iris email` (config/profiles/default.yaml).
40
+ - name: email
41
+ module: googleapiclient
42
+ purpose: the email assistant (`iris email`, Gmail)
43
+ - name: ml
44
+ module: sentence_transformers
45
+ purpose: semantic email discovery and BGE rerank
@@ -0,0 +1,74 @@
1
+ # Tier-escalation judge (ADR-0068, docs/architecture/escalation-judge.md).
2
+ #
3
+ # A Response Curator head that, after a cheap Tier-1 answer, DIAGNOSES why the
4
+ # answer fell short and decides the next course — escalate to a stronger tier,
5
+ # clarify with the user, or reroute to a tool. YAML-first: thresholds and
6
+ # budgets are policy, not code.
7
+ #
8
+ # Rollout discipline mirrors the governance enforce flips: ship in `shadow`
9
+ # (decide + log + record the counterfactual, never act), validate that the
10
+ # decision tracks real outcomes, only then flip to `enforce`.
11
+ #
12
+ # enforce mode acts on all three diagnoses: escalate (capability_gap -> re-run at
13
+ # a stronger LOCAL tier), reroute (grounding_gap -> re-run same tier with a
14
+ # grounding/tool directive), clarify (ambiguity -> ask the user, gated by
15
+ # clarify_confidence_floor). Bounded by max_escalations + resource-governor veto,
16
+ # egress-safe (local tiers only). Default mode keeps all acting off until an
17
+ # operator flips it after reviewing shadow precision.
18
+ version: 1
19
+
20
+ # Master opt-in. The env flag IRIS_CURATOR_ESCALATION overrides this (matching
21
+ # the IRIS_CURATOR_* judge family). Default off so normal chat is unaffected.
22
+ enabled: false
23
+
24
+ # shadow = decide + log + record, never act.
25
+ # enforce = act on escalate, reroute and clarify (live, L3), each confidence-gated.
26
+ mode: shadow
27
+
28
+ # Hops above the start tier allowed per turn when acting. Bounded retry, never an
29
+ # unbounded "judge says escalate" loop.
30
+ max_escalations: 1
31
+
32
+ # The judge model tier — must be >= the generator tier (judge a Tier-1 output
33
+ # with a Tier-2 judge); the judge never both generates and promotes its output.
34
+ # The judge is built from this tier; if it is missing from llm_tiers.yaml the
35
+ # judge is off rather than falling back to a weaker model.
36
+ judge_tier: tier2
37
+
38
+ # Fraction of judged turns the shadow judge evaluates (cost control for the
39
+ # shadow data-collection pass). 1.0 = every judged turn.
40
+ sample_rate: 1.0
41
+
42
+ # clarify fires only above this confidence; asking too often is worse than a
43
+ # mediocre answer, so prefer escalate/reroute when the answer is knowable.
44
+ clarify_confidence_floor: 0.7
45
+
46
+ # escalate / reroute act only at or above this confidence. Both re-run the plan and
47
+ # replace the answer, so a verdict the judge itself is unsure of must not act.
48
+ action_confidence_floor: 0.7
49
+
50
+ # Defer to the governance cost cap + resource-governor veto when acting (L3+).
51
+ cost_aware: true
52
+
53
+ # L5 predictive start-tier priors. The escalation-priors tick mines
54
+ # escalation_shadow history per intent; an intent that reliably escalates gets
55
+ # its START tier raised so routing is predictive, not reactive. Env override:
56
+ # IRIS_CURATOR_ESCALATION_PRIORS. When disabled the recommendations are computed
57
+ # and logged (shadow) but NOT applied to the router — same shadow -> validate ->
58
+ # enforce discipline.
59
+ priors:
60
+ enabled: false
61
+ min_samples: 20 # per-intent turns before a prior is trusted
62
+ window_hours: 168 # history window mined for the rate (1 week)
63
+ escalate_rate: 0.4 # bump start tier when escalate-rate clears this
64
+
65
+ # Cloud escalation (ADR-0068 D4). OFF by default: escalation targets local tiers
66
+ # only, so personal/secret content can never leave the box. When enabled,
67
+ # escalation MAY target a cloud tier — but only when the content being sent
68
+ # classifies into `classifications` (the data classifier runs on the prompt +
69
+ # answer + memory context). `secret` is NEVER eligible, even if listed. The
70
+ # governance kernel's egress gate remains the final backstop. Env override:
71
+ # IRIS_CURATOR_ESCALATION_CLOUD.
72
+ cloud:
73
+ allow: false
74
+ classifications: [public] # widen to [public, internal] only after review; secret never
@@ -0,0 +1,26 @@
1
+ # Where each data class may be sent: the egress gate's policy (EgressGate, PreLLMCall;
2
+ # docs/architecture/unified-governance-layer.md §6.3). Read once, when the kernel is built.
3
+ #
4
+ # The tiers mean where a model runs, never what it is called (llm/locality.py): tier_1 and
5
+ # tier_2 are models on the owner's machines (a provider declared `runs: local` in
6
+ # llm_tiers.yaml), tier_3 leaves them (`runs: cloud`, or undeclared). "Local" includes a
7
+ # host the owner controls reached over the owner's own tailnet -- the cloud VM uses the
8
+ # Mac's Ollama that way -- never a third party's service.
9
+ #
10
+ # max_tier the furthest tier a prompt of this class may reach
11
+ # on_violation what a call beyond it gets: deny | require_approval (default deny)
12
+ #
13
+ # secret is local only (owner, 2026-09-30): any local model, never tier_3, and a violation
14
+ # is always a hard deny. The loader refuses a table that loosens that, so no edit here can
15
+ # send a secret off the owner's machines.
16
+ classes:
17
+ secret:
18
+ max_tier: tier_2
19
+ on_violation: deny
20
+ personal:
21
+ max_tier: tier_2
22
+ on_violation: require_approval
23
+ internal:
24
+ max_tier: tier_3
25
+ public:
26
+ max_tier: tier_3
@@ -0,0 +1,49 @@
1
+ # Owner identity policy (ADR-0125; docs/architecture/owner-pii-masking.md).
2
+ #
3
+ # ontology_kinds: which attributes of the owner's CONFIRMED memory facts are the owner's
4
+ # identity, and as which kind (name, email, phone, address, handle, link). Only statements
5
+ # whose subject is the owner count, so a contact's name never becomes owner PII. The keys
6
+ # are attributes of config/memory/ontology.yaml; this mapping lives here, never in the
7
+ # ontology (memris refuses unknown keys and knows no IRIS vocabulary).
8
+ #
9
+ # blog and website are `link`: egress refuses to send a link, so a confirmed blog or
10
+ # website joins what it refuses (ADR-0125 amendment 6).
11
+ ontology_kinds:
12
+ name: name
13
+ nickname: name
14
+ email: email
15
+ phone: phone
16
+ github: handle
17
+ linkedin: handle
18
+ blog: link
19
+ website: link
20
+
21
+ # guards: what each guard does with an occurrence of each kind (owner, 2026-09-30).
22
+ #
23
+ # egress network tool arguments deny | log | pass
24
+ # answer_owner an answer to the owner halt | mask | pass
25
+ # answer_other an answer anyone else reads halt | mask | pass
26
+ # capability a capability result mask | pseudonym | pass
27
+ # tier3 a prompt to a tier-3 model placeholder | pass
28
+ # web_search web-search arguments deny | mask | pass
29
+ #
30
+ # pseudonym: the consumer sees [owner:<kind>#<n>] unless its manifest grants the kind
31
+ # (capabilities: uses: - <capability>: {unmask: [<kind>, ...]}). secret is masked and never
32
+ # unmasked. Only the capability column acts in PR 3; PR 4 audits the rest in shadow.
33
+ guards:
34
+ kinds:
35
+ secret: {egress: deny, answer_owner: halt, answer_other: halt, capability: mask, tier3: placeholder, web_search: deny}
36
+ link: {egress: deny, answer_owner: pass, answer_other: pass, capability: pass, tier3: pass, web_search: deny}
37
+ name: {egress: log, answer_owner: pass, answer_other: mask, capability: pseudonym, tier3: pass, web_search: mask}
38
+ email: {egress: deny, answer_owner: pass, answer_other: mask, capability: pseudonym, tier3: placeholder, web_search: deny}
39
+ phone: {egress: deny, answer_owner: pass, answer_other: mask, capability: pseudonym, tier3: placeholder, web_search: deny}
40
+ address: {egress: deny, answer_owner: pass, answer_other: mask, capability: pseudonym, tier3: placeholder, web_search: deny}
41
+ handle: {egress: log, answer_owner: pass, answer_other: mask, capability: pseudonym, tier3: pass, web_search: mask}
42
+ # A name literal of one word (a first name, a nickname): masked only in web-search
43
+ # arguments, and it never denies or halts anywhere (ADR-0125 decision 4).
44
+ first_name_alone: {egress: log, answer_owner: pass, answer_other: pass, capability: pass, tier3: pass, web_search: mask}
45
+ # Network tools (fnmatch) where an egress deny of these kinds is only logged, until a
46
+ # per-destination allowlist exists. Never secret or link: egress refuses both today.
47
+ log_only_destinations:
48
+ tools: ["github_*", "mcp_*"]
49
+ kinds: [email, phone, address]
@@ -0,0 +1,18 @@
1
+ # `iris mcp serve`: the MCP clients the owner serves IRIS's tools to
2
+ # (src/iris_harness/runtime/mcp_serve.py; examples/08-mcp).
3
+ #
4
+ # `iris mcp serve --client NAME` must name a client listed here; every call is governed
5
+ # and audited as `mcp:NAME`. The name is the owner's (it sits in the client's config the
6
+ # owner writes); what a client says about itself decides nothing.
7
+ #
8
+ # local: true -- the client runs on this machine and the owner accepts that results
9
+ # holding their personal data reach it.
10
+ # local: false -- (the default) a result labelled personal is withheld from it.
11
+ # A result labelled secret is withheld from every client, local or not.
12
+ #
13
+ # The owner's own list goes in $IRIS_HOME/mcp-serve.yaml (same shape); its entries win
14
+ # over these.
15
+ clients:
16
+ # The default when --client is not given: treated as not local.
17
+ stdio:
18
+ local: false
@@ -0,0 +1,11 @@
1
+ # MCP server signing policy (Governance Phase 6 supply-chain workstream).
2
+ # See docs/architecture/mcp-server-signing.md.
3
+ # Sub-phase 6b.1 ships the loader; the bridge gate + enforcement land in 6b.2+.
4
+ version: 1
5
+ enabled: true
6
+ # shadow = verify + audit but never block; flip to enforce once your servers are
7
+ # signed and the audit is clean (see the doc's enforce-flip runbook).
8
+ mode: shadow
9
+ # Action under enforce for an unsigned / untrusted / invalid server.
10
+ unsigned_policy: warn
11
+ trust_store: config/governance/mcp-trust.yaml
@@ -0,0 +1,12 @@
1
+ # Root of trust for MCP server signatures (operator-managed).
2
+ # The IRIS agent process must NOT have write access to this file.
3
+ # Add public keys with `iris mcp keygen --id <key_id>` (CLI lands in 6b.3),
4
+ # then sign servers with `iris mcp sign <server> --key <key_id>`.
5
+ version: 1
6
+ keys: []
7
+ # Example (do not use this fabricated key):
8
+ # - key_id: ops-2026
9
+ # public_key: <base64 ed25519 public key>
10
+ # comment: "primary signing key"
11
+ revoked_key_ids: []
12
+ revoked_signatures: []
@@ -0,0 +1,13 @@
1
+ # Sandbox runtime selection (Governance Phase 6 hardening workstream).
2
+ # See docs/architecture/sandbox-hardening.md.
3
+ # Default runtime: docker → today's behavior unchanged. gVisor lands in 6c.2;
4
+ # Firecracker is evaluated/deferred. gVisor/Firecracker are Linux-only — on
5
+ # macOS the runtime check fails and falls back to docker.
6
+ version: 1
7
+ runtime: docker # docker | gvisor | firecracker (IRIS_SANDBOX_RUNTIME overrides)
8
+ on_unavailable: fallback # fallback (→ docker, logged) | disable (no code_exec)
9
+ limits:
10
+ memory: 1g
11
+ cpus: "2"
12
+ pids_limit: 256
13
+ timeout_seconds: 30
@@ -0,0 +1,18 @@
1
+ # Tools that need the owner's approval for a call made AFTER the run read outside text
2
+ # (issue #149).
3
+ #
4
+ # Outside text is the result of any tool that declares `content: external` (a web page, an
5
+ # email, a document, an MCP server's answer). Redaction of instruction-like phrases is
6
+ # phrase-level, so a model that read such text can still be steered toward a harmful action.
7
+ # A write to memory is the realistic sink: a poisoned fact outlives the turn. So in a run that
8
+ # has an external observation, a call of a tool listed here is held for the owner's
9
+ # approval on the same card the other approved-per-call tools use, and says why. The same
10
+ # call in a run that read nothing from outside is unchanged. The next user message starts a
11
+ # clean run.
12
+ #
13
+ # Names only, no wildcards. A file that is missing, unreadable or malformed falls back to
14
+ # the three tools below; removing a name here is the owner's decision.
15
+ approval_when_tainted:
16
+ - memory_correct
17
+ - memory_forget
18
+ - memory_restore