ithrl 0.1.0__tar.gz → 0.3.0__tar.gz

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 (178) hide show
  1. {ithrl-0.1.0 → ithrl-0.3.0}/.gitignore +1 -0
  2. ithrl-0.3.0/CHANGELOG.md +70 -0
  3. {ithrl-0.1.0 → ithrl-0.3.0}/CONTRIBUTING.md +153 -46
  4. ithrl-0.3.0/PKG-INFO +167 -0
  5. ithrl-0.3.0/README.md +134 -0
  6. ithrl-0.3.0/ROADMAP.md +142 -0
  7. ithrl-0.3.0/docs/architecture.md +306 -0
  8. ithrl-0.3.0/docs/branding/branding.css +39 -0
  9. ithrl-0.3.0/docs/branding/ithrl-favicon.svg +16 -0
  10. ithrl-0.3.0/docs/branding/ithrl-icon.svg +12 -0
  11. ithrl-0.3.0/docs/branding/ithrl-logo-dark.svg +21 -0
  12. ithrl-0.3.0/docs/branding/ithrl-logo-light.svg +21 -0
  13. ithrl-0.3.0/docs/branding/ithrl-logo.png +0 -0
  14. ithrl-0.3.0/docs/branding/ithrl-social.png +0 -0
  15. {ithrl-0.1.0 → ithrl-0.3.0}/docs/cli.md +75 -0
  16. ithrl-0.3.0/docs/decisions/0001-native-evidence-and-controlled-runners.md +82 -0
  17. ithrl-0.3.0/docs/decisions/0002-fixed-samples-and-durable-dispatch.md +122 -0
  18. ithrl-0.3.0/docs/decisions/0003-strict-fresh-baselines.md +71 -0
  19. ithrl-0.3.0/docs/decisions/0004-single-finding-fuzz-confirmation.md +80 -0
  20. ithrl-0.3.0/docs/decisions/index.md +21 -0
  21. ithrl-0.3.0/docs/index.md +47 -0
  22. ithrl-0.3.0/docs/measurements.md +403 -0
  23. ithrl-0.3.0/docs/native-runs.md +515 -0
  24. ithrl-0.3.0/docs/research/context-fuzzing.md +345 -0
  25. ithrl-0.3.0/docs/research/feasibility.md +195 -0
  26. ithrl-0.3.0/docs/research/index.md +32 -0
  27. ithrl-0.3.0/docs/research/ordinary-session-investigation.md +112 -0
  28. ithrl-0.3.0/docs/research/reduction-design.md +488 -0
  29. ithrl-0.3.0/docs/results.md +251 -0
  30. {ithrl-0.1.0 → ithrl-0.3.0}/docs/third-party-notices.txt +5 -0
  31. ithrl-0.3.0/docs/troubleshooting.md +155 -0
  32. ithrl-0.3.0/examples/fuzz/campaign.toml +37 -0
  33. ithrl-0.3.0/examples/fuzz/codex.jsonl +7 -0
  34. ithrl-0.3.0/examples/fuzz/copilot.jsonl +9 -0
  35. {ithrl-0.1.0 → ithrl-0.3.0}/pyproject.toml +57 -6
  36. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/_jsonl.py +30 -27
  37. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/codex/context.py +53 -28
  38. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/contracts.py +39 -2
  39. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/copilot/context.py +102 -36
  40. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/registry.py +60 -1
  41. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/behavior.py +27 -2
  42. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/calibration.py +166 -30
  43. ithrl-0.3.0/src/ithrl/case/evidence.py +309 -0
  44. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/__init__.py +66 -16
  45. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/extract.py +75 -7
  46. ithrl-0.3.0/src/ithrl/cli/fuzz.py +464 -0
  47. ithrl-0.3.0/src/ithrl/cli/fuzz_output.py +310 -0
  48. ithrl-0.3.0/src/ithrl/cli/fuzz_run.py +438 -0
  49. ithrl-0.3.0/src/ithrl/cli/fuzz_session.py +233 -0
  50. ithrl-0.3.0/src/ithrl/cli/inspect.py +179 -0
  51. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/native.py +46 -3
  52. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/output.py +52 -6
  53. ithrl-0.3.0/src/ithrl/cli/progress.py +62 -0
  54. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/sampled.py +83 -4
  55. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/sampled_output.py +76 -0
  56. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/sampled_reduction.py +143 -115
  57. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/sampled_session.py +22 -69
  58. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/shrink.py +6 -32
  59. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/context.py +3 -2
  60. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/execution/budget.py +19 -11
  61. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/execution/contracts.py +6 -2
  62. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/execution/preflight.py +14 -4
  63. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/experiment.py +96 -1
  64. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/extraction.py +40 -7
  65. ithrl-0.3.0/src/ithrl/fuzz/__init__.py +10 -0
  66. ithrl-0.3.0/src/ithrl/fuzz/campaign.py +534 -0
  67. ithrl-0.3.0/src/ithrl/fuzz/configuration.py +77 -0
  68. ithrl-0.3.0/src/ithrl/fuzz/contracts.py +118 -0
  69. ithrl-0.3.0/src/ithrl/fuzz/deterministic.py +90 -0
  70. ithrl-0.3.0/src/ithrl/fuzz/generation.py +55 -0
  71. ithrl-0.3.0/src/ithrl/fuzz/progress.py +117 -0
  72. ithrl-0.3.0/src/ithrl/fuzz/sampling.py +232 -0
  73. ithrl-0.3.0/src/ithrl/fuzz/simplify.py +96 -0
  74. ithrl-0.3.0/src/ithrl/fuzz/statistics.py +91 -0
  75. ithrl-0.3.0/src/ithrl/inspection.py +778 -0
  76. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/measurement.py +2 -0
  77. ithrl-0.3.0/src/ithrl/mutation.py +180 -0
  78. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/observations.py +72 -26
  79. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/reduce/__init__.py +2 -0
  80. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/reduce/contracts.py +366 -31
  81. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/reduce/engine.py +248 -25
  82. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/reduce/search.py +52 -50
  83. ithrl-0.3.0/src/ithrl/results/inspection.py +382 -0
  84. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/results/models.py +9 -4
  85. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/results/storage.py +23 -35
  86. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/results/summary.py +5 -18
  87. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/results/validation.py +44 -4
  88. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/run_state.py +160 -32
  89. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/capability.py +20 -49
  90. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/configuration.py +29 -6
  91. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/isolation.py +18 -55
  92. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/materialize.py +152 -60
  93. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/policy.py +3 -3
  94. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/protocol.py +76 -38
  95. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/protocol_contracts.py +8 -1
  96. ithrl-0.3.0/src/ithrl/runner/codex/relay.py +403 -0
  97. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/runner.py +75 -19
  98. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/runtime_configuration.py +28 -13
  99. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/schema.py +1 -13
  100. ithrl-0.3.0/src/ithrl/runner/codex/transcript.py +288 -0
  101. ithrl-0.3.0/src/ithrl/runner/codex/worker.py +334 -0
  102. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/contracts.py +47 -2
  103. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/capability.py +55 -200
  104. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/configuration.py +3 -1
  105. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/isolation.py +72 -76
  106. ithrl-0.3.0/src/ithrl/runner/copilot/materialize.py +299 -0
  107. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/policy.py +11 -39
  108. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/protocol/__init__.py +1 -2
  109. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/protocol/contracts.py +21 -2
  110. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/protocol/decoding.py +3 -1
  111. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/protocol/parser.py +243 -85
  112. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/protocol/state.py +14 -10
  113. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/runner.py +47 -28
  114. ithrl-0.3.0/src/ithrl/runner/copilot/sdk_runtime.py +138 -0
  115. ithrl-0.3.0/src/ithrl/runner/copilot/worker.py +678 -0
  116. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/evidence.py +52 -10
  117. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/fake.py +3 -1
  118. ithrl-0.3.0/src/ithrl/runner/runtime/certificates.py +58 -0
  119. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/contracts.py +2 -0
  120. ithrl-0.3.0/src/ithrl/runner/runtime/probes.py +49 -0
  121. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/process.py +35 -23
  122. ithrl-0.3.0/src/ithrl/runner/runtime/programs.py +75 -0
  123. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/protection.py +9 -0
  124. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/validation.py +15 -21
  125. ithrl-0.3.0/src/ithrl/sampled_run_metadata.py +87 -0
  126. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/sampling.py +63 -16
  127. ithrl-0.3.0/src/ithrl/text_sections.py +218 -0
  128. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/workflow.py +105 -16
  129. ithrl-0.1.0/CHANGELOG.md +0 -80
  130. ithrl-0.1.0/PKG-INFO +0 -118
  131. ithrl-0.1.0/README.md +0 -89
  132. ithrl-0.1.0/docs/index.md +0 -23
  133. ithrl-0.1.0/docs/measurements.md +0 -86
  134. ithrl-0.1.0/docs/native-runs.md +0 -150
  135. ithrl-0.1.0/docs/results.md +0 -105
  136. ithrl-0.1.0/docs/troubleshooting.md +0 -73
  137. ithrl-0.1.0/src/ithrl/case/evidence.py +0 -169
  138. ithrl-0.1.0/src/ithrl/runner/codex/transcript.py +0 -130
  139. ithrl-0.1.0/src/ithrl/runner/codex/worker.py +0 -175
  140. ithrl-0.1.0/src/ithrl/runner/copilot/materialize.py +0 -484
  141. ithrl-0.1.0/src/ithrl/runner/copilot/worker.py +0 -351
  142. {ithrl-0.1.0 → ithrl-0.3.0}/LICENSE +0 -0
  143. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/__init__.py +0 -0
  144. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/__main__.py +0 -0
  145. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/__init__.py +0 -0
  146. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/codex/__init__.py +0 -0
  147. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/codex/decisions.py +0 -0
  148. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/codex/discovery.py +0 -0
  149. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/codex/parser.py +0 -0
  150. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/copilot/__init__.py +0 -0
  151. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/copilot/decisions.py +0 -0
  152. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/copilot/discovery.py +0 -0
  153. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/copilot/parser.py +0 -0
  154. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/discovery.py +0 -0
  155. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/adapters/errors.py +0 -0
  156. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/__init__.py +0 -0
  157. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/contracts.py +0 -0
  158. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/filesystem.py +0 -0
  159. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/source.py +0 -0
  160. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/source_context.py +0 -0
  161. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/source_storage.py +0 -0
  162. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/case/storage.py +0 -0
  163. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/cli/paths.py +0 -0
  164. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/decisions.py +0 -0
  165. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/examples/synthetic-trace.json +0 -0
  166. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/execution/__init__.py +0 -0
  167. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/path_safety.py +0 -0
  168. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/results/__init__.py +0 -0
  169. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/__init__.py +0 -0
  170. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/codex/__init__.py +0 -0
  171. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/copilot/__init__.py +0 -0
  172. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/registry.py +0 -0
  173. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/__init__.py +0 -0
  174. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/output.py +0 -0
  175. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/runner/runtime/state.py +0 -0
  176. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/statistics.py +0 -0
  177. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/synthetic.py +0 -0
  178. {ithrl-0.1.0 → ithrl-0.3.0}/src/ithrl/timestamps.py +0 -0
@@ -4,6 +4,7 @@ __pycache__/
4
4
  *.py[cod]
5
5
  .pytest_cache/
6
6
  .ruff_cache/
7
+ .rumdl_cache/
7
8
  .hypothesis/
8
9
  .pyrefly/
9
10
  .coverage
@@ -0,0 +1,70 @@
1
+ # CHANGELOG
2
+
3
+ ## v0.3.0 (2026-11-10)
4
+
5
+ ### Features
6
+
7
+ - Add finer final-response reduction ([#52](https://github.com/eberkut/ithrl/pull/52), [`562124a`](https://github.com/eberkut/ithrl/commit/562124ab071788a52e0d50dd538048ee67de464b))
8
+ - Define source-bound text-section removal ([#51](https://github.com/eberkut/ithrl/pull/51), [`56c9e6c`](https://github.com/eberkut/ithrl/commit/56c9e6cfb24a83dc32573232b447e574cb0f616f))
9
+ - Inspect retained context without provider calls ([#49](https://github.com/eberkut/ithrl/pull/49), [`5604688`](https://github.com/eberkut/ithrl/commit/5604688e269543305fe4b7b253a703dc404c1139))
10
+ - **reduce**: Qualify paragraph removal on ordinary sessions ([#58](https://github.com/eberkut/ithrl/pull/58), [`5c6ae26`](https://github.com/eberkut/ithrl/commit/5c6ae26760ea7bd94b406ebf9ba3214e5c4ce64c))
11
+
12
+ ### Refactoring
13
+
14
+ - Simplify experiment workflows and test fixtures ([#50](https://github.com/eberkut/ithrl/pull/50), [`782bfa2`](https://github.com/eberkut/ithrl/commit/782bfa2692a49a5bb2a4f555801abda23cde6fda))
15
+
16
+ ## v0.2.0 (2026-11-02)
17
+
18
+ ### Bug Fixes
19
+
20
+ - **codex**: Bound and account for physical provider requests ([#33](https://github.com/eberkut/ithrl/pull/33), [`88529d6`](https://github.com/eberkut/ithrl/commit/88529d6f8b930dbcc546a0011f085c67d0bef1ac))
21
+ - **copilot**: Recover catalogue connections and qualify fuzzing ([#37](https://github.com/eberkut/ithrl/pull/37), [`ff6cf63`](https://github.com/eberkut/ithrl/commit/ff6cf6324325f7f6dad8f8c9c80ea58bfe4e249a))
22
+ - **copilot**: Restore native session prefixes through the CLI ([#34](https://github.com/eberkut/ithrl/pull/34), [`36845dd`](https://github.com/eberkut/ithrl/commit/36845ddb8239c0a488552297aaa70e6211979e59))
23
+ - **fuzz**: Preserve accounting and validate campaign recovery ([#25](https://github.com/eberkut/ithrl/pull/25), [`f1f4793`](https://github.com/eberkut/ithrl/commit/f1f479318fe914f3033667b65381f7101bd3aaea))
24
+ - **sampling**: Enforce calibration budgets and report durable progress ([#32](https://github.com/eberkut/ithrl/pull/32), [`bd40577`](https://github.com/eberkut/ithrl/commit/bd40577c734d70b36e59a9e6d3babafa1502bfd3))
25
+
26
+ ### Features
27
+
28
+ - **extract**: Support literal predicates for native decisions ([#31](https://github.com/eberkut/ithrl/pull/31), [`3b18c2b`](https://github.com/eberkut/ithrl/commit/3b18c2bdd814c4e4c3bf79825a8cab77eb433661))
29
+ - **fuzz**: Add mutation and sampled comparison services ([`56ee8b8`](https://github.com/eberkut/ithrl/commit/56ee8b8c5e1370b91db6c9c952eb8ceec19c95ae))
30
+ - **fuzz**: Expose inspectable campaigns and saved results ([#24](https://github.com/eberkut/ithrl/pull/24), [`e60e472`](https://github.com/eberkut/ithrl/commit/e60e47230b99e50ff42de7cd8fb89b3769e6d6e2))
31
+ - **fuzz**: Persist campaigns and recover interrupted execution ([#22](https://github.com/eberkut/ithrl/pull/22), [`806667f`](https://github.com/eberkut/ithrl/commit/806667f47e8bae1ccbf9b32fadc511ca559675d0))
32
+ - **fuzz**: Qualify native Codex text appends ([#28](https://github.com/eberkut/ithrl/pull/28), [`a5b880b`](https://github.com/eberkut/ithrl/commit/a5b880b60ef9834bb57b2c4950e18cd17ff0b275))
33
+
34
+ ### Performance Improvements
35
+
36
+ - Streamline local workflows and harden result publication ([#36](https://github.com/eberkut/ithrl/pull/36), [`43b9d81`](https://github.com/eberkut/ithrl/commit/43b9d81d0dcff85708da5c914986a68bbe8141db))
37
+
38
+ ## v0.1.0 (2026-10-23)
39
+
40
+ ### Bug Fixes
41
+
42
+ - **adapters**: Detect saved session formats structurally ([`c8256b9`](https://github.com/eberkut/ithrl/commit/c8256b93ce79fb9c3f025e2b92a970f336497218))
43
+ - **reduce**: Validate native candidates before sampled dispatch ([`90d4c0d`](https://github.com/eberkut/ithrl/commit/90d4c0d11a206389d44c6a59991df53c19802514))
44
+ - **runner**: Clarify Codex isolation prerequisites ([`4a409c1`](https://github.com/eberkut/ithrl/commit/4a409c1f37caf301a00cfbd20d3a95cf15844eb9))
45
+
46
+ ### Features
47
+
48
+ - Establish credential-free context reduction core ([`c517409`](https://github.com/eberkut/ithrl/commit/c517409c06e40c92b24a8b990685abd4acc9a9ba))
49
+ - **adapters**: Parse Codex and Copilot session evidence ([`3b81c26`](https://github.com/eberkut/ithrl/commit/3b81c2607397d884bcfb1b19dbf995f66ccb0107))
50
+ - **calibration**: Add bounded sampled runner calibration ([`f9db180`](https://github.com/eberkut/ithrl/commit/f9db18012565badc2cf2a3a4a6158487d4c5fb70))
51
+ - **case**: Preserve immutable native source evidence ([`d108b96`](https://github.com/eberkut/ithrl/commit/d108b96487ccb69f6b36642ae331d36272038722))
52
+ - **cli**: Add an installed example and focused public guides ([`1efc2ff`](https://github.com/eberkut/ithrl/commit/1efc2ffb03c734b666b1d1da9b5610ad62970267))
53
+ - **cli**: Add guarded native calibration ([`06d2bfb`](https://github.com/eberkut/ithrl/commit/06d2bfb3f4d34f4dc845d9d6877257e4e79f9120))
54
+ - **cli**: Integrate sampled reduction and exact resume ([`40be766`](https://github.com/eberkut/ithrl/commit/40be7664ba90ac5341d93fb5a725dbfa0efd48d3))
55
+ - **extract**: Support ordinary Codex and Copilot sessions ([`3cd0c10`](https://github.com/eberkut/ithrl/commit/3cd0c1092aeb3669b86fdae07e887d28ba9d685f))
56
+ - **reduce**: Add sampled contracts and durable progress ([`650252d`](https://github.com/eberkut/ithrl/commit/650252d76e8d7d72f3f5715ecaf488e752dc18b1))
57
+ - **reduce**: Integrate sampled candidate search ([`72958d8`](https://github.com/eberkut/ithrl/commit/72958d8d6ae0307ca2d090a2a10d02606bafdea6))
58
+ - **runner**: Add Codex final-response execution ([`ad30a9a`](https://github.com/eberkut/ithrl/commit/ad30a9a17b0e665056eca9b415cbf4e2770a7bf7))
59
+ - **runner**: Add controlled Copilot execution ([`c9d1bb2`](https://github.com/eberkut/ithrl/commit/c9d1bb23bfdd98bb022fd0b62ca9b8a81021fe4b))
60
+ - **runner**: Add isolated execution runtime ([`17d2224`](https://github.com/eberkut/ithrl/commit/17d22240414cdb32d4464f16e7b2621d99729ca0))
61
+ - **runner**: Add shared execution foundation ([`89536e9`](https://github.com/eberkut/ithrl/commit/89536e919730fc0abf680a2928a89761c78339f5))
62
+ - **runner**: Validate isolated native calibration ([`b0cd438`](https://github.com/eberkut/ithrl/commit/b0cd438d1fa280f0ddafa39d23653a7ac926da1b))
63
+ - **sampling**: Collect bounded fresh-baseline blocks ([`16abf30`](https://github.com/eberkut/ithrl/commit/16abf30b964eae299177d1e1dade6f545ffbda31))
64
+ - **sampling**: Support paced execution and safe overload replacement ([`5d70fbd`](https://github.com/eberkut/ithrl/commit/5d70fbd26901a0574883e07fd4055644c8515e80))
65
+ - **statistics**: Add fixed-sample candidate classification ([`fb26fca`](https://github.com/eberkut/ithrl/commit/fb26fcaf7c064f49ac7d63b4e2ceb1ab3d6dcdb5))
66
+ - **workflow**: Confirm sampled reductions with fresh evidence ([`ee291e4`](https://github.com/eberkut/ithrl/commit/ee291e4d906394452da61640989cef594f62caf7))
67
+
68
+ ### Refactoring
69
+
70
+ - Simplify execution paths and avoid redundant context copies ([`34ab361`](https://github.com/eberkut/ithrl/commit/34ab36165fed08678a80679b3f1753e6f26f63f8))
@@ -1,19 +1,37 @@
1
1
  # Contributing
2
2
 
3
- Start with an [issue](https://github.com/eberkut/ithrl/issues) describing the problem or proposed
4
- change. Pull requests are limited to collaborators; discuss the work before preparing one.
3
+ Open an [issue](https://github.com/eberkut/ithrl/issues) for a bug report, question or proposed
4
+ change. Pull requests are limited to collaborators. If you are not a collaborator and want to
5
+ implement a change, agree on scope and ask the maintainer about access in the issue before preparing
6
+ a PR.
5
7
 
6
8
  For bug reports, include the ithrl version, platform, sanitized error code and steps to reproduce.
7
9
  Keep full sessions, cases, proprietary source and credentials out of public reports. Report
8
- suspected vulnerabilities through [private vulnerability reporting](https://github.com/eberkut/ithrl/security/advisories/new).
10
+ suspected vulnerabilities through
11
+ [private vulnerability reporting](https://github.com/eberkut/ithrl/security/advisories/new).
12
+
13
+ ## First contribution
14
+
15
+ 1. Find an existing issue or open one, and agree on scope with the maintainer.
16
+ 2. Follow [development setup](#development-setup) to prepare the locked environment.
17
+ 3. Make a focused change using [Preparing a change](#preparing-a-change), and run the relevant
18
+ [checks](#checks).
19
+ 4. Open a PR linking the issue and explaining the change and its validation. Follow the
20
+ [review requirements](#pull-request-review).
21
+
22
+ For task-specific instructions, see [documentation](#documentation),
23
+ [workflows and dependencies](#workflow-and-dependency-checks),
24
+ [integration tests](#credential-free-integration-tests) or
25
+ [native smoke tests](#opt-in-native-smoke-tests).
9
26
 
10
27
  ## Development setup
11
28
 
12
- Use [uv](https://docs.astral.sh/uv/) and Python 3.12, 3.13 or 3.14. Python 3.14 is the primary
13
- development version. From the repository root:
29
+ Use [uv](https://docs.astral.sh/uv/) at the version required by `tool.uv.required-version` in
30
+ `pyproject.toml`, and Python 3.12, 3.13 or 3.14. CI reads the same uv pin through `setup-uv`'s
31
+ `version-file` input. Python 3.14 is the primary development version. From the repository root:
14
32
 
15
33
  ```bash
16
- uv sync --locked --all-groups
34
+ uv sync --locked --all-groups --all-extras
17
35
  uv run ithrl --help
18
36
  ```
19
37
 
@@ -28,6 +46,8 @@ Run the same entry points used by CI:
28
46
  uv lock --check
29
47
  uv run ruff check .
30
48
  uv run ruff format --check .
49
+ uv run rumdl fmt --check .
50
+ uv run rumdl check .
31
51
  uv run pyrefly check
32
52
  uv run pytest --ignore=tests/packaging
33
53
  uv run radon cc src/ithrl --min B --show-complexity --total-average
@@ -36,7 +56,8 @@ uv build --sdist --wheel --no-sources
36
56
  ITHRL_DIST_DIR=dist uv run pytest -o addopts= tests/packaging
37
57
  ```
38
58
 
39
- Non-packaging tests and the synthetic example need no provider credentials or network requests.
59
+ Non-packaging tests and the synthetic example need no provider credentials or external network
60
+ access. Native-runner tests need Linux, Bubblewrap and OpenSSL; their HTTPS fixture runs locally.
40
61
  Packaging checks may download build and runtime dependencies. Radon reports are review signals.
41
62
 
42
63
  CI runs tests, dependency audits and installed-package checks on Python 3.12–3.14. It builds one
@@ -47,6 +68,23 @@ an isolated tool, pass its path to `uv tool install` or `pipx install`.
47
68
  For local matrix runs, set `UV_PYTHON` on every command. Use separate environments, test caches and
48
69
  coverage files for parallel runs; otherwise run versions sequentially.
49
70
 
71
+ Install the local hooks with `uv run pre-commit install`; run them on the whole repository with
72
+ `uv run pre-commit run --all-files`. Ruff and rumdl format files in place. CI checks formatting
73
+ without modifying files.
74
+
75
+ Recognized Markdown-only PRs skip Python linting, typing, unit-test matrices and dependency audits.
76
+ They retain Markdown formatting/linting, documentation tests, the strict site build, workflow and
77
+ dependency review, and all package build/install checks. Mixed changes, unknown paths, configuration
78
+ changes and PRs with 3,000 or more changed files run full validation. Rename detection considers
79
+ both paths; deletions participate. Failed path detection fails the required Workflows check.
80
+ Main-branch, scheduled, manual and release runs always perform full validation.
81
+
82
+ The required `Python tests` check summarizes the test matrix. It accepts a skipped matrix only
83
+ after successful Markdown-only classification. Failed classification, missing decisions, test
84
+ failures and unexpected skips fail this check.
85
+
86
+ The logo sources, usage rules and regeneration commands are in [branding](docs/branding/README.md).
87
+
50
88
  ## Workflow and dependency checks
51
89
 
52
90
  For GitHub Actions or Dependabot changes, use the jactionlint release pinned in
@@ -58,12 +96,13 @@ jactionlint --no-online --strict-exit
58
96
 
59
97
  CI uses its default correctness/security profile, with online lookups and automatic fixes disabled.
60
98
 
61
- Audit the resolved runtime dependencies and every dependency group, including development, docs
62
- and audit tooling, from `uv.lock`. Run this in Bash with the locked environment synchronized:
99
+ Audit the resolved runtime dependencies, optional extras and every dependency group, including
100
+ development, docs and audit tooling, from `uv.lock`. Run this in Bash with the locked environment
101
+ synchronized:
63
102
 
64
103
  ```bash
65
104
  set -o pipefail
66
- uv export --locked --all-groups --no-emit-project --format requirements.txt |
105
+ uv export --locked --all-groups --all-extras --no-emit-project --format requirements.txt |
67
106
  uv run --locked --group audit pip-audit --strict --disable-pip --require-hashes -r /dev/stdin
68
107
  ```
69
108
 
@@ -72,25 +111,56 @@ package names and versions without installing those packages, resolving alternat
72
111
  fixes. CI evaluates markers on each supported Python version. This covers locked versions rather
73
112
  than every version permitted by package dependency ranges.
74
113
 
75
- GitHub's dependency graph and Dependency Review use the inventory GitHub has for each commit.
76
- Before relying on them for `uv.lock` coverage, compare the hosted package/version inventory with
77
- the locked export on each supported Python version. The PR dependency-review job rejects newly
78
- introduced known vulnerabilities at any severity across runtime, development and unknown scopes.
79
- It uses a read-only token and does not check out or execute PR code. If it reports incomplete
80
- dependency snapshots, wait for GitHub's graph update and rerun the job. No license allowlist is
81
- enforced by this check. Keep the lockfile audit above as the full-inventory CI gate; Dependabot
82
- version updates alone do not establish dependency-graph coverage.
114
+ For dependency changes, run the lockfile audit above on each supported Python version. GitHub's
115
+ dependency graph may omit packages from `uv.lock`, so Dependabot and Dependency Review cannot
116
+ replace that audit.
117
+
118
+ The PR dependency-review job rejects newly introduced known vulnerabilities at any severity across
119
+ runtime, development and unknown scopes. It uses a read-only token and does not check out or execute
120
+ PR code. If it reports incomplete dependency snapshots, wait for GitHub's graph update and rerun
121
+ the job. License checks are disabled.
83
122
 
84
123
  CI runs weekly on Monday at 06:17 UTC to detect new advisories. Dependabot checks Python, Actions
85
124
  and pre-commit dependencies weekly, groups minor/patch updates and leaves majors individually
86
125
  reviewable. Ordinary updates have a seven-day cooldown; security updates have none. Updates are
87
- never automatically merged. Hosted dependency-graph coverage is a separate verification gate.
126
+ never automatically merged.
88
127
 
89
128
  ## Documentation
90
129
 
91
- README owns the quick start; `docs/` owns user guides and reference. Support, security and conduct
92
- policies live at the repository root. Keep private sessions, cases and credentials out of
93
- documentation and generated output.
130
+ Use `uv run rumdl fmt .` to format Markdown, then `uv run rumdl check .` to lint it. The same
131
+ version and `pyproject.toml` configuration apply to pre-commit and CI. Prose wraps at 100
132
+ characters; commands and tables retain their layout. MkDocs syntax is recognized within `docs/`. The
133
+ generated CLI reference has narrow exceptions for Typer's prompts, option alignment and wrapping;
134
+ its byte-for-byte generation check remains enforced. The generated changelog keeps each entry on
135
+ one source line, with a line-length exception.
136
+
137
+ Keep installation and first-use instructions in README, and detailed user guides and reference in
138
+ `docs/`. Support, security and conduct policies live at the repository root. Keep private sessions,
139
+ cases and credentials out of documentation and generated output.
140
+
141
+ Use [Diátaxis](https://diataxis.fr/) to match a section to the reader's need. A tutorial guides
142
+ learning through a reproducible example with expected results. A how-to gives prerequisites,
143
+ actions and a success check for a specific task. Reference describes commands and contracts;
144
+ explanation covers rationale, evidence and limits. Link between these when the reader needs more
145
+ detail. Apply the distinction within existing pages; add a page when it has a separate purpose.
146
+ Use concrete instructions and claims supported by evidence. Remove filler, promotional language
147
+ and repeated explanations.
148
+
149
+ [ROADMAP.md](ROADMAP.md) describes future direction. GitHub issues own actionable scope,
150
+ dependencies, acceptance criteria and status; release milestones group scope and the public
151
+ [Project](https://github.com/users/eberkut/projects/1/views/4) provides views of those same issues.
152
+ Link implementation pull requests to their owning issues and record relevant validation before
153
+ closing them. Keep future plans separate from current support claims.
154
+
155
+ Use [architecture](docs/architecture.md) to locate current contracts,
156
+ [decision records](docs/decisions/index.md) for significant choices and alternatives, and
157
+ [research](docs/research/index.md) for methods, measurements and reproducibility. Amend the owning
158
+ document instead of maintaining a second plan. A new decision record should explain context,
159
+ decision, alternatives and consequences; supersede an old decision explicitly when needed.
160
+
161
+ Before evaluating a new study, declare its tested domain, criteria, seeds, budget and intended
162
+ claims. Report costs across complete workflows, including failed and incomplete work, and document
163
+ the alternatives and limitations needed to interpret the results.
94
164
 
95
165
  The optional `docs` dependency group pins MkDocs and the shadcn theme. Search runs in the browser;
96
166
  fonts and scripts are served with the site. GitHub star-count requests and raw Markdown copying
@@ -100,13 +170,16 @@ When changing the theme or enabled extensions, check that asset list and the
100
170
  To preview the site locally:
101
171
 
102
172
  ```bash
103
- uv sync --locked --all-groups
173
+ uv sync --locked --all-groups --all-extras
104
174
  uv run --group docs mkdocs serve
105
175
  ```
106
176
 
107
- `mkdocs.yml` admits only the named public files under `docs/`. When adding a page, update its
108
- navigation and file allowlist, the sdist include list in `pyproject.toml`, and the documentation
109
- manifests in the documentation and packaging tests. Never set `docs_dir` to the repository root.
177
+ `mkdocs.yml` admits public pages and Markdown files in the dedicated `docs/decisions/` and
178
+ `docs/research/` directories. These directories contain publication-ready material only. Add new
179
+ pages to navigation; a page within an admitted directory needs no per-file package/test entry.
180
+ When adding a public directory or asset type, update the site/sdist publication boundaries and
181
+ their tests together. Never set `docs_dir` to the repository root. Keep raw evidence and generated
182
+ research outputs outside the documentation sources.
110
183
 
111
184
  After changing CLI options or help, regenerate the committed reference with Typer:
112
185
 
@@ -132,7 +205,7 @@ runs in a separate `github-pages` environment job without checking out or execut
132
205
  Pull requests receive read-only documentation checks through CI and cannot deploy.
133
206
 
134
207
  Repository administrators must select **Settings → Pages → Source: GitHub Actions** and restrict
135
- the `github-pages` environment to `main` before the first deployment. No custom domain, separate
208
+ the `github-pages` environment to `main`. No custom domain, separate
136
209
  site repository, `gh-pages` branch or personal access token is needed. After a successful
137
210
  deployment, check the published pages, navigation and static assets at the URL above.
138
211
 
@@ -153,8 +226,15 @@ accounting and budget refusal:
153
226
  uv run pytest -o addopts= tests/integration/test_native_calibration.py -q
154
227
  ```
155
228
 
229
+ Fuzz CLI tests cover harness-free inspection, consent, bounded collection, unsuccessful outcomes,
230
+ interruption and exact resume without provider requests:
231
+
232
+ ```bash
233
+ uv run pytest -o addopts= tests/integration/test_fuzz_cli.py -q
234
+ ```
235
+
156
236
  These tests establish local contracts. Native qualification is recorded in the
157
- [measurement notes](docs/native-runs.md#compatibility-and-measurements).
237
+ [measurements](docs/measurements.md).
158
238
 
159
239
  ## Opt-in native smoke tests
160
240
 
@@ -188,13 +268,13 @@ uv run pytest -o addopts= tests/live -m native_smoke -s \
188
268
  ```
189
269
 
190
270
  Every invocation creates fresh private state, harmless session content and an empty original
191
- workspace. Calibration requires two matching attempts and permits at most two, each bounded at
192
- 120 seconds plus cancellation grace. Final-response profiles allow up to two provider calls;
193
- Copilot shell allows up to four, with `pwd` visible but denied.
271
+ workspace. Calibration requires two matching attempts and permits at most two, each bounded at 120
272
+ seconds plus cancellation grace. Codex allows up to 32 provider calls across the two attempts;
273
+ either Copilot profile allows up to two. In the shell profile, `pwd` is visible but denied.
194
274
 
195
- Returned actions never execute. Hosted tools, MCP and tool-side network effects remain forbidden.
196
- An input-token cap cannot be enforced. Private evidence records known counts and unknown
197
- acceptance explicitly. Unsupported or unsuccessful profiles fail the test without skipping or retrying.
275
+ Returned actions never execute. Hosted tools, MCP and tool-side network effects remain forbidden. An
276
+ input-token cap cannot be enforced. Private evidence records known counts and unknown acceptance
277
+ explicitly. Unsupported or unsuccessful profiles fail the test without skipping or retrying.
198
278
 
199
279
  ## Preparing a change
200
280
 
@@ -206,13 +286,38 @@ Changes to native protocols, reconstruction, permissions or provider accounting
206
286
  the affected safety boundary. Mock tests establish local contracts; claims of native support also
207
287
  need capability, isolation, calibration and live-use evidence for the target profile.
208
288
 
289
+ ### Pull request review
290
+
291
+ Pull requests are squash-merged, with the PR title becoming the commit subject. Use a Conventional
292
+ Commit title, such as `fix(codex): handle overload responses` or
293
+ `docs: explain confirmation results`. The title check reruns on title edits and new pushes; it reads
294
+ metadata without checking out PR code. Make sure the required CI and CodeQL checks pass and resolve
295
+ review conversations before merging.
296
+
297
+ CodeRabbit reviews PRs when they are ready for review and posts feedback in a walkthrough and
298
+ inline comments. Address relevant findings or explain why a suggestion does not apply. The
299
+ maintainer makes the final review and merge decisions.
300
+
301
+ CodeRabbit's optional planning and code-generation features are configured in
302
+ [`.coderabbit.yaml`](.coderabbit.yaml). A paid CodeRabbit account is not required to contribute.
303
+
209
304
  ## Preparing a release
210
305
 
306
+ The release procedures below are for maintainers with repository and package-publishing access.
307
+
308
+ For every feature, aim for parity across supported harnesses. Any exception must be clearly
309
+ justified and documented before release.
310
+
211
311
  Python Semantic Release, pinned in the `release` dependency group, calculates versions from
212
312
  Conventional Commits. `pyproject.toml` is the version source; installed CLI and Codex client
213
313
  metadata read that distribution version. The tool generates `CHANGELOG.md` from the full release
214
- history, omitting routine build, CI, documentation, style and test commits. Do not edit the
215
- generated changelog by hand; review its contents before approving a release.
314
+ history, omitting routine build, CI, documentation, style and test commits. Its
315
+ [template](.github/changelog/CHANGELOG.md.j2) keeps lists compact, with one entry per source line.
316
+ Change the template to adjust formatting; do not edit generated entries by hand.
317
+
318
+ A maintainer starts preparation; Semantic Release chooses the version and writes the notes.
319
+ Review and merge the generated files through a PR so CI tests the prepared version before the
320
+ publication workflow builds it. The publication workflow uses that committed version.
216
321
 
217
322
  Use `main` with complete history and all existing release tags available. Preview the next version
218
323
  without changing files, the index, commits, tags or remote state:
@@ -250,24 +355,26 @@ ownership and the following repository/index settings:
250
355
 
251
356
  - PyPI and TestPyPI Trusted Publishers bind `eberkut/ithrl`, `release.yml` and their respective
252
357
  `pypi` / `testpypi` environments. Publishing uses OIDC, without a stored PyPI API token.
253
- - Both environments admit only `main`. `pypi` requires the maintainer's approval, permits
254
- self-review and disallows administrative approval bypass. Environment declarations in YAML
255
- do not configure these protections; verify the actual settings before dispatch.
358
+ - Both environments admit only `main`, require the maintainer's approval, permit self-review and
359
+ disallow administrative approval bypass. Environment declarations in YAML do not configure these
360
+ protections; verify the actual settings before dispatch.
256
361
  - Release-tag rules permit the maintainer's signed-tag creation and prevent unapproved tag
257
362
  replacement or deletion. The workflow never creates a tag.
258
363
 
259
- The dispatch gate admits the repository's current maintainer identity and requires the full source
260
- SHA and exact final `X.Y.Z` version. Replace the placeholders with the reviewed values:
364
+ The release workflow accepts dispatches only from the repository maintainer. Supply the full source
365
+ commit SHA and exact final `X.Y.Z` version. Replace the placeholders with the reviewed values:
261
366
 
262
367
  ```bash
263
368
  gh workflow run release.yml --repo eberkut/ithrl --ref main \
264
369
  -f version=X.Y.Z -f source-sha=FULL_APPROVED_COMMIT_SHA
265
370
  ```
266
371
 
267
- 1. Inspect that run's checks and successful **Publish TestPyPI rehearsal** job. Its summary records
372
+ 1. After source verification and validation pass, approve the `testpypi` deployment on the run's
373
+ GitHub page. This authorizes the public TestPyPI upload.
374
+ 2. Inspect the successful **Publish TestPyPI rehearsal** job. Its summary records
268
375
  the source, version, immutable artifact ID and checksum-manifest digest. The production job
269
376
  waits at the `pypi` environment. TestPyPI files, logs and artifacts are public.
270
- 2. Download that run's `release-distributions` artifact into a new review directory. For example:
377
+ 3. Download that run's `release-distributions` artifact into a new review directory. For example:
271
378
 
272
379
  ```bash
273
380
  gh run download RUN_ID --repo eberkut/ithrl \
@@ -278,7 +385,7 @@ gh workflow run release.yml --repo eberkut/ithrl --ref main \
278
385
  from the review directory. Inspect the release notes and confirm TestPyPI serves the same
279
386
  distribution hashes. Complete a clean TestPyPI installation/example rehearsal before approval;
280
387
  resolve dependencies only from the normal PyPI index, without mixing indexes.
281
- 3. After the rehearsal passes and tag creation is approved, create and verify the signed tag at
388
+ 4. After the rehearsal passes and tag creation is approved, create and verify the signed tag at
282
389
  the frozen source commit, then push only that tag through the permitted tag-rules path:
283
390
 
284
391
  ```bash
@@ -287,12 +394,12 @@ gh workflow run release.yml --repo eberkut/ithrl --ref main \
287
394
  git push origin refs/tags/vX.Y.Z
288
395
  ```
289
396
 
290
- 4. Review and approve the `pypi` deployment on the run's GitHub page. The job verifies the existing
397
+ 5. Review and approve the `pypi` deployment on the run's GitHub page. The job verifies the existing
291
398
  annotated tag targets the frozen source, rechecks the files, and uploads to PyPI. The final job
292
399
  rechecks the tag/files and creates the GitHub Release with those distributions, notes and
293
400
  checksums. Signature verification belongs to the preceding maintainer tag check; the workflow
294
401
  checks the tag object and target commit.
295
- 5. Verify the published versions, hashes, attestations and installed example. A successful upload
402
+ 6. Verify the published versions, hashes, attestations and installed example. A successful upload
296
403
  alone does not complete release acceptance.
297
404
 
298
405
  Complete review within 30 days: release artifacts are retained for 30 days, and GitHub limits the
ithrl-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.5
2
+ Name: ithrl
3
+ Version: 0.3.0
4
+ Summary: Find smaller agent contexts that preserve a selected model behavior
5
+ Project-URL: Source, https://github.com/eberkut/ithrl
6
+ Project-URL: Issues, https://github.com/eberkut/ithrl/issues
7
+ Project-URL: Documentation, https://eberkut.github.io/ithrl/
8
+ Project-URL: Changelog, https://github.com/eberkut/ithrl/releases
9
+ Author: Vincent Morel
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Debuggers
21
+ Requires-Python: >=3.12
22
+ Requires-Dist: filelock>=3.32.4
23
+ Requires-Dist: github-copilot-sdk==1.0.28
24
+ Requires-Dist: jsonschema>=4.25
25
+ Requires-Dist: packaging>=24.2
26
+ Requires-Dist: platformdirs>=4.3
27
+ Requires-Dist: pydantic>=2.12
28
+ Requires-Dist: rich>=14
29
+ Requires-Dist: typer>=0.16
30
+ Provides-Extra: fuzz
31
+ Requires-Dist: scipy>=1.18; extra == 'fuzz'
32
+ Description-Content-Type: text/markdown
33
+
34
+ <!-- rumdl-disable MD033 -->
35
+ <h1>
36
+ <picture>
37
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/eberkut/ithrl/main/docs/branding/ithrl-logo-dark.svg">
38
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/eberkut/ithrl/main/docs/branding/ithrl-logo-light.svg">
39
+ <img src="https://raw.githubusercontent.com/eberkut/ithrl/main/docs/branding/ithrl-logo.png" alt="ithrl" width="320" height="158">
40
+ </picture>
41
+ </h1>
42
+ <!-- rumdl-enable MD033 -->
43
+
44
+ [![PyPI](https://img.shields.io/pypi/v/ithrl.svg)](https://pypi.org/project/ithrl/)
45
+ [![CI](https://github.com/eberkut/ithrl/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/eberkut/ithrl/actions/workflows/ci.yml)
46
+
47
+ `ithrl` turns saved Codex and GitHub Copilot sessions into debugging experiments. Search for a
48
+ smaller context that preserves a chosen response or tool request, or a small text change that alters
49
+ it.
50
+
51
+ [Documentation](https://eberkut.github.io/ithrl/) · [Try it](#try-it) ·
52
+ [Supported inputs](#supported-inputs)
53
+
54
+ ## Install
55
+
56
+ With [uv](https://docs.astral.sh/uv/):
57
+
58
+ ```bash
59
+ uv tool install ithrl
60
+ ```
61
+
62
+ You can also install with `pipx install ithrl` or, in an existing virtual environment,
63
+ `python -m pip install ithrl`. For context fuzzing, use `'ithrl[fuzz]'` in place of `ithrl` in
64
+ the installation command.
65
+
66
+ Tested on Python 3.12–3.14. Native runners require Linux. APIs and saved formats may change before
67
+ 1.0; keep your source sessions and record the version used for each case.
68
+
69
+ ## Try it
70
+
71
+ The bundled deterministic example needs no account, agent installation or model access:
72
+
73
+ ```bash
74
+ mkdir -m 700 ithrl-demo
75
+ ithrl extract --example --output ithrl-demo/case
76
+ ithrl shrink ithrl-demo/case --observation-store ithrl-demo/observations.sqlite
77
+ ```
78
+
79
+ The result removes half the context items and confirms that the target is preserved. Output excerpt:
80
+
81
+ ```text
82
+ Reduced and confirmed
83
+ context items 10 -> 5
84
+ original test target observed
85
+ search 1-minimal; all valid single removals tested
86
+ confirmation target preserved
87
+ observations 15
88
+ No network requests or provider calls. No actions executed.
89
+ ```
90
+
91
+ Inspect the saved result in `ithrl-demo/case/results/`; the
92
+ [results guide](https://github.com/eberkut/ithrl/blob/main/docs/results.md) explains its files.
93
+ Use a new directory to repeat the example; extraction refuses to overwrite an existing case.
94
+
95
+ ## Commands
96
+
97
+ - `ithrl extract` browses saved sessions and creates a case from a selected decision.
98
+ - `ithrl shrink CASE` searches for context removals that preserve the selected behavior.
99
+ - `ithrl inspect retained CASE --result RESULT` explains retained units and recorded removal trials
100
+ from a saved reduction without model access. See
101
+ [results and privacy](https://github.com/eberkut/ithrl/blob/main/docs/results.md#inspect-retained-context).
102
+ - `ithrl fuzz CASE --config PRIVATE_TOML` searches for and simplifies text appends that decrease how
103
+ often the selected behavior occurs, with independent confirmation.
104
+
105
+ For example, extract a saved session file:
106
+
107
+ ```bash
108
+ ithrl extract path/to/session.jsonl --output .ithrl/case
109
+ ```
110
+
111
+ Extraction makes no provider calls. Native experiments require Linux, usable Bubblewrap, an
112
+ installed harness and model access. Review the provider, safety controls and call/time budget in the
113
+ [native-run guide](https://github.com/eberkut/ithrl/blob/main/docs/native-runs.md) before execution.
114
+ Returned actions are observed and denied. Cases contain copied session content; keep them private.
115
+
116
+ ## Supported inputs
117
+
118
+ | Input | Extracted decisions | Reduction | Fuzzing |
119
+ | --- | --- | --- | --- |
120
+ | Bundled synthetic example | Synthetic tool request | Deterministic local runner | Local fake runner |
121
+ | Codex CLI rollouts | Final responses | Experimental native runner; [paragraph-removal measurements](https://github.com/eberkut/ithrl/blob/main/docs/measurements.md#ordinary-session-paragraph-removal) | Experimental prior-user text appends |
122
+ | Copilot CLI session events | Final responses and shell requests | Experimental final-response paragraph removal and denied `bash` runner | Experimental prior-user text appends for final-response targets |
123
+
124
+ Native Codex and Copilot final-response fuzzing supports appending text to eligible prior user
125
+ input while preserving the fixed triggering input. The
126
+ [fuzzing walkthrough](https://github.com/eberkut/ithrl/blob/main/docs/native-runs.md#context-fuzzing)
127
+ starts with a local example and covers native execution.
128
+
129
+ [Saved-session measurements](https://github.com/eberkut/ithrl/blob/main/docs/measurements.md#saved-session-experiments)
130
+ include ordinary Codex and Copilot final-response experiments that removed paragraphs from retained
131
+ prior-user text and passed fresh confirmation at a 20-percentage-point preservation margin. The
132
+ [worked investigation](https://github.com/eberkut/ithrl/blob/main/docs/research/ordinary-session-investigation.md)
133
+ explains what the smaller Codex context helped a developer inspect and what remains unresolved.
134
+ The measurements distinguish private runtime qualification from integrated support and report
135
+ resource usage and unsuccessful outcomes alongside completed runs. Check
136
+ [native compatibility](https://github.com/eberkut/ithrl/blob/main/docs/native-runs.md#compatibility-and-measurements)
137
+ for the installed harness's requirements.
138
+
139
+ ## Documentation
140
+
141
+ Read the [documentation site](https://eberkut.github.io/ithrl/) or browse the guides below.
142
+
143
+ - [Native runs](https://github.com/eberkut/ithrl/blob/main/docs/native-runs.md): session selection,
144
+ experiment configuration, preflight, model execution and measured resource usage.
145
+ - [Results and privacy](https://github.com/eberkut/ithrl/blob/main/docs/results.md): saved files,
146
+ result interpretation, budgets, resume and sensitive data.
147
+ - [Contributing](https://github.com/eberkut/ithrl/blob/main/CONTRIBUTING.md): issue-first
148
+ collaboration, checkout setup, checks and smoke tests.
149
+ - [Roadmap](https://github.com/eberkut/ithrl/blob/main/ROADMAP.md): current priorities and planned
150
+ capabilities.
151
+ - [Architecture](https://github.com/eberkut/ithrl/blob/main/docs/architecture.md): implementation
152
+ boundaries and decisions.
153
+ - [Research](https://github.com/eberkut/ithrl/blob/main/docs/research/index.md): feasibility
154
+ studies, statistical methods and measurements.
155
+
156
+ For help, bugs or proposals, see [Support](https://github.com/eberkut/ithrl/blob/main/SUPPORT.md).
157
+ Report vulnerabilities through
158
+ [private reporting](https://github.com/eberkut/ithrl/security/advisories/new).
159
+
160
+ ## Name
161
+
162
+ Pronounce `ithrl` as **Ithuriel**, the angel whose spear reveals Satan in disguise in Milton's
163
+ [*Paradise Lost*](https://rpo.library.utoronto.ca/content/paradise-lost-book-iv-1674).
164
+
165
+ ## License
166
+
167
+ Licensed under the [Apache License 2.0](https://github.com/eberkut/ithrl/blob/main/LICENSE).