esoi 0.6.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 (331) hide show
  1. esoi/__init__.py +246 -0
  2. esoi/__main__.py +89 -0
  3. esoi/apply_esoi.py +43 -0
  4. esoi/command_table.py +142 -0
  5. esoi/data/esoi_template.csv +54 -0
  6. esoi/data/skill/evolvable-structure/INDEX.md +63 -0
  7. esoi/data/skill/evolvable-structure/SKILL.md +142 -0
  8. esoi/data/skill/evolvable-structure/coding/components.md +27 -0
  9. esoi/data/skill/evolvable-structure/coding/concept_ai_quest_qar.md +36 -0
  10. esoi/data/skill/evolvable-structure/coding/pipelines_and_experiments.md +39 -0
  11. esoi/data/skill/evolvable-structure/coding/registry_and_templates.md +34 -0
  12. esoi/data/skill/evolvable-structure/coding/writealyze.md +48 -0
  13. esoi/data/skill/evolvable-structure/coding.md +59 -0
  14. esoi/data/skill/evolvable-structure/other-categories.md +159 -0
  15. esoi/data/skill/evolvable-structure/principles/difficulties.md +111 -0
  16. esoi/data/skill/evolvable-structure/principles/documenting.md +85 -0
  17. esoi/data/skill/evolvable-structure/principles/patterns_change.md +188 -0
  18. esoi/data/skill/evolvable-structure/principles/patterns_consideration.md +31 -0
  19. esoi/data/skill/evolvable-structure/principles/patterns_core.md +81 -0
  20. esoi/data/skill/evolvable-structure/principles/patterns_people.md +70 -0
  21. esoi/data/skill/evolvable-structure/principles/purpose.md +75 -0
  22. esoi/data/skill/evolvable-structure/principles/research.md +71 -0
  23. esoi/data/skill/evolvable-structure/principles/vocabulary.md +68 -0
  24. esoi/data/skill/evolvable-structure/principles.md +91 -0
  25. esoi/data/skill/evolvable-structure/python_tools.md +72 -0
  26. esoi/data/skill/evolvable-structure/sources/INDEX.md +39 -0
  27. esoi/data/skill/evolvable-structure/sources/agentic_frameworks.md +152 -0
  28. esoi/data/skill/evolvable-structure/sources/cantr_governance_proposals.md +163 -0
  29. esoi/data/skill/evolvable-structure/sources/components_research.md +145 -0
  30. esoi/data/skill/evolvable-structure/sources/definitions_and_advice.md +209 -0
  31. esoi/data/skill/evolvable-structure/sources/evolutionary_architecture_talk.md +119 -0
  32. esoi/data/skill/evolvable-structure/sources/public_research.md +214 -0
  33. esoi/data/skill/evolvable-structure/sources/trello_project_documentation.md +261 -0
  34. esoi/data/skill/evolvable-structure/steps.md +194 -0
  35. esoi/data/skill_version.json +58 -0
  36. esoi/esoi_selection.json +412 -0
  37. esoi/optimization/__init__.py +0 -0
  38. esoi/optimization/commands.py +160 -0
  39. esoi/optimization/flow.py +37 -0
  40. esoi/optimization/interface.py +12 -0
  41. esoi/optimization/keep_metric_record/__init__.py +0 -0
  42. esoi/optimization/keep_metric_record/interface.py +35 -0
  43. esoi/optimization/keep_metric_record/iteration.py +145 -0
  44. esoi/optimization/keep_metric_record/metric_meter.py +276 -0
  45. esoi/optimization/keep_metric_record/metric_results.py +368 -0
  46. esoi/optimization/keep_metric_record/spec_slice.py +269 -0
  47. esoi/optimization/leaderboard/__init__.py +0 -0
  48. esoi/optimization/leaderboard/arm_kinds.py +45 -0
  49. esoi/optimization/leaderboard/arm_selection.py +44 -0
  50. esoi/optimization/leaderboard/board_report.py +174 -0
  51. esoi/optimization/leaderboard/cascade_report.py +145 -0
  52. esoi/optimization/leaderboard/cascade_stages.py +336 -0
  53. esoi/optimization/leaderboard/case_identity.py +82 -0
  54. esoi/optimization/leaderboard/evidence_table.py +226 -0
  55. esoi/optimization/leaderboard/held_out_parts.py +109 -0
  56. esoi/optimization/leaderboard/inherited_gate.py +55 -0
  57. esoi/optimization/leaderboard/interface.py +34 -0
  58. esoi/optimization/leaderboard/lock_evidence.py +51 -0
  59. esoi/optimization/leaderboard/ranking.py +95 -0
  60. esoi/optimization/leaderboard/results_log.py +101 -0
  61. esoi/optimization/leaderboard/rival_decisions.py +215 -0
  62. esoi/optimization/leaderboard/rival_pairing.py +84 -0
  63. esoi/optimization/leaderboard/stage_standings.py +204 -0
  64. esoi/optimization/leaderboard/stats.py +203 -0
  65. esoi/optimization/leaderboard/switching_policy.py +77 -0
  66. esoi/optimization/leaderboard/verdict_labels.py +82 -0
  67. esoi/optimization/measurement_harness/__init__.py +0 -0
  68. esoi/optimization/measurement_harness/access.py +111 -0
  69. esoi/optimization/measurement_harness/arm_loading.py +102 -0
  70. esoi/optimization/measurement_harness/balance.py +74 -0
  71. esoi/optimization/measurement_harness/call_meter.py +156 -0
  72. esoi/optimization/measurement_harness/case_count.py +14 -0
  73. esoi/optimization/measurement_harness/case_loading.py +91 -0
  74. esoi/optimization/measurement_harness/cassette.py +132 -0
  75. esoi/optimization/measurement_harness/check_guards.py +56 -0
  76. esoi/optimization/measurement_harness/component_folder.py +43 -0
  77. esoi/optimization/measurement_harness/discriminating_cases/__init__.py +0 -0
  78. esoi/optimization/measurement_harness/discriminating_cases/interface.py +23 -0
  79. esoi/optimization/measurement_harness/expect.py +95 -0
  80. esoi/optimization/measurement_harness/foundation_parts.py +228 -0
  81. esoi/optimization/measurement_harness/hermetic.py +41 -0
  82. esoi/optimization/measurement_harness/interface.py +53 -0
  83. esoi/optimization/measurement_harness/mutation_score.py +66 -0
  84. esoi/optimization/measurement_harness/offline_guard.py +116 -0
  85. esoi/optimization/measurement_harness/per_case_log.py +82 -0
  86. esoi/optimization/measurement_harness/record_result.py +58 -0
  87. esoi/optimization/measurement_harness/record_slices.py +96 -0
  88. esoi/optimization/measurement_harness/rerun_stale.py +203 -0
  89. esoi/optimization/measurement_harness/run_arguments.py +84 -0
  90. esoi/optimization/measurement_harness/run_cases.py +78 -0
  91. esoi/optimization/measurement_harness/run_command.py +38 -0
  92. esoi/optimization/measurement_harness/run_component.py +306 -0
  93. esoi/optimization/measurement_harness/run_cost.py +25 -0
  94. esoi/optimization/measurement_harness/run_errors.py +14 -0
  95. esoi/optimization/promote_the_winner/__init__.py +0 -0
  96. esoi/optimization/promote_the_winner/interface.py +26 -0
  97. esoi/optimization/promote_the_winner/promote.py +409 -0
  98. esoi/optimization/when_metrics_are_run/__init__.py +0 -0
  99. esoi/optimization/when_metrics_are_run/interface.py +31 -0
  100. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/__init__.py +0 -0
  101. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/attest.py +156 -0
  102. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/builds_on.py +166 -0
  103. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/code_changed.py +25 -0
  104. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/code_provenance.py +85 -0
  105. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/import_scan.py +184 -0
  106. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/import_world.py +136 -0
  107. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/interface.py +12 -0
  108. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/ownership_index.py +135 -0
  109. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/stale_reasons.py +115 -0
  110. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/stale_scope.py +174 -0
  111. esoi/optimization/when_metrics_are_run/know_what_a_result_measures/staleness.py +152 -0
  112. esoi/optimization/when_metrics_are_run/paid_gating.py +73 -0
  113. esoi/optimization/when_metrics_are_run/public_evidence/__init__.py +0 -0
  114. esoi/optimization/when_metrics_are_run/public_evidence/evidence_grading.py +362 -0
  115. esoi/optimization/when_metrics_are_run/public_evidence/evidence_ranking.py +207 -0
  116. esoi/optimization/when_metrics_are_run/public_evidence/evidence_records.py +241 -0
  117. esoi/optimization/when_metrics_are_run/public_evidence/evidence_report.py +106 -0
  118. esoi/optimization/when_metrics_are_run/public_evidence/grading_table.py +75 -0
  119. esoi/optimization/when_metrics_are_run/public_evidence/interface.py +6 -0
  120. esoi/optimization/when_metrics_are_run/run_guards.py +232 -0
  121. esoi/optimization/when_metrics_are_run/run_log.py +128 -0
  122. esoi/runtime/__init__.py +0 -0
  123. esoi/runtime/assemble_by_name/__init__.py +0 -0
  124. esoi/runtime/assemble_by_name/arm_inspection.py +46 -0
  125. esoi/runtime/assemble_by_name/arm_ranking.py +65 -0
  126. esoi/runtime/assemble_by_name/assemble.py +481 -0
  127. esoi/runtime/assemble_by_name/assembly.py +75 -0
  128. esoi/runtime/assemble_by_name/assembly_config.py +37 -0
  129. esoi/runtime/assemble_by_name/build_parts.py +130 -0
  130. esoi/runtime/assemble_by_name/cascade_layers.py +79 -0
  131. esoi/runtime/assemble_by_name/closure.py +53 -0
  132. esoi/runtime/assemble_by_name/declared_needs.py +51 -0
  133. esoi/runtime/assemble_by_name/dependency_graph.py +82 -0
  134. esoi/runtime/assemble_by_name/entry.py +206 -0
  135. esoi/runtime/assemble_by_name/entry_check.py +46 -0
  136. esoi/runtime/assemble_by_name/entry_cli.py +65 -0
  137. esoi/runtime/assemble_by_name/entry_outcome.py +70 -0
  138. esoi/runtime/assemble_by_name/entry_types.py +44 -0
  139. esoi/runtime/assemble_by_name/environ_options.py +44 -0
  140. esoi/runtime/assemble_by_name/environment_needs/__init__.py +0 -0
  141. esoi/runtime/assemble_by_name/environment_needs/api_links.py +17 -0
  142. esoi/runtime/assemble_by_name/environment_needs/checking.py +223 -0
  143. esoi/runtime/assemble_by_name/environment_needs/closure.py +150 -0
  144. esoi/runtime/assemble_by_name/environment_needs/declarations.py +361 -0
  145. esoi/runtime/assemble_by_name/environment_needs/generated_files.py +166 -0
  146. esoi/runtime/assemble_by_name/environment_needs/python_specs.py +57 -0
  147. esoi/runtime/assemble_by_name/environment_needs/report.py +77 -0
  148. esoi/runtime/assemble_by_name/environment_needs/source_location.py +20 -0
  149. esoi/runtime/assemble_by_name/hierarchy.py +178 -0
  150. esoi/runtime/assemble_by_name/installation/__init__.py +0 -0
  151. esoi/runtime/assemble_by_name/installation/assembly_plan.py +74 -0
  152. esoi/runtime/assemble_by_name/installation/command_running.py +46 -0
  153. esoi/runtime/assemble_by_name/installation/conflicts.py +144 -0
  154. esoi/runtime/assemble_by_name/installation/execution.py +181 -0
  155. esoi/runtime/assemble_by_name/installation/install_lock.py +50 -0
  156. esoi/runtime/assemble_by_name/installation/plan.py +67 -0
  157. esoi/runtime/assemble_by_name/installation/plan_report.py +54 -0
  158. esoi/runtime/assemble_by_name/installation/resolution_ladder.py +171 -0
  159. esoi/runtime/assemble_by_name/installation/resolvers.py +46 -0
  160. esoi/runtime/assemble_by_name/intent_map.py +114 -0
  161. esoi/runtime/assemble_by_name/interface.py +40 -0
  162. esoi/runtime/assemble_by_name/lazy_need.py +37 -0
  163. esoi/runtime/assemble_by_name/lock_file.py +59 -0
  164. esoi/runtime/assemble_by_name/offline_guard.py +36 -0
  165. esoi/runtime/assemble_by_name/packaged_records.py +74 -0
  166. esoi/runtime/assemble_by_name/pending_needs.py +90 -0
  167. esoi/runtime/assemble_by_name/project_runner.py +29 -0
  168. esoi/runtime/assemble_by_name/readme_example.py +164 -0
  169. esoi/runtime/assemble_by_name/seat_blockers.py +100 -0
  170. esoi/runtime/assemble_by_name/target_lookup.py +57 -0
  171. esoi/runtime/commands.py +265 -0
  172. esoi/runtime/consumer_check/__init__.py +0 -0
  173. esoi/runtime/consumer_check/consumer.py +425 -0
  174. esoi/runtime/consumer_check/follow.py +397 -0
  175. esoi/runtime/consumer_check/interface.py +28 -0
  176. esoi/runtime/flow.py +31 -0
  177. esoi/runtime/implementation_selection/__init__.py +0 -0
  178. esoi/runtime/implementation_selection/declare.py +164 -0
  179. esoi/runtime/implementation_selection/interface.py +25 -0
  180. esoi/runtime/implementation_selection/lock.py +328 -0
  181. esoi/runtime/implementation_selection/lock_command.py +91 -0
  182. esoi/runtime/implementation_selection/select.py +172 -0
  183. esoi/runtime/implementation_selection/selection_cascade.py +273 -0
  184. esoi/runtime/implementation_selection/selection_registry.py +147 -0
  185. esoi/runtime/implementation_selection/variants.py +75 -0
  186. esoi/runtime/interface.py +12 -0
  187. esoi/structure/__init__.py +0 -0
  188. esoi/structure/commands.py +235 -0
  189. esoi/structure/flow.py +50 -0
  190. esoi/structure/intent_registry/__init__.py +0 -0
  191. esoi/structure/intent_registry/admit.py +112 -0
  192. esoi/structure/intent_registry/assembly_errors.py +11 -0
  193. esoi/structure/intent_registry/besidecode.py +342 -0
  194. esoi/structure/intent_registry/circumstances.py +160 -0
  195. esoi/structure/intent_registry/config.py +297 -0
  196. esoi/structure/intent_registry/fields.py +278 -0
  197. esoi/structure/intent_registry/implementedby.py +141 -0
  198. esoi/structure/intent_registry/import_base.py +23 -0
  199. esoi/structure/intent_registry/intents.py +249 -0
  200. esoi/structure/intent_registry/interface.py +46 -0
  201. esoi/structure/intent_registry/migrate.py +165 -0
  202. esoi/structure/intent_registry/name_check.py +21 -0
  203. esoi/structure/intent_registry/parsed_source.py +52 -0
  204. esoi/structure/intent_registry/records.py +551 -0
  205. esoi/structure/intent_registry/registry.py +129 -0
  206. esoi/structure/intent_registry/specify_from_code/__init__.py +0 -0
  207. esoi/structure/intent_registry/specify_from_code/declarations.py +368 -0
  208. esoi/structure/intent_registry/specify_from_code/interface.py +26 -0
  209. esoi/structure/intent_registry/specify_from_code/newsolution.py +115 -0
  210. esoi/structure/intent_registry/tables.py +110 -0
  211. esoi/structure/intent_registry/template_sync/__init__.py +0 -0
  212. esoi/structure/intent_registry/template_sync/interface.py +28 -0
  213. esoi/structure/intent_registry/template_sync/template.py +282 -0
  214. esoi/structure/intent_registry/template_sync/templates.py +489 -0
  215. esoi/structure/intent_registry/template_sync/versioning.py +275 -0
  216. esoi/structure/interface.py +12 -0
  217. esoi/structure/library_adoption/__init__.py +0 -0
  218. esoi/structure/library_adoption/interface.py +26 -0
  219. esoi/structure/library_adoption/resolve.py +120 -0
  220. esoi/structure/ownership_map/__init__.py +0 -0
  221. esoi/structure/ownership_map/interface.py +25 -0
  222. esoi/structure/structure_budget/__init__.py +0 -0
  223. esoi/structure/structure_budget/interface.py +26 -0
  224. esoi/structure/structure_check/__init__.py +0 -0
  225. esoi/structure/structure_check/check.py +187 -0
  226. esoi/structure/structure_check/coherence.py +370 -0
  227. esoi/structure/structure_check/coherence_code_evidence.py +363 -0
  228. esoi/structure/structure_check/coherence_paragraph.py +216 -0
  229. esoi/structure/structure_check/coherence_records.py +18 -0
  230. esoi/structure/structure_check/hygiene.py +224 -0
  231. esoi/structure/structure_check/interface.py +31 -0
  232. esoi/structure/structure_check/ratchet.py +242 -0
  233. esoi/structure/structure_check/rules/__init__.py +75 -0
  234. esoi/structure/structure_check/rules/adoption_rules.py +122 -0
  235. esoi/structure/structure_check/rules/base.py +164 -0
  236. esoi/structure/structure_check/rules/beside_rules.py +231 -0
  237. esoi/structure/structure_check/rules/cascade_rules.py +98 -0
  238. esoi/structure/structure_check/rules/consideration_rules.py +88 -0
  239. esoi/structure/structure_check/rules/declarations.py +25 -0
  240. esoi/structure/structure_check/rules/entry_rules.py +489 -0
  241. esoi/structure/structure_check/rules/foundation_rules.py +68 -0
  242. esoi/structure/structure_check/rules/generated.py +143 -0
  243. esoi/structure/structure_check/rules/hierarchy_rules.py +54 -0
  244. esoi/structure/structure_check/rules/intents.py +340 -0
  245. esoi/structure/structure_check/rules/layout.py +180 -0
  246. esoi/structure/structure_check/rules/measurement.py +355 -0
  247. esoi/structure/structure_check/rules/modulefacts.py +174 -0
  248. esoi/structure/structure_check/rules/one_criterion.py +218 -0
  249. esoi/structure/structure_check/rules/registry_rules.py +229 -0
  250. esoi/structure/structure_check/rules/structure_quality_rules.py +79 -0
  251. esoi/structure/structure_check/rules/version_rules.py +41 -0
  252. esoi/structure/structure_check/rules/wording.py +112 -0
  253. esoi/structure/structure_quality/__init__.py +0 -0
  254. esoi/structure/structure_quality/adopted.py +73 -0
  255. esoi/structure/structure_quality/assess.py +24 -0
  256. esoi/structure/structure_quality/balance.py +117 -0
  257. esoi/structure/structure_quality/behavior.py +63 -0
  258. esoi/structure/structure_quality/cochange.py +71 -0
  259. esoi/structure/structure_quality/compare.py +159 -0
  260. esoi/structure/structure_quality/complexity.py +36 -0
  261. esoi/structure/structure_quality/conformance.py +204 -0
  262. esoi/structure/structure_quality/coupling.py +371 -0
  263. esoi/structure/structure_quality/duplication.py +120 -0
  264. esoi/structure/structure_quality/expert_review.py +63 -0
  265. esoi/structure/structure_quality/flow.py +27 -0
  266. esoi/structure/structure_quality/foundation.py +89 -0
  267. esoi/structure/structure_quality/interface.py +59 -0
  268. esoi/structure/structure_quality/overlap.py +28 -0
  269. esoi/structure/structure_quality/project.py +262 -0
  270. esoi/structure/structure_quality/protocol_groups.py +119 -0
  271. esoi/structure/structure_quality/report.py +35 -0
  272. esoi/structure/structure_quality/scope.py +252 -0
  273. esoi/structure/structure_quality/size.py +99 -0
  274. esoi/structure/structure_quality/surface.py +152 -0
  275. esoi/understanding/__init__.py +0 -0
  276. esoi/understanding/commands.py +352 -0
  277. esoi/understanding/esoi_for_ai/__init__.py +0 -0
  278. esoi/understanding/esoi_for_ai/behaviour.py +76 -0
  279. esoi/understanding/esoi_for_ai/command_provider.py +39 -0
  280. esoi/understanding/esoi_for_ai/esoi_behaviour_judge/__init__.py +0 -0
  281. esoi/understanding/esoi_for_ai/esoi_behaviour_judge/behaviour_judge.py +55 -0
  282. esoi/understanding/esoi_for_ai/esoi_behaviour_judge/interface.py +24 -0
  283. esoi/understanding/esoi_for_ai/interface.py +34 -0
  284. esoi/understanding/flow.py +44 -0
  285. esoi/understanding/interface.py +12 -0
  286. esoi/understanding/local_application_index/__init__.py +0 -0
  287. esoi/understanding/local_application_index/interface.py +25 -0
  288. esoi/understanding/local_application_index/projects.py +412 -0
  289. esoi/understanding/readable_records/__init__.py +0 -0
  290. esoi/understanding/readable_records/diagram.py +128 -0
  291. esoi/understanding/readable_records/interface.py +48 -0
  292. esoi/understanding/readable_records/readme.py +93 -0
  293. esoi/understanding/readable_records/readme_adopted.py +53 -0
  294. esoi/understanding/readable_records/readme_folder_page.py +236 -0
  295. esoi/understanding/readable_records/readme_intent_page.py +240 -0
  296. esoi/understanding/readable_records/readme_trail.py +117 -0
  297. esoi/understanding/readable_records/readme_view.py +198 -0
  298. esoi/understanding/review_tracker/__init__.py +0 -0
  299. esoi/understanding/review_tracker/interface.py +29 -0
  300. esoi/understanding/review_tracker/sheets.py +342 -0
  301. esoi/understanding/review_tracker/tracker.py +372 -0
  302. esoi/understanding/solution_consideration/__init__.py +0 -0
  303. esoi/understanding/solution_consideration/fan_out.py +67 -0
  304. esoi/understanding/solution_consideration/knowledge.py +300 -0
  305. esoi/understanding/solution_consideration/network_records.py +155 -0
  306. esoi/understanding/solution_consideration/solution_prompt.py +543 -0
  307. esoi/understanding/solution_relevance/__init__.py +0 -0
  308. esoi/understanding/solution_relevance/relevance.py +139 -0
  309. esoi/understanding/solution_relevance/relevance_cases.py +159 -0
  310. esoi/understanding/spec_search/__init__.py +0 -0
  311. esoi/understanding/spec_search/spec_index.py +336 -0
  312. esoi/understanding/spec_search/spec_search.py +532 -0
  313. esoi/understanding/spec_search/standards_check.py +172 -0
  314. esoi/understanding/spec_search/standards_measure.py +251 -0
  315. esoi/understanding/spec_search/standards_nav.py +370 -0
  316. esoi/understanding/the_standard/__init__.py +0 -0
  317. esoi/understanding/the_standard/docs.py +237 -0
  318. esoi/understanding/the_standard/interface.py +37 -0
  319. esoi/understanding/the_standard/scaffold.py +351 -0
  320. esoi/understanding/the_standard/skill_distribution/__init__.py +0 -0
  321. esoi/understanding/the_standard/skill_distribution/interface.py +27 -0
  322. esoi/understanding/the_standard/skill_distribution/skill.py +419 -0
  323. esoi/understanding/the_standard/the_steps/__init__.py +0 -0
  324. esoi/understanding/the_standard/the_steps/interface.py +25 -0
  325. esoi-0.6.0.dist-info/METADATA +123 -0
  326. esoi-0.6.0.dist-info/RECORD +331 -0
  327. esoi-0.6.0.dist-info/WHEEL +5 -0
  328. esoi-0.6.0.dist-info/entry_points.txt +2 -0
  329. esoi-0.6.0.dist-info/licenses/LICENSE +201 -0
  330. esoi-0.6.0.dist-info/licenses/NOTICE +4 -0
  331. esoi-0.6.0.dist-info/top_level.txt +1 -0
esoi/__init__.py ADDED
@@ -0,0 +1,246 @@
1
+ """esoi: Evolvable Structure that Optimizes Intent (ESOI) as a library and a command.
2
+
3
+ An adopting repository keeps its intent as records (problems, ideals, solutions, implementations, metrics),
4
+ its placement as components, and its measurements as a results log. This package checks them against each
5
+ other (``esoi check``), runs and records evaluations (``esoi run``), ranks implementations
6
+ (``esoi leaderboard``), resolves a selection table at run time and builds a review tracker (``esoi tracker``).
7
+ Everything specific to a repository is configuration (``esoi.toml``).
8
+
9
+ In code, declare a solution once where it lives and call it::
10
+
11
+ from esoi import solution, implementation, override
12
+
13
+ @solution("greet-a-person")
14
+ def greet(name): ...
15
+
16
+ @implementation("greet-a-person", "plain")
17
+ def plain(name): return f"Hello, {name}!"
18
+
19
+ greet("Ada") # the project default, from the records
20
+ greet("Ada", using="loud") # this call only
21
+ with override("greet-a-person", "loud"): ... # a block
22
+
23
+ The public API is this module. Everything a program that embeds esoi imports is named here, so a module can move inside the package without
24
+ breaking a caller: the flat names in ``PUBLIC`` (``from esoi import Assembler``) and the namespaces in ``NAMESPACES``
25
+ (``from esoi import harness`` then ``harness.load_cases``). The package is four containers (``understanding``, ``structure``,
26
+ ``optimization``, ``runtime``), each one folder per solution; import from them only inside esoi. ``tests/test_public_api.py`` resolves
27
+ every name below.
28
+ """
29
+ import importlib
30
+ import types
31
+ from typing import Any, Dict, Tuple
32
+
33
+ from esoi.runtime.implementation_selection.declare import implementation, override, register, resolve, solution
34
+ from esoi.runtime.implementation_selection.selection_registry import SelectionError
35
+
36
+ __version__ = "0.6.0" # the package's version: pyproject.toml carries the same number (a test keeps them equal)
37
+
38
+
39
+ # Flat public names: name -> (module, attribute). A name here may differ from the attribute when the attribute alone would be unclear.
40
+ PUBLIC: Dict[str, Tuple[str, str]] = {
41
+ "AFTER": ("esoi.optimization.keep_metric_record.metric_meter", "AFTER"),
42
+ "Assembler": ("esoi.runtime.assemble_by_name.assemble", "Assembler"),
43
+ "Assembly": ("esoi.runtime.assemble_by_name.assembly", "Assembly"),
44
+ "AssemblyConfig": ("esoi.runtime.assemble_by_name.assembly_config", "AssemblyConfig"),
45
+ "AssemblyError": ("esoi.structure.intent_registry.assembly_errors", "AssemblyError"),
46
+ "BEFORE": ("esoi.optimization.keep_metric_record.metric_meter", "BEFORE"),
47
+ "BudgetExceeded": ("esoi.optimization.when_metrics_are_run.paid_gating", "BudgetExceeded"),
48
+ "CallMeter": ("esoi.optimization.measurement_harness.call_meter", "CallMeter"),
49
+ "Config": ("esoi.structure.intent_registry.config", "Config"),
50
+ "ConsumerOptions": ("esoi.runtime.consumer_check.consumer", "Options"),
51
+ "EVERY_MOMENT": ("esoi.optimization.keep_metric_record.metric_meter", "EVERY_MOMENT"),
52
+ "EntryError": ("esoi.runtime.assemble_by_name.entry_types", "EntryError"),
53
+ "FileMetricLedger": ("esoi.optimization.keep_metric_record.metric_results", "FileMetricLedger"),
54
+ "Lazy": ("esoi.runtime.assemble_by_name.lazy_need", "Lazy"),
55
+ "MAX_METRICS": ("esoi.optimization.keep_metric_record.metric_results", "MAX_METRICS"),
56
+ "MetricIteration": ("esoi.optimization.keep_metric_record.iteration", "MetricIteration"),
57
+ "MetricLedger": ("esoi.optimization.keep_metric_record.metric_results", "MetricLedger"),
58
+ "MetricMeter": ("esoi.optimization.keep_metric_record.metric_meter", "MetricMeter"),
59
+ "MetricResult": ("esoi.optimization.keep_metric_record.metric_results", "MetricResult"),
60
+ "NOT_RECORDED_LINE": ("esoi.optimization.keep_metric_record.metric_results", "NOT_RECORDED_LINE"),
61
+ "Offline": ("esoi.runtime.assemble_by_name.offline_guard", "Offline"),
62
+ "Pending": ("esoi.runtime.assemble_by_name.entry_types", "Pending"),
63
+ "READING_STATUS": ("esoi.optimization.keep_metric_record.iteration", "READING_STATUS"),
64
+ "Registry": ("esoi.structure.intent_registry.registry", "Registry"),
65
+ "RepoSliceSource": ("esoi.optimization.keep_metric_record.spec_slice", "RepoSliceSource"),
66
+ "RequirementEntry": ("esoi.runtime.assemble_by_name.environment_needs.declarations", "Entry"),
67
+ "RuleContext": ("esoi.structure.structure_check.rules.base", "Context"),
68
+ "RuleGroup": ("esoi.structure.structure_check.rules.base", "RuleGroup"),
69
+ "RunError": ("esoi.optimization.measurement_harness.run_errors", "RunError"),
70
+ "RunFiles": ("esoi.optimization.keep_metric_record.metric_results", "RunFiles"),
71
+ "SOURCES": ("esoi.optimization.keep_metric_record.metric_results", "SOURCES"),
72
+ "SOURCE_MEASURED": ("esoi.optimization.keep_metric_record.metric_results", "SOURCE_MEASURED"),
73
+ "SOURCE_NOT_APPLICABLE": ("esoi.optimization.keep_metric_record.metric_results", "SOURCE_NOT_APPLICABLE"),
74
+ "SOURCE_RECORDED": ("esoi.optimization.keep_metric_record.metric_results", "SOURCE_RECORDED"),
75
+ "SliceSource": ("esoi.optimization.keep_metric_record.spec_slice", "SliceSource"),
76
+ "SpecSlice": ("esoi.optimization.keep_metric_record.spec_slice", "SpecSlice"),
77
+ "TagTable": ("esoi.understanding.spec_search.spec_search", "TagTable"),
78
+ "assess_structure_quality": ("esoi.structure.structure_check.rules.structure_quality_rules", "assess_path"),
79
+ "assembly_plan": ("esoi.runtime.assemble_by_name.installation.assembly_plan", "assembly_plan"),
80
+ "call_entry": ("esoi.runtime.assemble_by_name.entry", "call_entry"),
81
+ "check_consumer": ("esoi.runtime.consumer_check.consumer", "check_consumer"),
82
+ "check_headers": ("esoi.structure.intent_registry.records", "check_headers"),
83
+ "check_records": ("esoi.structure.intent_registry.records", "check_records"),
84
+ "check_structure": ("esoi.structure.structure_check.check", "check"),
85
+ "compare_structure_quality": ("esoi.structure.structure_check.rules.structure_quality_rules", "compare_refs"),
86
+ "consumer_cases_hash": ("esoi.runtime.consumer_check.consumer", "cases_hash"),
87
+ "consumer_library_dir": ("esoi.runtime.consumer_check.consumer", "library_dir"),
88
+ "declared_entry": ("esoi.runtime.assemble_by_name.target_lookup", "declared"),
89
+ "describe_metric": ("esoi.optimization.keep_metric_record.spec_slice", "describe_metric"),
90
+ "environ_declared": ("esoi.runtime.assemble_by_name.environ_options", "environ_declared"),
91
+ "environ_fill": ("esoi.runtime.assemble_by_name.environ_options", "environ_fill"),
92
+ "environ_lacking": ("esoi.runtime.assemble_by_name.environ_options", "environ_lacking"),
93
+ "first_arm": ("esoi.structure.intent_registry.registry", "first_arm"),
94
+ "format_value": ("esoi.optimization.keep_metric_record.metric_results", "format_value"),
95
+ "harness_arms": ("esoi.structure.intent_registry.registry", "harness_arms"),
96
+ "index_tokens": ("esoi.understanding.spec_search.spec_index", "tokens"),
97
+ "load": ("esoi.structure.intent_registry.registry", "load"),
98
+ "load_cases": ("esoi.optimization.measurement_harness.case_loading", "load_cases"),
99
+ "load_template": ("esoi.structure.intent_registry.records", "load_template"),
100
+ "meters_from_names": ("esoi.optimization.keep_metric_record.metric_meter", "meters_from_names"),
101
+ "own_code_paths": ("esoi.optimization.when_metrics_are_run.know_what_a_result_measures.code_provenance", "own_code_paths"),
102
+ "parse_tags": ("esoi.structure.intent_registry.fields", "parse_tags"),
103
+ "payload_of": ("esoi.optimization.keep_metric_record.metric_results", "payload_of"),
104
+ "read_csv": ("esoi.structure.intent_registry.tables", "read_csv"),
105
+ "read_tree": ("esoi.structure.intent_registry.intents", "read_tree"),
106
+ "reconcile": ("esoi.optimization.keep_metric_record.metric_results", "reconcile"),
107
+ "record_fields": ("esoi.structure.intent_registry.records", "fields"),
108
+ "render_line": ("esoi.optimization.keep_metric_record.metric_results", "render_line"),
109
+ "run_entry": ("esoi.runtime.assemble_by_name.entry", "run"),
110
+ "served_by_solution": ("esoi.understanding.spec_search.spec_search", "served_by_solution"),
111
+ "split_ids": ("esoi.structure.intent_registry.tables", "ids"),
112
+ "stratified_sample": ("esoi.optimization.measurement_harness.case_loading", "stratified_sample"),
113
+ "tables_of": ("esoi.structure.intent_registry.records", "tables_of"),
114
+ "targets": ("esoi.runtime.assemble_by_name.entry", "targets"),
115
+ "terms_of": ("esoi.understanding.spec_search.spec_search", "terms_of"),
116
+ "views_from_index": ("esoi.understanding.spec_search.spec_search", "views_from_index"),
117
+ "views_from_items": ("esoi.understanding.spec_search.spec_search", "views_from_items"),
118
+ "without_line": ("esoi.optimization.keep_metric_record.metric_results", "without_line"),
119
+ }
120
+
121
+ # Public namespaces: ``from esoi import harness`` gives an object with just these attributes of these modules.
122
+ NAMESPACES: Dict[str, Dict[str, Tuple[str, ...]]] = {
123
+ "access": {
124
+ "esoi.optimization.measurement_harness.access": ('violation',),
125
+ },
126
+ "cascade": {
127
+ "esoi.optimization.leaderboard.cascade_stages": ('load_stages', 'parse'),
128
+ "esoi.optimization.leaderboard.stage_standings": ('stage_index',),
129
+ },
130
+ "config": {
131
+ "esoi.structure.intent_registry.config": ('load',),
132
+ },
133
+ "declarations": {
134
+ "esoi.structure.intent_registry.specify_from_code.declarations": ('code_files', 'drift', 'scan'),
135
+ },
136
+ "entry": {
137
+ "esoi.runtime.assemble_by_name.entry": ('build_handle', 'prepare', 'runner'),
138
+ "esoi.runtime.assemble_by_name.entry_types": ('Pending',),
139
+ "esoi.runtime.assemble_by_name.intent_map": ('snapshot',),
140
+ "esoi.runtime.assemble_by_name.offline_guard": ('Offline',),
141
+ "esoi.runtime.assemble_by_name.readme_example": ('run_block',),
142
+ },
143
+ "evidence": {
144
+ "esoi.optimization.when_metrics_are_run.public_evidence.evidence_grading": ('estimates', 'lines_for_implementation'),
145
+ "esoi.optimization.when_metrics_are_run.public_evidence.evidence_ranking": ('rank',),
146
+ "esoi.optimization.when_metrics_are_run.public_evidence.evidence_records": ('EvidenceError', 'implementation_candidates', 'load', 'load_for'),
147
+ },
148
+ "evidence_table": {
149
+ "esoi.optimization.leaderboard.evidence_table": ('cell', 'cost_label', 'public_label', 'rate_label', 'seconds_label'),
150
+ },
151
+ "expect": {
152
+ "esoi.optimization.measurement_harness.expect": ('aggregate_by_kind', 'check', 'score_kind_case'),
153
+ },
154
+ "foundation": {
155
+ "esoi.optimization.when_metrics_are_run.know_what_a_result_measures.builds_on": ('declared', 'declared_arms', 'problems'),
156
+ },
157
+ "harness": {
158
+ "esoi.optimization.leaderboard.case_identity": ('cases_digest',),
159
+ "esoi.optimization.measurement_harness.arm_loading": ('load_impl',),
160
+ "esoi.optimization.measurement_harness.call_meter": ('CallMeter',),
161
+ "esoi.optimization.measurement_harness.case_loading": ('load_cases',),
162
+ "esoi.optimization.when_metrics_are_run.know_what_a_result_measures.code_provenance": ('current_sha',),
163
+ "esoi.optimization.measurement_harness.component_folder": ('prepare_path',),
164
+ "esoi.optimization.measurement_harness.record_result": ('record_result',),
165
+ "esoi.optimization.measurement_harness.record_slices": ('record_slices',),
166
+ "esoi.optimization.measurement_harness.run_component": ('run_component',),
167
+ "esoi.optimization.when_metrics_are_run.paid_gating": ('declares_paid', 'price_for'),
168
+ },
169
+ "hermetic": {
170
+ "esoi.optimization.measurement_harness.hermetic": ('from_config',),
171
+ },
172
+ "hygiene": {
173
+ "esoi.structure.structure_check.hygiene": ('repo_files', 'scan_repo', 'scan_text'),
174
+ },
175
+ "intents": {
176
+ "esoi.structure.intent_registry.intents": ('RECORD_FILES', 'discover', 'folders', 'read_rows', 'read_tree', 'tree_folders'),
177
+ },
178
+ "leaderboard": {
179
+ "esoi.optimization.leaderboard.arm_kinds": ('arm_kind', 'invariant_reason'),
180
+ "esoi.optimization.leaderboard.arm_selection": ('selected_impls',),
181
+ "esoi.optimization.leaderboard.case_identity": ('cases_digest',),
182
+ "esoi.optimization.leaderboard.held_out_parts": ('part_of', 'part_row', 'selection_leader'),
183
+ "esoi.optimization.leaderboard.ranking": ('pass_rate', 'passes', 'rank'),
184
+ "esoi.optimization.leaderboard.results_log": ('all_results', 'is_partial', 'per_case_rows', 'slice_results'),
185
+ "esoi.optimization.leaderboard.rival_decisions": ('best_guess', 'challengers', 'decisions'),
186
+ "esoi.optimization.leaderboard.switching_policy": ('Policy', 'holdout_fraction', 'policies'),
187
+ "esoi.optimization.leaderboard.verdict_labels": ('slice_verdicts',),
188
+ },
189
+ "lock": {
190
+ "esoi.runtime.implementation_selection.lock": ('diff', 'status', 'update', 'write'),
191
+ },
192
+ "registry": {
193
+ "esoi.structure.intent_registry.registry": ('load',),
194
+ },
195
+ "requirements": {
196
+ "esoi.runtime.assemble_by_name.environment_needs.checking": ('UNMET', 'check'),
197
+ "esoi.runtime.assemble_by_name.environment_needs.closure": ('members_pairs',),
198
+ "esoi.runtime.assemble_by_name.environment_needs.declarations": ('Api', 'Binary', 'Download', 'Entry', 'Env', 'Isolate', 'Python', 'Resource', 'Service', 'api', 'binary', 'declared', 'download', 'env', 'gather', 'isolatable', 'network', 'python', 'resource', 'service'),
199
+ "esoi.runtime.assemble_by_name.environment_needs.generated_files": ('env_template',),
200
+ "esoi.runtime.assemble_by_name.environment_needs.report": ('describe',),
201
+ },
202
+ "scaffold": {
203
+ "esoi.understanding.the_standard.scaffold": ('init',),
204
+ },
205
+ "selection": {
206
+ "esoi.runtime.implementation_selection.declare": ('override', 'register', 'resolve'),
207
+ "esoi.runtime.implementation_selection.selection_cascade": ('choose', 'env_name', 'names', 'snapshot'),
208
+ "esoi.runtime.implementation_selection.selection_registry": ('REGISTRY', 'SelectionError', 'entry_for'),
209
+ },
210
+ "spec_index": {
211
+ "esoi.understanding.spec_search.spec_index": ('build', 'cached', 'find_specs', 'of_intent', 'related', 'show', 'tokens'),
212
+ },
213
+ "spec_search": {
214
+ "esoi.understanding.spec_search.spec_search": ('Found', 'Gate', 'RECORD_CANDIDATE_KINDS', 'RECORD_SOURCE', 'Selection', 'TagTable', 'VectorSearch', 'View', 'fuse', 'gate_decision', 'gated', 'lexical_scored', 'render', 'search', 'terms_of', 'views_from_index', 'views_from_items'),
215
+ },
216
+ "standards_nav": {
217
+ "esoi.understanding.spec_search.standards_nav": ('MAX_SHOWN', 'lint', 'select_for_task'),
218
+ },
219
+ }
220
+
221
+ __all__ = sorted(["SelectionError", "implementation", "override", "register", "resolve", "solution", "run", "__version__", *PUBLIC, *NAMESPACES])
222
+
223
+
224
+ def run(target, input=None, **overrides):
225
+ """One line for any solution or intent of esoi itself: ``esoi.run("structure-check", ".")``. Packages bind the same function
226
+ to their own Assembler (``entry.runner``)."""
227
+ from esoi.runtime.assemble_by_name.interface import own_runner
228
+ return own_runner()(target, input, **overrides)
229
+
230
+
231
+ def __getattr__(name: str) -> Any:
232
+ if name in PUBLIC:
233
+ module, attribute = PUBLIC[name]
234
+ return getattr(importlib.import_module(module), attribute)
235
+ if name in NAMESPACES:
236
+ space = types.SimpleNamespace()
237
+ for module, attributes in NAMESPACES[name].items():
238
+ loaded = importlib.import_module(module)
239
+ for attribute in attributes:
240
+ setattr(space, attribute, getattr(loaded, attribute))
241
+ return space
242
+ raise AttributeError(f"module 'esoi' has no attribute {name!r}")
243
+
244
+
245
+ def __dir__():
246
+ return sorted(set(globals()) | set(__all__))
esoi/__main__.py ADDED
@@ -0,0 +1,89 @@
1
+ """The ``esoi`` command line. Each subcommand is a thin call into the module that owns the behaviour.
2
+
3
+ esoi init [DIR] [--package NAME] scaffold a passing example repository
4
+ esoi check [--strict] [--findings] [--for-decision] [--write-docs] run every rule (esoi rules lists them)
5
+ esoi rules [--markdown] list the rules and what each one means
6
+ esoi template sync|check keep the parsed intent template in step with its source
7
+ esoi skill sync|check|install the public copy of the author's skill: generate, verify, install
8
+ esoi records [check|sync] check only the intent records, or write the rows the code declares and they lack
9
+ esoi records place|gather [--apply] move records beside the code they describe (or into the structure folder); a dry run without --apply
10
+ esoi admit SOLUTION NAME --why TEXT register a newly found technology as an implementation of a solution (a rival with no arm until its code is declared);
11
+ with --changed WHAT instead of NAME: record a justified change to the specification
12
+ esoi new solution ID [--intent ID] a solution in one command: records, code with declarations, evaluation folder
13
+ esoi run COMPONENT --impl NAME [--record] run and record one implementation over a component's cases
14
+ esoi stale --explain COMPONENT | --count which changed files a recorded result measures, and how many rows each staleness rule calls stale
15
+ esoi leaderboard [--strict] rank the implementations of every evaluated solution
16
+ esoi select SOLUTION [--name NAME] show which implementation runs now, and which layer of the cascade chose it
17
+ esoi cascade [SOLUTION] [--strict] a metric's cascading conditionals: each stage's results, the chosen implementation, what to run next
18
+ esoi evidence-table [--file F] Markdown table of arms, Wilson intervals, paired verdicts; written between markers in F
19
+ esoi evidence [list|grade|rank|table] public evidence others measured, graded A to D; complementary, never a result row
20
+ esoi select --promote [SOLUTION] switch `selected` to the rival shown better on the solution's own metric
21
+ esoi select --snapshot FILE write the defaults and modules for a package shipped without the records
22
+ esoi tracker build|check build or verify the review tracker tabs
23
+ esoi consumer check --registry CSV check a consuming repository's integration registry
24
+ esoi fields migrate [--apply] split scoped_purpose into the new solution and metric fields in every records folder (dry run without --apply)
25
+ esoi intent migrate [--apply] move a legacy overall layout to the intent layout (dry run without --apply)
26
+ esoi spec index [--out FILE]|find TEXT [-k N] [--expand N]|show ID [--tier 0|1|2]|related ID [--depth N]|intent [ID] [--cache FILE] the specification index: find the few records a new use case needs
27
+ esoi spec prompt SOLUTION [--task T] [--budget N] [--with CSV] [--json] the prompt for one solution's own consideration, formed from its network of records
28
+ esoi consider TEXT [--solution ID] [--max N] [--list] one generated prompt per solution a change or candidate concerns, and per parent level (JSON)
29
+ esoi projects init|add|list|check|index|where the local ESOI index (a folder named by ESOI_HOME, else ~/.esoi)
30
+ esoi version [--record] the package version, the skill it follows, the template version; --record writes the template version into esoi.toml
31
+ esoi hygiene [--staged] [--history] scan for secrets, machine paths and real addresses
32
+ esoi requirements [--package P | --scope S] [--solution ID] [--check] [--json] [--env-template FILE] [--install-script FILE] what the implementations need from their environment
33
+ esoi install [--package P | --scope S] [--solution ID ...] [--assembly] [--yes] install only what the solutions in use need (dry run without --yes)
34
+ esoi lock [--package P | --scope S] [--file esoi.lock.json] [--update [--safe|--latest]] [--diff] [--status] [--solution ID ...] [--json] pin the selected implementations; see and take newer ones on your schedule
35
+ esoi attest COMPONENT IMPL --reason TEXT [--through SHA] [--author NAME] record that an arm's own code changed but not what its result measures
36
+ esoi docs check|wiki [--out DIR] [--repo-url URL] [--push WIKI_GIT_URL] the four-category docs standard; generate the wiki from docs/
37
+ esoi sheet-sync sync|push|pull|check two-way sync of the tracker with a Google Sheet (esoi[sheets])
38
+
39
+ ``--config PATH`` (before the subcommand) names the configuration file or folder; by default the nearest
40
+ ``esoi.toml`` or ``[tool.esoi]`` table from the current folder upward is used.
41
+ """
42
+ from __future__ import annotations
43
+
44
+ import argparse
45
+ import sys
46
+ from typing import List, Optional
47
+
48
+ from esoi import __version__
49
+ from esoi.optimization import commands as optimization_commands
50
+ from esoi.runtime import commands as runtime_commands
51
+ from esoi.structure import commands as structure_commands
52
+ from esoi.understanding import commands as understanding_commands
53
+
54
+ CONTAINERS = (understanding_commands, structure_commands, optimization_commands, runtime_commands)
55
+
56
+
57
+ def build_parser() -> argparse.ArgumentParser:
58
+ parser = argparse.ArgumentParser(prog="esoi", description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
59
+ parser.add_argument("--config", default=None, help="the config file, or the folder that holds it")
60
+ parser.add_argument("--version", action="version", version=f"esoi {__version__}")
61
+ parser.set_defaults(needs_config=True, package_version=__version__) # the front door names the version; a command reads it from args
62
+ sub = parser.add_subparsers(dest="cmd", required=True)
63
+ for container in CONTAINERS:
64
+ container.register(sub)
65
+ return parser
66
+
67
+
68
+ def main(argv: Optional[List[str]] = None) -> int:
69
+ argv = sys.argv[1:] if argv is None else list(argv)
70
+ if "run" in argv: # everything after `run` belongs to the harness, flags included
71
+ position = argv.index("run")
72
+ args = build_parser().parse_args(argv[:position + 1])
73
+ args.rest = argv[position + 1:]
74
+ else:
75
+ args = build_parser().parse_args(argv)
76
+ config = None
77
+ needs = args.needs_config(args) if callable(args.needs_config) else args.needs_config
78
+ if needs:
79
+ from esoi.structure.intent_registry import config as config_module
80
+ try:
81
+ config = config_module.load(args.config)
82
+ except config_module.ConfigError as exc:
83
+ print(f"esoi: {exc}", file=sys.stderr)
84
+ return 2
85
+ return args.handler(config, args)
86
+
87
+
88
+ if __name__ == "__main__":
89
+ sys.exit(main())
esoi/apply_esoi.py ADDED
@@ -0,0 +1,43 @@
1
+ """The root of esoi: Apply ESOI to a Project. ``esoi.run("apply-esoi", ".")`` calls the four containers in the order the work happens, each
2
+ through its one-line entry: Understanding, Structure, Optimization, Runtime."""
3
+ from typing import Any, Dict, Protocol, runtime_checkable
4
+
5
+ from esoi.optimization.interface import Optimizing
6
+ from esoi.runtime.assemble_by_name.lazy_need import Lazy
7
+ from esoi.runtime.implementation_selection.declare import implementation, solution
8
+ from esoi.structure.interface import Structuring
9
+ from esoi.structure.intent_registry import intents
10
+ from esoi.understanding.interface import Understanding
11
+ from esoi.runtime.interface import RuntimeServing
12
+
13
+
14
+ @solution("apply-esoi", kind="evaluate", entry="review", example=".")
15
+ @runtime_checkable
16
+ class ApplyingEsoi(Protocol):
17
+ """How far a project applies ESOI: one read-only report from each container."""
18
+
19
+ def review(self, project: str) -> Dict[str, Any]: ...
20
+
21
+
22
+ @implementation("apply-esoi", "through-the-four-containers")
23
+ class ThroughTheFourContainers:
24
+ """Understanding, then Structure, then Optimization, then Runtime, each called through its entry."""
25
+
26
+ def __init__(self, understanding: Lazy[Understanding], structure: Lazy[Structuring], optimization: Lazy[Optimizing], runtime: Lazy[RuntimeServing]):
27
+ self.understanding, self.structure, self.optimization, self.runtime = understanding, structure, optimization, runtime
28
+
29
+ def review(self, project: str) -> Dict[str, Any]:
30
+ with intents.session(): # the record folders are found once for the whole review
31
+ return {"understanding": self.understanding.review(project), "structure": self.structure.review(project),
32
+ "optimization": self.optimization.review(project), "runtime": self.runtime.review()}
33
+
34
+
35
+ @implementation("apply-esoi", "documents-only")
36
+ class DocumentsOnly:
37
+ """What applying ESOI by hand needs: Understanding alone, with no checks and no measurements."""
38
+
39
+ def __init__(self, understanding: Lazy[Understanding]):
40
+ self.understanding = understanding
41
+
42
+ def review(self, project: str) -> Dict[str, Any]:
43
+ return {"understanding": self.understanding.review(project)}
esoi/command_table.py ADDED
@@ -0,0 +1,142 @@
1
+ """Build the sub-command parsers of a container from a text table, so each ``commands.py`` states only what is its own: the commands, their
2
+ arguments and their handlers.
3
+
4
+ A table is text. A line that starts at the left edge is a command, ``name | options | help``; each indented line under it is one argument,
5
+ ``flags | options | help``, where flags are comma-separated (``--from`` or a bare ``name`` for a positional) and options are space-separated
6
+ ``key=value`` pairs. The keys are a closed list, and a value is read by what its key means, never by how it looks:
7
+
8
+ * an argument takes ``action``, ``default``, ``choices`` (a comma list, each read by the argument's ``type``), ``type`` (``int``), ``nargs`` (``?``, ``*``, ``+``,
9
+ ``REMAINDER`` or a whole number), ``metavar`` (a comma pair makes a tuple), ``dest``, ``required`` (``True`` or ``False``), and ``group=NAME`` to put arguments in one
10
+ mutually exclusive group;
11
+ * ``default`` is the text after the ``=`` (empty for the empty string, so ``default=8`` is ``"8"`` and ``type=int`` makes ``argparse`` turn it into 8), except the two words
12
+ ``None`` and ``[]``, which are those values;
13
+ * a command takes ``add_help`` and ``needs_config`` (``True`` or ``False``).
14
+
15
+ A key, a value or a handler the table does not allow stops the build with a ``TableError`` that names the line. The handler of a command is the
16
+ ``run_<name>`` function of the module that owns the table (dashes become underscores).
17
+ """
18
+ from __future__ import annotations
19
+
20
+ import argparse
21
+ from typing import Any, Callable, Dict, List, Optional, Tuple
22
+
23
+ TYPES = {"int": int}
24
+ ARGUMENT_KEYS = ("action", "default", "choices", "type", "nargs", "metavar", "dest", "required", "group")
25
+ COMMAND_KEYS = ("add_help", "needs_config")
26
+ NARGS_WORDS = {"?": "?", "*": "*", "+": "+", "REMAINDER": argparse.REMAINDER}
27
+ DEFAULT_WORDS = {"None": None, "[]": []}
28
+
29
+
30
+ class TableError(ValueError):
31
+ """A line of a command table that cannot be built; the message names the line."""
32
+
33
+
34
+ def boolean(text: str, options: Dict[str, Any]) -> bool:
35
+ if text not in ("True", "False"):
36
+ raise TableError(f"a boolean option must be True or False, not {text!r}")
37
+ return text == "True"
38
+
39
+
40
+ def type_of(text: str, options: Dict[str, Any]) -> Callable:
41
+ if text not in TYPES:
42
+ raise TableError(f"type must be one of {', '.join(TYPES)}, not {text!r}")
43
+ return TYPES[text]
44
+
45
+
46
+ def nargs_of(text: str, options: Dict[str, Any]) -> Any:
47
+ if text in NARGS_WORDS:
48
+ return NARGS_WORDS[text]
49
+ if text.isdigit():
50
+ return int(text)
51
+ raise TableError(f"nargs must be ?, *, +, REMAINDER or a whole number, not {text!r}")
52
+
53
+
54
+ def choices_of(text: str, options: Dict[str, Any]) -> list:
55
+ kind = options.get("type", str) # write type= before choices=
56
+ try:
57
+ return [kind(part) for part in text.split(",")]
58
+ except ValueError:
59
+ raise TableError(f"choices {text!r} are not all valid for type {kind.__name__}") from None
60
+
61
+
62
+ def metavar_of(text: str, options: Dict[str, Any]) -> Any:
63
+ return tuple(text.split(",")) if "," in text else text
64
+
65
+
66
+ def default_of(text: str, options: Dict[str, Any]) -> Any:
67
+ return DEFAULT_WORDS.get(text, text)
68
+
69
+
70
+ READERS: Dict[str, Callable[[str, Dict[str, Any]], Any]] = {
71
+ "required": boolean, "add_help": boolean, "needs_config": boolean, "type": type_of, "nargs": nargs_of, "choices": choices_of,
72
+ "metavar": metavar_of, "default": default_of,
73
+ }
74
+
75
+
76
+ def option_value(key: str, text: str, options: Dict[str, Any]) -> Any:
77
+ """One ``key=value`` option as ``argparse`` takes it (text unless the key says otherwise); ``options`` holds the ones read before it on the line."""
78
+ return READERS.get(key, lambda value, read: value)(text, options)
79
+
80
+
81
+ def options_of(text: str, allowed: Tuple[str, ...]) -> Dict[str, Any]:
82
+ """The ``key=value`` pairs of an options field; a key outside ``allowed`` is an error."""
83
+ found: Dict[str, Any] = {}
84
+ for part in text.split():
85
+ key, equals, value = part.partition("=")
86
+ if not equals:
87
+ raise TableError(f"{part!r} is not key=value")
88
+ if key not in allowed:
89
+ raise TableError(f"unknown option {key!r} (allowed: {', '.join(allowed)})")
90
+ found[key] = option_value(key, value, found)
91
+ return found
92
+
93
+
94
+ def split_fields(line: str) -> List[str]:
95
+ """The three fields of a table line: its name or flags, its options and its help."""
96
+ fields = [part.strip() for part in line.strip().split("|", 2)]
97
+ return fields + [""] * (3 - len(fields))
98
+
99
+
100
+ def add_argument(parser: argparse.ArgumentParser, line: str, groups: Dict[str, Any]) -> None:
101
+ flags, text, help_text = split_fields(line)
102
+ options = options_of(text, ARGUMENT_KEYS)
103
+ target = parser
104
+ if "group" in options:
105
+ name = options.pop("group")
106
+ if name not in groups:
107
+ groups[name] = parser.add_mutually_exclusive_group()
108
+ target = groups[name]
109
+ if help_text:
110
+ options["help"] = help_text
111
+ target.add_argument(*flags.split(","), **options)
112
+
113
+
114
+ def add_command(sub, line: str, handlers: Dict[str, Callable], extra: Optional[Dict[str, Dict[str, Any]]]):
115
+ """The sub-parser of one command line of the table."""
116
+ name, text, help_text = split_fields(line)
117
+ options = options_of(text, COMMAND_KEYS)
118
+ handler = handlers.get("run_" + name.replace("-", "_"))
119
+ if handler is None:
120
+ raise TableError(f"command {name!r} has no function run_{name.replace('-', '_')}")
121
+ parser = sub.add_parser(name, help=help_text, add_help=options.pop("add_help", True))
122
+ parser.set_defaults(handler=handler, **options, **(extra or {}).get(name, {}))
123
+ return parser
124
+
125
+
126
+ def register(sub, table: str, handlers: Dict[str, Callable], extra: Optional[Dict[str, Dict[str, Any]]] = None) -> None:
127
+ """Add every command of ``table`` to the sub-parsers ``sub``; ``handlers`` is the owning module's namespace and ``extra`` adds
128
+ ``set_defaults`` values to a command by name (for a value that is code, such as a function of the parsed arguments)."""
129
+ parser = None
130
+ groups: Dict[str, Any] = {}
131
+ for number, line in enumerate(table.splitlines(), 1):
132
+ if not line.strip():
133
+ continue
134
+ try:
135
+ if line[0] != " ":
136
+ parser, groups = add_command(sub, line, handlers, extra), {}
137
+ elif parser is None:
138
+ raise TableError("an argument line comes before any command")
139
+ else:
140
+ add_argument(parser, line, groups)
141
+ except (TableError, argparse.ArgumentError) as exc:
142
+ raise TableError(f"command table line {number} ({line.strip()[:60]!r}): {exc}") from None
@@ -0,0 +1,54 @@
1
+ entity,field_key,question,group,required
2
+ intent,definition,"In ESOI, intents are meaningful containers of a set of specifications. For human understanding, they serve as a personal category of interest or relate to a tangible container such as an organization.",meta,no
3
+ intent,name,What is a specific phrase which distinguishes the topic of the intent from other intents?,specify,yes
4
+ intent,vision_statement,"What is this intent manifesting in present tense? e.g. ""I am ..."" or ""The world is ..."" Any subject and verb can be used.",specify,yes
5
+ intent,opportunities,What are potentials inspired by this intent?,specify,yes
6
+ intent,solution_coherence,What is a paragraph which describes how all the intent's solutions fit together to accomplish the intent's vision statement?,specify,yes
7
+ intent,solution_diagram,"How are solutions connected in the intent's implementation, what is transferred in each edge, and in what direction?",specify,no
8
+ intent,what_it_is_not,"A general category like ""parenting"" or ""career."" An intent is also not an organization itself, rather the container of specification that clarifies why the organization exists (as a solution and implementation within an intent). In this example, different versions of the same organization can be documented as separate alternative implementations.",meta,no
9
+ problem,definition,"A description of what motivated the intent. A challenge, difficulty, or description of how an ideal is not reached.",meta,no
10
+ problem,problem,What is the problem?,specify,yes
11
+ problem,who_has_it,Who or what type of person has the problem?,specify,yes
12
+ problem,why_it_matters,Why does this problem matter?,specify,yes
13
+ problem,why_hard,Why is the problem hard to resolve?,specify,yes
14
+ problem,existing_attempts,What solutions or workarounds already attempt to address the problem?,specify,yes
15
+ problem,what_it_is_not,"A decision, task, recommendation, or component, but all of these can *have* problems.",meta,no
16
+ problem,connects_to,"Ideals that oppose at least one aspect of the problem, Solutions that would solve at least one aspect of the problem",meta,no
17
+ solution,definition,A strategic definition of how one or more problems can be addressed to fulfill the intent.,meta,no
18
+ solution,name,What's a name that describes the type of solution it is?,specify,yes
19
+ solution,description,"What is the solution's unique value proposition, which justifies its existence? (Consider how it differs from other solutions, without explicitly stating anything about other solutions)",specify,yes
20
+ solution,purpose,An inspiring sentence which clarifies the niche of utility that the solution serves without enumerating use cases. Start with a verb and name who or what it serves where relevant.,specify,yes
21
+ solution,approach,"An inspiring sentence which clarifies how the solution solves problems, which applies to every implementation. This is also the solution's human-readable strategy statement. Start with a verb and name no actor (worded like a responsibility).",specify,yes
22
+ solution,out_of_scope,"What type of use cases is the solution intentionally avoiding, which exclusions aren't otherwise apparent or typical? (Don't explicitly name other solutions that aren't in scope)",specify,no
23
+ solution,milestones,"What are the solution's priorities in order? Every solution specifies at least one. Each milestone is a value of one or more metrics, which doesn't have to be the authoritative metric directly but it should relate to it. End condition (optional): Condition for the milestone to no longer be a priority (date or other circumstance), at which point it's archived. Met: Whether the milestone has been reached, and when. Target completion time (optional): Planned completion date and time (which other dependent milestones may rely on). May be a date or a specific minute of a date where precision is needed.",specify,yes
24
+ solution,knowledge,"What knowledge informs the solution's definition or implementations? This can be a list of many items, including chosen assumptions, best guesses, evidence, theories, or perspectives which inform the solution or its implementations.",specify,no
25
+ solution,measures_of_success,"What would indicate the solution is successful? Note: These are metric solutions, with specific fields defined there. However, humans using ESOI may specify this in natural language, which AI can then translate into fully specified metrics.",specify,yes
26
+ solution,tags,"What classifications may be necessary to avoid risk? Risk Addressed: Every tag should name what risk it mitigates, which are linked problems, whether from the same intent as the solution or from other intents (such as R1-R4 below which are problems defined for ESOI). Tags are not problems themselves; they help mitigate structural problems such as through tagging topics or types of technology used. Note: Possible risks (structural problems): R1 (duplication): Adding a new solution that duplicates an existing one. R2 (opportunity): Not leveraging the benefits of an existing solution, such as partial overlap of purpose. R3 (dependency): Not being aware of solutions that need to change definition or implementation due to something else changing. R4 (mistake): Using a solution when it should not be for the particular use case.",specify,no
27
+ solution,parameters,Parameters,interface,no
28
+ solution,inputs,Inputs,interface,no
29
+ solution,outputs,Outputs,interface,no
30
+ solution,effects,Effects (other than outputs),interface,no
31
+ solution,usage_notes,Other information on when and how to use the solution,interface,no
32
+ solution,what_it_is_not,"Fully functional code or solution, but it can be an abstract class, template, or routing which a separate structure solution network defines.",meta,no
33
+ solution,connects_to,"Implementations that build what the solution defines, Metrics that define and implement the solution's measures of success, Problems the solution addresses.",meta,no
34
+ implementation,definition,The built structure which carries out its associated solution; also known as an alternative.,meta,no
35
+ implementation,name,What's a name that distinguishes this implementation from other alternatives?,specify,yes
36
+ implementation,description,"What is the implementation's unique value proposition, to achieve the purpose of its solution? (Consider how it differs from other existing or potential alternatives, without explicitly stating anything about other implementations)",specify,yes
37
+ implementation,advantages,Advantages,specify,yes
38
+ implementation,disadvantages,Disadvantages,specify,yes
39
+ implementation,dependencies,Solutions that the implementation uses. Note: Ideally the ESOI framework used enables automatic dependency awareness.,specify,no
40
+ implementation,what_it_is_not,What end users of the relevant solution directly interact with. The solution provides an interface on top of the implementation. A structure solution defines how solutions will define interfaces.,meta,no
41
+ ideal,definition,"A definition of the future state implied by the intent, in a particular dimension or aspect.",meta,no
42
+ ideal,name,What's a combined noun with adjective that represents the ideal's direction of interest?,specify,yes
43
+ ideal,principle,What does this ideal ask for?,specify,yes
44
+ ideal,state_description,Describe what it would be like to experience this ideal.,specify,yes
45
+ ideal,hints_of_measurement,How would you know this ideal is reached?,specify,yes
46
+ ideal,what_it_is_not,"A practical metric or solution, or technology.",meta,no
47
+ ideal,connects_to,Problems the ideal opposes.,meta,no
48
+ metric,definition,"A practical way to measure the distance between the implementations of a solution and an ideal which the solution was defined to achieve. Alternative implementations are compared via metrics. Consequently, every solution has only one authoritative metric, which can be a combination of multiple metrics or factors with weights that reflect the solution's ideals and purpose. Note: Metrics can also be solutions, as metrics themselves may be refined over time with alternative implementations (including dataset versions). For metrics that cost resources to run, it's recommended to define cascading conditionals.",meta,no
49
+ metric,name,What's a name that clarifies what is being measured?,specify,yes
50
+ metric,purpose,"A statement of what the metric ensures, specifically and comprehensively yet simply stated. This statement does not need to enumerate its current implementation, rather it encapsulates an intention to measure.",specify,yes
51
+ metric,record,What is recorded as the metric to compare implementations?,specify,yes
52
+ metric,disadvantages,"What can the metric not see, or what could it reward wrongly?",specify,no
53
+ metric,cascading_conditionals,"If specified, this ordered list is used when running the authoritative metric and cheaper or prioritized metrics are earlier in the list to determine whether it's worth running subsequent metrics. Each item (conditional) in the list defines (1) the parameters of one of the solution's metrics (e.g. scale, or simulation vs real) and (2) the required value of the metric in order to move onto the next conditional, and optionally (3) other conditions required before it's worth running the metric for that stage of the list. If the metrics are reused with the same parameters across conditionals (each conditional may combine multiple metrics), then this metric is not rerun when executing the subsequent conditional.",specify,no
54
+ metric,expiration,"When do metrics need to be rerun? Never by default, and ESOI projects can have a default which individual metrics can override.",specify,no