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.
- esoi/__init__.py +246 -0
- esoi/__main__.py +89 -0
- esoi/apply_esoi.py +43 -0
- esoi/command_table.py +142 -0
- esoi/data/esoi_template.csv +54 -0
- esoi/data/skill/evolvable-structure/INDEX.md +63 -0
- esoi/data/skill/evolvable-structure/SKILL.md +142 -0
- esoi/data/skill/evolvable-structure/coding/components.md +27 -0
- esoi/data/skill/evolvable-structure/coding/concept_ai_quest_qar.md +36 -0
- esoi/data/skill/evolvable-structure/coding/pipelines_and_experiments.md +39 -0
- esoi/data/skill/evolvable-structure/coding/registry_and_templates.md +34 -0
- esoi/data/skill/evolvable-structure/coding/writealyze.md +48 -0
- esoi/data/skill/evolvable-structure/coding.md +59 -0
- esoi/data/skill/evolvable-structure/other-categories.md +159 -0
- esoi/data/skill/evolvable-structure/principles/difficulties.md +111 -0
- esoi/data/skill/evolvable-structure/principles/documenting.md +85 -0
- esoi/data/skill/evolvable-structure/principles/patterns_change.md +188 -0
- esoi/data/skill/evolvable-structure/principles/patterns_consideration.md +31 -0
- esoi/data/skill/evolvable-structure/principles/patterns_core.md +81 -0
- esoi/data/skill/evolvable-structure/principles/patterns_people.md +70 -0
- esoi/data/skill/evolvable-structure/principles/purpose.md +75 -0
- esoi/data/skill/evolvable-structure/principles/research.md +71 -0
- esoi/data/skill/evolvable-structure/principles/vocabulary.md +68 -0
- esoi/data/skill/evolvable-structure/principles.md +91 -0
- esoi/data/skill/evolvable-structure/python_tools.md +72 -0
- esoi/data/skill/evolvable-structure/sources/INDEX.md +39 -0
- esoi/data/skill/evolvable-structure/sources/agentic_frameworks.md +152 -0
- esoi/data/skill/evolvable-structure/sources/cantr_governance_proposals.md +163 -0
- esoi/data/skill/evolvable-structure/sources/components_research.md +145 -0
- esoi/data/skill/evolvable-structure/sources/definitions_and_advice.md +209 -0
- esoi/data/skill/evolvable-structure/sources/evolutionary_architecture_talk.md +119 -0
- esoi/data/skill/evolvable-structure/sources/public_research.md +214 -0
- esoi/data/skill/evolvable-structure/sources/trello_project_documentation.md +261 -0
- esoi/data/skill/evolvable-structure/steps.md +194 -0
- esoi/data/skill_version.json +58 -0
- esoi/esoi_selection.json +412 -0
- esoi/optimization/__init__.py +0 -0
- esoi/optimization/commands.py +160 -0
- esoi/optimization/flow.py +37 -0
- esoi/optimization/interface.py +12 -0
- esoi/optimization/keep_metric_record/__init__.py +0 -0
- esoi/optimization/keep_metric_record/interface.py +35 -0
- esoi/optimization/keep_metric_record/iteration.py +145 -0
- esoi/optimization/keep_metric_record/metric_meter.py +276 -0
- esoi/optimization/keep_metric_record/metric_results.py +368 -0
- esoi/optimization/keep_metric_record/spec_slice.py +269 -0
- esoi/optimization/leaderboard/__init__.py +0 -0
- esoi/optimization/leaderboard/arm_kinds.py +45 -0
- esoi/optimization/leaderboard/arm_selection.py +44 -0
- esoi/optimization/leaderboard/board_report.py +174 -0
- esoi/optimization/leaderboard/cascade_report.py +145 -0
- esoi/optimization/leaderboard/cascade_stages.py +336 -0
- esoi/optimization/leaderboard/case_identity.py +82 -0
- esoi/optimization/leaderboard/evidence_table.py +226 -0
- esoi/optimization/leaderboard/held_out_parts.py +109 -0
- esoi/optimization/leaderboard/inherited_gate.py +55 -0
- esoi/optimization/leaderboard/interface.py +34 -0
- esoi/optimization/leaderboard/lock_evidence.py +51 -0
- esoi/optimization/leaderboard/ranking.py +95 -0
- esoi/optimization/leaderboard/results_log.py +101 -0
- esoi/optimization/leaderboard/rival_decisions.py +215 -0
- esoi/optimization/leaderboard/rival_pairing.py +84 -0
- esoi/optimization/leaderboard/stage_standings.py +204 -0
- esoi/optimization/leaderboard/stats.py +203 -0
- esoi/optimization/leaderboard/switching_policy.py +77 -0
- esoi/optimization/leaderboard/verdict_labels.py +82 -0
- esoi/optimization/measurement_harness/__init__.py +0 -0
- esoi/optimization/measurement_harness/access.py +111 -0
- esoi/optimization/measurement_harness/arm_loading.py +102 -0
- esoi/optimization/measurement_harness/balance.py +74 -0
- esoi/optimization/measurement_harness/call_meter.py +156 -0
- esoi/optimization/measurement_harness/case_count.py +14 -0
- esoi/optimization/measurement_harness/case_loading.py +91 -0
- esoi/optimization/measurement_harness/cassette.py +132 -0
- esoi/optimization/measurement_harness/check_guards.py +56 -0
- esoi/optimization/measurement_harness/component_folder.py +43 -0
- esoi/optimization/measurement_harness/discriminating_cases/__init__.py +0 -0
- esoi/optimization/measurement_harness/discriminating_cases/interface.py +23 -0
- esoi/optimization/measurement_harness/expect.py +95 -0
- esoi/optimization/measurement_harness/foundation_parts.py +228 -0
- esoi/optimization/measurement_harness/hermetic.py +41 -0
- esoi/optimization/measurement_harness/interface.py +53 -0
- esoi/optimization/measurement_harness/mutation_score.py +66 -0
- esoi/optimization/measurement_harness/offline_guard.py +116 -0
- esoi/optimization/measurement_harness/per_case_log.py +82 -0
- esoi/optimization/measurement_harness/record_result.py +58 -0
- esoi/optimization/measurement_harness/record_slices.py +96 -0
- esoi/optimization/measurement_harness/rerun_stale.py +203 -0
- esoi/optimization/measurement_harness/run_arguments.py +84 -0
- esoi/optimization/measurement_harness/run_cases.py +78 -0
- esoi/optimization/measurement_harness/run_command.py +38 -0
- esoi/optimization/measurement_harness/run_component.py +306 -0
- esoi/optimization/measurement_harness/run_cost.py +25 -0
- esoi/optimization/measurement_harness/run_errors.py +14 -0
- esoi/optimization/promote_the_winner/__init__.py +0 -0
- esoi/optimization/promote_the_winner/interface.py +26 -0
- esoi/optimization/promote_the_winner/promote.py +409 -0
- esoi/optimization/when_metrics_are_run/__init__.py +0 -0
- esoi/optimization/when_metrics_are_run/interface.py +31 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/__init__.py +0 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/attest.py +156 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/builds_on.py +166 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/code_changed.py +25 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/code_provenance.py +85 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/import_scan.py +184 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/import_world.py +136 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/interface.py +12 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/ownership_index.py +135 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/stale_reasons.py +115 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/stale_scope.py +174 -0
- esoi/optimization/when_metrics_are_run/know_what_a_result_measures/staleness.py +152 -0
- esoi/optimization/when_metrics_are_run/paid_gating.py +73 -0
- esoi/optimization/when_metrics_are_run/public_evidence/__init__.py +0 -0
- esoi/optimization/when_metrics_are_run/public_evidence/evidence_grading.py +362 -0
- esoi/optimization/when_metrics_are_run/public_evidence/evidence_ranking.py +207 -0
- esoi/optimization/when_metrics_are_run/public_evidence/evidence_records.py +241 -0
- esoi/optimization/when_metrics_are_run/public_evidence/evidence_report.py +106 -0
- esoi/optimization/when_metrics_are_run/public_evidence/grading_table.py +75 -0
- esoi/optimization/when_metrics_are_run/public_evidence/interface.py +6 -0
- esoi/optimization/when_metrics_are_run/run_guards.py +232 -0
- esoi/optimization/when_metrics_are_run/run_log.py +128 -0
- esoi/runtime/__init__.py +0 -0
- esoi/runtime/assemble_by_name/__init__.py +0 -0
- esoi/runtime/assemble_by_name/arm_inspection.py +46 -0
- esoi/runtime/assemble_by_name/arm_ranking.py +65 -0
- esoi/runtime/assemble_by_name/assemble.py +481 -0
- esoi/runtime/assemble_by_name/assembly.py +75 -0
- esoi/runtime/assemble_by_name/assembly_config.py +37 -0
- esoi/runtime/assemble_by_name/build_parts.py +130 -0
- esoi/runtime/assemble_by_name/cascade_layers.py +79 -0
- esoi/runtime/assemble_by_name/closure.py +53 -0
- esoi/runtime/assemble_by_name/declared_needs.py +51 -0
- esoi/runtime/assemble_by_name/dependency_graph.py +82 -0
- esoi/runtime/assemble_by_name/entry.py +206 -0
- esoi/runtime/assemble_by_name/entry_check.py +46 -0
- esoi/runtime/assemble_by_name/entry_cli.py +65 -0
- esoi/runtime/assemble_by_name/entry_outcome.py +70 -0
- esoi/runtime/assemble_by_name/entry_types.py +44 -0
- esoi/runtime/assemble_by_name/environ_options.py +44 -0
- esoi/runtime/assemble_by_name/environment_needs/__init__.py +0 -0
- esoi/runtime/assemble_by_name/environment_needs/api_links.py +17 -0
- esoi/runtime/assemble_by_name/environment_needs/checking.py +223 -0
- esoi/runtime/assemble_by_name/environment_needs/closure.py +150 -0
- esoi/runtime/assemble_by_name/environment_needs/declarations.py +361 -0
- esoi/runtime/assemble_by_name/environment_needs/generated_files.py +166 -0
- esoi/runtime/assemble_by_name/environment_needs/python_specs.py +57 -0
- esoi/runtime/assemble_by_name/environment_needs/report.py +77 -0
- esoi/runtime/assemble_by_name/environment_needs/source_location.py +20 -0
- esoi/runtime/assemble_by_name/hierarchy.py +178 -0
- esoi/runtime/assemble_by_name/installation/__init__.py +0 -0
- esoi/runtime/assemble_by_name/installation/assembly_plan.py +74 -0
- esoi/runtime/assemble_by_name/installation/command_running.py +46 -0
- esoi/runtime/assemble_by_name/installation/conflicts.py +144 -0
- esoi/runtime/assemble_by_name/installation/execution.py +181 -0
- esoi/runtime/assemble_by_name/installation/install_lock.py +50 -0
- esoi/runtime/assemble_by_name/installation/plan.py +67 -0
- esoi/runtime/assemble_by_name/installation/plan_report.py +54 -0
- esoi/runtime/assemble_by_name/installation/resolution_ladder.py +171 -0
- esoi/runtime/assemble_by_name/installation/resolvers.py +46 -0
- esoi/runtime/assemble_by_name/intent_map.py +114 -0
- esoi/runtime/assemble_by_name/interface.py +40 -0
- esoi/runtime/assemble_by_name/lazy_need.py +37 -0
- esoi/runtime/assemble_by_name/lock_file.py +59 -0
- esoi/runtime/assemble_by_name/offline_guard.py +36 -0
- esoi/runtime/assemble_by_name/packaged_records.py +74 -0
- esoi/runtime/assemble_by_name/pending_needs.py +90 -0
- esoi/runtime/assemble_by_name/project_runner.py +29 -0
- esoi/runtime/assemble_by_name/readme_example.py +164 -0
- esoi/runtime/assemble_by_name/seat_blockers.py +100 -0
- esoi/runtime/assemble_by_name/target_lookup.py +57 -0
- esoi/runtime/commands.py +265 -0
- esoi/runtime/consumer_check/__init__.py +0 -0
- esoi/runtime/consumer_check/consumer.py +425 -0
- esoi/runtime/consumer_check/follow.py +397 -0
- esoi/runtime/consumer_check/interface.py +28 -0
- esoi/runtime/flow.py +31 -0
- esoi/runtime/implementation_selection/__init__.py +0 -0
- esoi/runtime/implementation_selection/declare.py +164 -0
- esoi/runtime/implementation_selection/interface.py +25 -0
- esoi/runtime/implementation_selection/lock.py +328 -0
- esoi/runtime/implementation_selection/lock_command.py +91 -0
- esoi/runtime/implementation_selection/select.py +172 -0
- esoi/runtime/implementation_selection/selection_cascade.py +273 -0
- esoi/runtime/implementation_selection/selection_registry.py +147 -0
- esoi/runtime/implementation_selection/variants.py +75 -0
- esoi/runtime/interface.py +12 -0
- esoi/structure/__init__.py +0 -0
- esoi/structure/commands.py +235 -0
- esoi/structure/flow.py +50 -0
- esoi/structure/intent_registry/__init__.py +0 -0
- esoi/structure/intent_registry/admit.py +112 -0
- esoi/structure/intent_registry/assembly_errors.py +11 -0
- esoi/structure/intent_registry/besidecode.py +342 -0
- esoi/structure/intent_registry/circumstances.py +160 -0
- esoi/structure/intent_registry/config.py +297 -0
- esoi/structure/intent_registry/fields.py +278 -0
- esoi/structure/intent_registry/implementedby.py +141 -0
- esoi/structure/intent_registry/import_base.py +23 -0
- esoi/structure/intent_registry/intents.py +249 -0
- esoi/structure/intent_registry/interface.py +46 -0
- esoi/structure/intent_registry/migrate.py +165 -0
- esoi/structure/intent_registry/name_check.py +21 -0
- esoi/structure/intent_registry/parsed_source.py +52 -0
- esoi/structure/intent_registry/records.py +551 -0
- esoi/structure/intent_registry/registry.py +129 -0
- esoi/structure/intent_registry/specify_from_code/__init__.py +0 -0
- esoi/structure/intent_registry/specify_from_code/declarations.py +368 -0
- esoi/structure/intent_registry/specify_from_code/interface.py +26 -0
- esoi/structure/intent_registry/specify_from_code/newsolution.py +115 -0
- esoi/structure/intent_registry/tables.py +110 -0
- esoi/structure/intent_registry/template_sync/__init__.py +0 -0
- esoi/structure/intent_registry/template_sync/interface.py +28 -0
- esoi/structure/intent_registry/template_sync/template.py +282 -0
- esoi/structure/intent_registry/template_sync/templates.py +489 -0
- esoi/structure/intent_registry/template_sync/versioning.py +275 -0
- esoi/structure/interface.py +12 -0
- esoi/structure/library_adoption/__init__.py +0 -0
- esoi/structure/library_adoption/interface.py +26 -0
- esoi/structure/library_adoption/resolve.py +120 -0
- esoi/structure/ownership_map/__init__.py +0 -0
- esoi/structure/ownership_map/interface.py +25 -0
- esoi/structure/structure_budget/__init__.py +0 -0
- esoi/structure/structure_budget/interface.py +26 -0
- esoi/structure/structure_check/__init__.py +0 -0
- esoi/structure/structure_check/check.py +187 -0
- esoi/structure/structure_check/coherence.py +370 -0
- esoi/structure/structure_check/coherence_code_evidence.py +363 -0
- esoi/structure/structure_check/coherence_paragraph.py +216 -0
- esoi/structure/structure_check/coherence_records.py +18 -0
- esoi/structure/structure_check/hygiene.py +224 -0
- esoi/structure/structure_check/interface.py +31 -0
- esoi/structure/structure_check/ratchet.py +242 -0
- esoi/structure/structure_check/rules/__init__.py +75 -0
- esoi/structure/structure_check/rules/adoption_rules.py +122 -0
- esoi/structure/structure_check/rules/base.py +164 -0
- esoi/structure/structure_check/rules/beside_rules.py +231 -0
- esoi/structure/structure_check/rules/cascade_rules.py +98 -0
- esoi/structure/structure_check/rules/consideration_rules.py +88 -0
- esoi/structure/structure_check/rules/declarations.py +25 -0
- esoi/structure/structure_check/rules/entry_rules.py +489 -0
- esoi/structure/structure_check/rules/foundation_rules.py +68 -0
- esoi/structure/structure_check/rules/generated.py +143 -0
- esoi/structure/structure_check/rules/hierarchy_rules.py +54 -0
- esoi/structure/structure_check/rules/intents.py +340 -0
- esoi/structure/structure_check/rules/layout.py +180 -0
- esoi/structure/structure_check/rules/measurement.py +355 -0
- esoi/structure/structure_check/rules/modulefacts.py +174 -0
- esoi/structure/structure_check/rules/one_criterion.py +218 -0
- esoi/structure/structure_check/rules/registry_rules.py +229 -0
- esoi/structure/structure_check/rules/structure_quality_rules.py +79 -0
- esoi/structure/structure_check/rules/version_rules.py +41 -0
- esoi/structure/structure_check/rules/wording.py +112 -0
- esoi/structure/structure_quality/__init__.py +0 -0
- esoi/structure/structure_quality/adopted.py +73 -0
- esoi/structure/structure_quality/assess.py +24 -0
- esoi/structure/structure_quality/balance.py +117 -0
- esoi/structure/structure_quality/behavior.py +63 -0
- esoi/structure/structure_quality/cochange.py +71 -0
- esoi/structure/structure_quality/compare.py +159 -0
- esoi/structure/structure_quality/complexity.py +36 -0
- esoi/structure/structure_quality/conformance.py +204 -0
- esoi/structure/structure_quality/coupling.py +371 -0
- esoi/structure/structure_quality/duplication.py +120 -0
- esoi/structure/structure_quality/expert_review.py +63 -0
- esoi/structure/structure_quality/flow.py +27 -0
- esoi/structure/structure_quality/foundation.py +89 -0
- esoi/structure/structure_quality/interface.py +59 -0
- esoi/structure/structure_quality/overlap.py +28 -0
- esoi/structure/structure_quality/project.py +262 -0
- esoi/structure/structure_quality/protocol_groups.py +119 -0
- esoi/structure/structure_quality/report.py +35 -0
- esoi/structure/structure_quality/scope.py +252 -0
- esoi/structure/structure_quality/size.py +99 -0
- esoi/structure/structure_quality/surface.py +152 -0
- esoi/understanding/__init__.py +0 -0
- esoi/understanding/commands.py +352 -0
- esoi/understanding/esoi_for_ai/__init__.py +0 -0
- esoi/understanding/esoi_for_ai/behaviour.py +76 -0
- esoi/understanding/esoi_for_ai/command_provider.py +39 -0
- esoi/understanding/esoi_for_ai/esoi_behaviour_judge/__init__.py +0 -0
- esoi/understanding/esoi_for_ai/esoi_behaviour_judge/behaviour_judge.py +55 -0
- esoi/understanding/esoi_for_ai/esoi_behaviour_judge/interface.py +24 -0
- esoi/understanding/esoi_for_ai/interface.py +34 -0
- esoi/understanding/flow.py +44 -0
- esoi/understanding/interface.py +12 -0
- esoi/understanding/local_application_index/__init__.py +0 -0
- esoi/understanding/local_application_index/interface.py +25 -0
- esoi/understanding/local_application_index/projects.py +412 -0
- esoi/understanding/readable_records/__init__.py +0 -0
- esoi/understanding/readable_records/diagram.py +128 -0
- esoi/understanding/readable_records/interface.py +48 -0
- esoi/understanding/readable_records/readme.py +93 -0
- esoi/understanding/readable_records/readme_adopted.py +53 -0
- esoi/understanding/readable_records/readme_folder_page.py +236 -0
- esoi/understanding/readable_records/readme_intent_page.py +240 -0
- esoi/understanding/readable_records/readme_trail.py +117 -0
- esoi/understanding/readable_records/readme_view.py +198 -0
- esoi/understanding/review_tracker/__init__.py +0 -0
- esoi/understanding/review_tracker/interface.py +29 -0
- esoi/understanding/review_tracker/sheets.py +342 -0
- esoi/understanding/review_tracker/tracker.py +372 -0
- esoi/understanding/solution_consideration/__init__.py +0 -0
- esoi/understanding/solution_consideration/fan_out.py +67 -0
- esoi/understanding/solution_consideration/knowledge.py +300 -0
- esoi/understanding/solution_consideration/network_records.py +155 -0
- esoi/understanding/solution_consideration/solution_prompt.py +543 -0
- esoi/understanding/solution_relevance/__init__.py +0 -0
- esoi/understanding/solution_relevance/relevance.py +139 -0
- esoi/understanding/solution_relevance/relevance_cases.py +159 -0
- esoi/understanding/spec_search/__init__.py +0 -0
- esoi/understanding/spec_search/spec_index.py +336 -0
- esoi/understanding/spec_search/spec_search.py +532 -0
- esoi/understanding/spec_search/standards_check.py +172 -0
- esoi/understanding/spec_search/standards_measure.py +251 -0
- esoi/understanding/spec_search/standards_nav.py +370 -0
- esoi/understanding/the_standard/__init__.py +0 -0
- esoi/understanding/the_standard/docs.py +237 -0
- esoi/understanding/the_standard/interface.py +37 -0
- esoi/understanding/the_standard/scaffold.py +351 -0
- esoi/understanding/the_standard/skill_distribution/__init__.py +0 -0
- esoi/understanding/the_standard/skill_distribution/interface.py +27 -0
- esoi/understanding/the_standard/skill_distribution/skill.py +419 -0
- esoi/understanding/the_standard/the_steps/__init__.py +0 -0
- esoi/understanding/the_standard/the_steps/interface.py +25 -0
- esoi-0.6.0.dist-info/METADATA +123 -0
- esoi-0.6.0.dist-info/RECORD +331 -0
- esoi-0.6.0.dist-info/WHEEL +5 -0
- esoi-0.6.0.dist-info/entry_points.txt +2 -0
- esoi-0.6.0.dist-info/licenses/LICENSE +201 -0
- esoi-0.6.0.dist-info/licenses/NOTICE +4 -0
- 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
|