gea-program 0.89.0__tar.gz → 0.90.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.89.0/gea_program.egg-info → gea_program-0.90.0}/PKG-INFO +61 -4
- {gea_program-0.89.0 → gea_program-0.90.0}/README.md +60 -3
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/__init__.py +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/__main__.py +65 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/acceptance_tests.py +214 -7
- gea_program-0.90.0/gea/benchmark.py +272 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dysfunction.py +27 -9
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/edr.py +73 -6
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/IT_SECURITY.md +5 -1
- gea_program-0.90.0/gea/help/benchmark.md +13 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/driller.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/dysfunction.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/edr.md +3 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/install.md +2 -2
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/mcp.md +1 -1
- gea_program-0.90.0/gea/help/public-data.md +15 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/reader.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/recorder.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/roadmap.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/01-install.md +2 -2
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/13-drilling-pages.md +10 -8
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/19-dossier-reader.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/22-updates.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/23-vpn.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/25-install-recorder.md +2 -2
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/29-driller-rig.md +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial.md +2 -2
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/helplib.py +3 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/mcp_server.py +7 -0
- gea_program-0.90.0/gea/public_pad.py +603 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/rig_state.py +5 -2
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/roadmap.py +26 -7
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/service.py +23 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/web/app.html +58 -1
- {gea_program-0.89.0 → gea_program-0.90.0/gea_program.egg-info}/PKG-INFO +61 -4
- {gea_program-0.89.0 → gea_program-0.90.0}/gea_program.egg-info/SOURCES.txt +4 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/pyproject.toml +1 -1
- {gea_program-0.89.0 → gea_program-0.90.0}/LICENSE +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/alerts.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/backup.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/bench.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/bit_seismic.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/blind_harness.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/calibration.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/casing_design.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog_map.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/catalog_register.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/certificates.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/cli.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/client_reports.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/collision.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/config_versioning.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/conformance.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/control_room.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/correlation.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dashboard.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/declarations.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/decline.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/deviation.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dlis.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dnp3.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/doctor.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dossier.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/drill_string.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/driller_link.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/earth_model.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/economics.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/ed25519.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/elevation.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/etp.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/example_register_map.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fat_sat.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/field_pull.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/files.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/fluid.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/follower.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/forward_model.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/frac_hits.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/friction_priors.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/front.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/gamma.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/geodesy.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/geomag.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/hartip.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/alarms.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/alerts.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/backup.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/bit-image.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/calibration.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/casing.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/catalog.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/charts.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/collision.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/conformance.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/control-room.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/data-in.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/declare.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/decline.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/dlis.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/doctor.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/dossier.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/drift.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/economics.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/etp.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/files.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/fluid.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/front.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/historian.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/https.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/instruments.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/interval.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/map.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/month-end.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/notifications.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/opseis.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/osdu.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/patches.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/plan.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/plume.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/quality.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/records.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/report-history.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/rocks.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/seismic.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/setup.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/simulation.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/site.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/sites.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/slip.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/soak.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/sra.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/start.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/structure.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tools.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/transients.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/02-sign-in.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/03-site.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/04-add-well.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/05-records.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/06-well-page.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/07-declare.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/08-patches.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/09-alarms.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/10-control-room.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/11-summary-month.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/12-where-the-well-is.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/14-production-pages.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/15-seismic.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/16-seismicity.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/17-recorder-office.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/18-reports.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/20-admin.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/21-upkeep.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/24-the-box.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/26-monitor.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/27-mirror-vpn.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/tutorial/28-driller-office.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/vibration.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/vpn.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/well-report.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/help/well3d.md +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/housekeeping.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/hydraulics.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/icon.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/interval.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/invoice_check.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/jobs.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/launcher.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/live_ports.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/loadtest.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/modbus.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/model_card.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/month_end.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/notify.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/oidc.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/opcua_port.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/operator_app.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/osdu.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/pad_summary.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/patches.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/pdf_report.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/penetrator.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/permits.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/piwebapi.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/plume.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/ports.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/ppdm.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/project.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/quakeml.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reader.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reader_app.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reconciler.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/recorder_link.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/report_history.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sample_record.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sbom.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seedlink.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/segy.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_array.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_film.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_response.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_track.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/series_cache.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/service_life.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/shapefile.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/shell.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/shut_in.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/simulation.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/site_map.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sla_report.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/slip.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/soak.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/sra.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/store_forward.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/strata_join.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/structure.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/supervisor.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/survey_view.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/telemetry.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/timestamp.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tls.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tool_library.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/torque_drag.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/transient.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tray.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/tutorial.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/updates.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/vibration.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/vpn.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/web/reader.html +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/well3d.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/well_assembler.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/well_records.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/well_report.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/wellplan.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/wellpos.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/winident.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/wits0.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/witsml.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/workspace.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/workspaces.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/x25519.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/setup.cfg +0 -0
- {gea_program-0.89.0 → gea_program-0.90.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.90.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -847,7 +847,7 @@ unsigned, the key hand-overs - and shows the reports as they were signed. A
|
|
|
847
847
|
reader made from the workspace knows the site's key fingerprints, so it
|
|
848
848
|
says whether a dossier is the site's; it allows no network request, and it
|
|
849
849
|
leaves the trusted time-stamp to `verify_dossier.py`. For a client who wants
|
|
850
|
-
it installed, every release also carries `GEA-Reader-Setup-0.
|
|
850
|
+
it installed, every release also carries `GEA-Reader-Setup-0.90.0.exe`: GEA
|
|
851
851
|
Reader as a Windows program of its own - its own icon and taskbar button,
|
|
852
852
|
Check with GEA Reader on a dossier's right-click menu, fingerprints the client
|
|
853
853
|
saves kept on that computer, nothing of GEA-Program. `gea help reader`.
|
|
@@ -1073,6 +1073,63 @@ eras of the protocol are spoken: the stateless revision 2026-07-28 and the
|
|
|
1073
1073
|
`initialize` handshake of 2025-11-25 and earlier. The **Assistant access**
|
|
1074
1074
|
tab (one button adds it to Claude Desktop), `gea mcp`, `gea help mcp`.
|
|
1075
1075
|
|
|
1076
|
+
### Benchmark
|
|
1077
|
+
|
|
1078
|
+
The wells of a pad against one another, and each against the best the pad
|
|
1079
|
+
has done. Every well with a drilling record is measured the same way from
|
|
1080
|
+
its own record - the footage, the days from its first stand to its last,
|
|
1081
|
+
feet per day, the rate on bottom, rotary and sliding, the median connection
|
|
1082
|
+
weight to weight, the trip speeds - and ranked on each count. Then each
|
|
1083
|
+
well is set against the pad's best: the well it would have been had every
|
|
1084
|
+
stretch of hole been drilled at the rate of whichever well was fastest
|
|
1085
|
+
through that stretch (300 ft or more of it), and every connection made in
|
|
1086
|
+
the pad's best quarter. The gap is hours the pad has already shown can be
|
|
1087
|
+
saved, on some well in that stretch - not a forecast, and not a cause: the
|
|
1088
|
+
bit, the motor, the mud and the hole size are not in the record. The
|
|
1089
|
+
**Benchmark** tab, `gea benchmark`, `gea help benchmark`; an assistant
|
|
1090
|
+
reads it as the `benchmark` tool.
|
|
1091
|
+
|
|
1092
|
+
### Public data: a real pad
|
|
1093
|
+
|
|
1094
|
+
A pad anyone may check. The Utah FORGE project - the U.S. Department of
|
|
1095
|
+
Energy's geothermal field laboratory near Milford, Utah - publishes the
|
|
1096
|
+
rig recorders of five wells drilled through the same basin fill and
|
|
1097
|
+
granite between 2017 and 2023, under Creative Commons Attribution 4.0.
|
|
1098
|
+
`gea public-pad` turns those files into a site of its own, so the rig
|
|
1099
|
+
time, the roadmap, the drilling alerts and the benchmark run on real
|
|
1100
|
+
records before any client's. The program does not contain the files and
|
|
1101
|
+
does not fetch them: the site downloads them in a browser from the
|
|
1102
|
+
Geothermal Data Repository, names the folder, and the program checks each
|
|
1103
|
+
file against the size and the SHA-256 it had when this release was checked
|
|
1104
|
+
with it, converts the three layouts that are not the recorder's own
|
|
1105
|
+
export, attaches each well, and keeps on the record what was done to
|
|
1106
|
+
each - 16A(78)-32's bit depth is RECONSTRUCTED from the block and the
|
|
1107
|
+
slips and is marked so on every page. Every page and report of that site
|
|
1108
|
+
ends with the credit the licence asks for.
|
|
1109
|
+
|
|
1110
|
+
What this release made of them, on the five files as published:
|
|
1111
|
+
|
|
1112
|
+
| Well | Drilled, ft | Days | ft/day | On bottom, ft/h | Median connection, min |
|
|
1113
|
+
|---|---|---|---|---|---|
|
|
1114
|
+
| 58-32 (2017) | 6,288 | 43.5 | 145 | 15.9 | 14.4 |
|
|
1115
|
+
| 16A(78)-32 (2020) | 11,035 | 67.8 | 163 | 34.4 | 11.3 |
|
|
1116
|
+
| 56-32 (2021) | 9,232 | 19.0 | 487 | 46.6 | 7.5 |
|
|
1117
|
+
| 78B-32 (2021) | 9,372 | 29.1 | 322 | 84.7 | 7.7 |
|
|
1118
|
+
| 16B(78)-32 (2023) | 10,490 | 52.4 | 200 | 45.7 | 10.2 |
|
|
1119
|
+
|
|
1120
|
+
Against the pad's best the five wells spent 812 of their 1,256 on-bottom
|
|
1121
|
+
hours beyond it. The roadmap's own check on them is split - running nearer
|
|
1122
|
+
the window was the faster half on two wells and the slower on two - which
|
|
1123
|
+
is the page saying, of wells drilled six years apart in three hole sizes,
|
|
1124
|
+
that one well's parameters are not the next well's roadmap. The drilling
|
|
1125
|
+
alerts, replayed, find 27 motor stalls on the three wells whose records
|
|
1126
|
+
can show one, three falls in off-bottom pressure on 78B-32 that no trip followed
|
|
1127
|
+
and one on 58-32 that a trip out of the hole followed within twelve hours.
|
|
1128
|
+
Data: Utah FORGE, Energy & Geoscience Institute at the University of Utah,
|
|
1129
|
+
funded by the U.S. Department of Energy; Geothermal Data Repository,
|
|
1130
|
+
gdr.openei.org; CC BY 4.0. The **Public data** tab, `gea public-pad`,
|
|
1131
|
+
`gea help public-data`.
|
|
1132
|
+
|
|
1076
1133
|
### Plan vs actual and the survey tools
|
|
1077
1134
|
|
|
1078
1135
|
Each well against its directional plan: at every survey station, how far
|
|
@@ -1737,7 +1794,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1737
1794
|
|
|
1738
1795
|
### The Windows installer
|
|
1739
1796
|
|
|
1740
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1797
|
+
Every release also carries `GEA-Program-Setup-0.90.0.exe` (for 0.90.0): the
|
|
1741
1798
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1742
1799
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1743
1800
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1756,7 +1813,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1756
1813
|
software deployment:
|
|
1757
1814
|
|
|
1758
1815
|
```
|
|
1759
|
-
GEA-Program-Setup-0.
|
|
1816
|
+
GEA-Program-Setup-0.90.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1760
1817
|
```
|
|
1761
1818
|
|
|
1762
1819
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -808,7 +808,7 @@ unsigned, the key hand-overs - and shows the reports as they were signed. A
|
|
|
808
808
|
reader made from the workspace knows the site's key fingerprints, so it
|
|
809
809
|
says whether a dossier is the site's; it allows no network request, and it
|
|
810
810
|
leaves the trusted time-stamp to `verify_dossier.py`. For a client who wants
|
|
811
|
-
it installed, every release also carries `GEA-Reader-Setup-0.
|
|
811
|
+
it installed, every release also carries `GEA-Reader-Setup-0.90.0.exe`: GEA
|
|
812
812
|
Reader as a Windows program of its own - its own icon and taskbar button,
|
|
813
813
|
Check with GEA Reader on a dossier's right-click menu, fingerprints the client
|
|
814
814
|
saves kept on that computer, nothing of GEA-Program. `gea help reader`.
|
|
@@ -1034,6 +1034,63 @@ eras of the protocol are spoken: the stateless revision 2026-07-28 and the
|
|
|
1034
1034
|
`initialize` handshake of 2025-11-25 and earlier. The **Assistant access**
|
|
1035
1035
|
tab (one button adds it to Claude Desktop), `gea mcp`, `gea help mcp`.
|
|
1036
1036
|
|
|
1037
|
+
### Benchmark
|
|
1038
|
+
|
|
1039
|
+
The wells of a pad against one another, and each against the best the pad
|
|
1040
|
+
has done. Every well with a drilling record is measured the same way from
|
|
1041
|
+
its own record - the footage, the days from its first stand to its last,
|
|
1042
|
+
feet per day, the rate on bottom, rotary and sliding, the median connection
|
|
1043
|
+
weight to weight, the trip speeds - and ranked on each count. Then each
|
|
1044
|
+
well is set against the pad's best: the well it would have been had every
|
|
1045
|
+
stretch of hole been drilled at the rate of whichever well was fastest
|
|
1046
|
+
through that stretch (300 ft or more of it), and every connection made in
|
|
1047
|
+
the pad's best quarter. The gap is hours the pad has already shown can be
|
|
1048
|
+
saved, on some well in that stretch - not a forecast, and not a cause: the
|
|
1049
|
+
bit, the motor, the mud and the hole size are not in the record. The
|
|
1050
|
+
**Benchmark** tab, `gea benchmark`, `gea help benchmark`; an assistant
|
|
1051
|
+
reads it as the `benchmark` tool.
|
|
1052
|
+
|
|
1053
|
+
### Public data: a real pad
|
|
1054
|
+
|
|
1055
|
+
A pad anyone may check. The Utah FORGE project - the U.S. Department of
|
|
1056
|
+
Energy's geothermal field laboratory near Milford, Utah - publishes the
|
|
1057
|
+
rig recorders of five wells drilled through the same basin fill and
|
|
1058
|
+
granite between 2017 and 2023, under Creative Commons Attribution 4.0.
|
|
1059
|
+
`gea public-pad` turns those files into a site of its own, so the rig
|
|
1060
|
+
time, the roadmap, the drilling alerts and the benchmark run on real
|
|
1061
|
+
records before any client's. The program does not contain the files and
|
|
1062
|
+
does not fetch them: the site downloads them in a browser from the
|
|
1063
|
+
Geothermal Data Repository, names the folder, and the program checks each
|
|
1064
|
+
file against the size and the SHA-256 it had when this release was checked
|
|
1065
|
+
with it, converts the three layouts that are not the recorder's own
|
|
1066
|
+
export, attaches each well, and keeps on the record what was done to
|
|
1067
|
+
each - 16A(78)-32's bit depth is RECONSTRUCTED from the block and the
|
|
1068
|
+
slips and is marked so on every page. Every page and report of that site
|
|
1069
|
+
ends with the credit the licence asks for.
|
|
1070
|
+
|
|
1071
|
+
What this release made of them, on the five files as published:
|
|
1072
|
+
|
|
1073
|
+
| Well | Drilled, ft | Days | ft/day | On bottom, ft/h | Median connection, min |
|
|
1074
|
+
|---|---|---|---|---|---|
|
|
1075
|
+
| 58-32 (2017) | 6,288 | 43.5 | 145 | 15.9 | 14.4 |
|
|
1076
|
+
| 16A(78)-32 (2020) | 11,035 | 67.8 | 163 | 34.4 | 11.3 |
|
|
1077
|
+
| 56-32 (2021) | 9,232 | 19.0 | 487 | 46.6 | 7.5 |
|
|
1078
|
+
| 78B-32 (2021) | 9,372 | 29.1 | 322 | 84.7 | 7.7 |
|
|
1079
|
+
| 16B(78)-32 (2023) | 10,490 | 52.4 | 200 | 45.7 | 10.2 |
|
|
1080
|
+
|
|
1081
|
+
Against the pad's best the five wells spent 812 of their 1,256 on-bottom
|
|
1082
|
+
hours beyond it. The roadmap's own check on them is split - running nearer
|
|
1083
|
+
the window was the faster half on two wells and the slower on two - which
|
|
1084
|
+
is the page saying, of wells drilled six years apart in three hole sizes,
|
|
1085
|
+
that one well's parameters are not the next well's roadmap. The drilling
|
|
1086
|
+
alerts, replayed, find 27 motor stalls on the three wells whose records
|
|
1087
|
+
can show one, three falls in off-bottom pressure on 78B-32 that no trip followed
|
|
1088
|
+
and one on 58-32 that a trip out of the hole followed within twelve hours.
|
|
1089
|
+
Data: Utah FORGE, Energy & Geoscience Institute at the University of Utah,
|
|
1090
|
+
funded by the U.S. Department of Energy; Geothermal Data Repository,
|
|
1091
|
+
gdr.openei.org; CC BY 4.0. The **Public data** tab, `gea public-pad`,
|
|
1092
|
+
`gea help public-data`.
|
|
1093
|
+
|
|
1037
1094
|
### Plan vs actual and the survey tools
|
|
1038
1095
|
|
|
1039
1096
|
Each well against its directional plan: at every survey station, how far
|
|
@@ -1698,7 +1755,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1698
1755
|
|
|
1699
1756
|
### The Windows installer
|
|
1700
1757
|
|
|
1701
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1758
|
+
Every release also carries `GEA-Program-Setup-0.90.0.exe` (for 0.90.0): the
|
|
1702
1759
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1703
1760
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1704
1761
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1717,7 +1774,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1717
1774
|
software deployment:
|
|
1718
1775
|
|
|
1719
1776
|
```
|
|
1720
|
-
GEA-Program-Setup-0.
|
|
1777
|
+
GEA-Program-Setup-0.90.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1721
1778
|
```
|
|
1722
1779
|
|
|
1723
1780
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -677,6 +677,19 @@ def main(argv=None) -> int:
|
|
|
677
677
|
p_os.add_argument("--actor", type=str, default="cli")
|
|
678
678
|
p_os.add_argument("--json", action="store_true")
|
|
679
679
|
|
|
680
|
+
p_bm = sub.add_parser("benchmark", help="the wells of a pad against one another: feet per day, on-bottom rate, connections and trips ranked, and each well against the pad's best - every stretch at the rate of the fastest well through it")
|
|
681
|
+
p_bm.add_argument("--workspace", type=str, default=None, help="the workspace folder; without one the self-test runs")
|
|
682
|
+
p_bm.add_argument("--write", action="store_true", help="write reports/benchmark/benchmark.json, .md, .csv and stretches.csv")
|
|
683
|
+
p_bm.add_argument("--actor", type=str, default="cli")
|
|
684
|
+
p_bm.add_argument("--json", action="store_true")
|
|
685
|
+
p_pp = sub.add_parser("public-pad", help="a real pad from public data: the Utah FORGE wells' published rig recorders (CC BY 4.0) made into a site of their own - the files to get and where, checked against their sizes and hashes, converted and attached; the program fetches nothing")
|
|
686
|
+
p_pp.add_argument("--folder", type=str, default=None, help="the folder the downloaded files are in; with nothing else, lists each file and whether it is there. Without a folder the self-test runs (stand-ins in each published layout)")
|
|
687
|
+
p_pp.add_argument("--verify", action="store_true", help="hash each file that is there against the SHA-256 this release was checked with")
|
|
688
|
+
p_pp.add_argument("--build", action="store_true", help="make the site at --site from the files in --folder, or add to it the wells it does not have yet")
|
|
689
|
+
p_pp.add_argument("--site", type=str, default=None, help="--build: the folder the site's workspace is made in")
|
|
690
|
+
p_pp.add_argument("--list", action="store_true", help="list the dataset's files, sizes, hashes and where each is published, and exit")
|
|
691
|
+
p_pp.add_argument("--actor", type=str, default="cli")
|
|
692
|
+
p_pp.add_argument("--json", action="store_true")
|
|
680
693
|
p_mc = sub.add_parser("mcp", help="the site, readable by an assistant: a Model Context Protocol server on standard input and output - local (no port), read-only (every tool reads one of the program's pages, none changes anything), logged; with --workspace alone it serves until its input closes")
|
|
681
694
|
p_mc.add_argument("--workspace", type=str, default=None, help="the workspace folder; without one the self-test runs (both eras of the protocol against a labelled site)")
|
|
682
695
|
p_mc.add_argument("--allow", type=str, default=None, help="serve only these tools this run, comma-separated (never more than the site offers)")
|
|
@@ -3575,6 +3588,58 @@ def main(argv=None) -> int:
|
|
|
3575
3588
|
for v in f_["versions"][: (50 if a.family else 3)]:
|
|
3576
3589
|
print(f" {v['utc']} {v.get('report_id') or ''} reports/{v['dir']}")
|
|
3577
3590
|
return 0
|
|
3591
|
+
elif a.cmd == "benchmark":
|
|
3592
|
+
import json as _json
|
|
3593
|
+
from . import benchmark as _BM
|
|
3594
|
+
from .cli import _safe_stdout
|
|
3595
|
+
from .workspace import Workspace, WorkspaceError
|
|
3596
|
+
_safe_stdout()
|
|
3597
|
+
if not a.workspace:
|
|
3598
|
+
r = _BM.selftest()
|
|
3599
|
+
print("\n".join(f"{'PASS' if c['pass'] else 'FAIL'} {c['check']}: {c['value']}" for c in r["checks"]) + f"\n{'OK' if r['ok'] else 'FAILED'} - {r['label']}")
|
|
3600
|
+
return 0 if r["ok"] else 1
|
|
3601
|
+
try:
|
|
3602
|
+
ws = Workspace(a.workspace)
|
|
3603
|
+
if a.write:
|
|
3604
|
+
from . import __version__ as _ver90b
|
|
3605
|
+
r = _BM.write_report(ws, _ver90b, a.actor)
|
|
3606
|
+
print(f"written: {', '.join(r['files'])} under {r['folder']}")
|
|
3607
|
+
p = _BM.page(ws)
|
|
3608
|
+
except (_BM.BenchmarkError, WorkspaceError, ValueError, OSError) as e:
|
|
3609
|
+
raise SystemExit(f"benchmark: {e.args[0] if e.args else e}")
|
|
3610
|
+
print(_json.dumps(p, default=str) if a.json else _BM.text(p))
|
|
3611
|
+
return 0
|
|
3612
|
+
elif a.cmd == "public-pad":
|
|
3613
|
+
import json as _json
|
|
3614
|
+
from . import public_pad as _PP
|
|
3615
|
+
from .cli import _safe_stdout
|
|
3616
|
+
_safe_stdout()
|
|
3617
|
+
if not a.folder and not a.list:
|
|
3618
|
+
r = _PP.selftest()
|
|
3619
|
+
print("\n".join(f"{'PASS' if c['pass'] else 'FAIL'} {c['check']}: {c['value']}" for c in r["checks"]) + f"\n{'OK' if r['ok'] else 'FAILED'} - {r['label']}")
|
|
3620
|
+
return 0 if r["ok"] else 1
|
|
3621
|
+
try:
|
|
3622
|
+
if a.build:
|
|
3623
|
+
if not a.site:
|
|
3624
|
+
raise SystemExit("public-pad: --build needs --site, the folder the site is made in")
|
|
3625
|
+
last_ = {"t": ""}
|
|
3626
|
+
|
|
3627
|
+
def say_(d_):
|
|
3628
|
+
t_ = f"{d_.get('well', '')} {d_.get('step', '')}".strip()
|
|
3629
|
+
if t_ != last_["t"] and d_.get("step") != "done":
|
|
3630
|
+
last_["t"] = t_
|
|
3631
|
+
print(f" {d_.get('n', '')}/{d_.get('of', '')} {t_}", flush=True)
|
|
3632
|
+
r = _PP.build(a.folder, a.site, a.actor, verify=True, progress=say_)
|
|
3633
|
+
print(f"{r['name']} at {r['path']}: " + (f"added {', '.join(r['added'])}" if r["added"] else "nothing to add") + f"; it has {', '.join(r['wells'])}")
|
|
3634
|
+
for e_ in r["record"]["wells"]:
|
|
3635
|
+
for n_ in e_["notes"]:
|
|
3636
|
+
print(f" {e_['well']}: {n_}")
|
|
3637
|
+
return 0
|
|
3638
|
+
s_ = _PP.status(a.folder or "", verify=a.verify)
|
|
3639
|
+
except (_PP.PublicPadError, OSError) as e:
|
|
3640
|
+
raise SystemExit(f"public-pad: {e.args[0] if e.args else e}")
|
|
3641
|
+
print(_json.dumps(s_, default=str) if a.json else _PP.text(s_))
|
|
3642
|
+
return 0
|
|
3578
3643
|
elif a.cmd == "mcp":
|
|
3579
3644
|
import json as _json
|
|
3580
3645
|
from . import mcp_server as _MC
|
|
@@ -18578,10 +18578,10 @@ def section_eg_dysfunction(tmp: str) -> None:
|
|
|
18578
18578
|
|
|
18579
18579
|
# -- EG2 a workspace: the replay, the live record, the alert ------------------------------------------------------------
|
|
18580
18580
|
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad EG", actor="tester")
|
|
18581
|
-
rec = DY.synthetic_record(True)
|
|
18581
|
+
rec = DY.synthetic_record(True, ends_now=True)
|
|
18582
18582
|
DY.write_edr(rec, str(d / "rig.csv"))
|
|
18583
18583
|
wid = ws.add_well_file(str(d / "rig.csv"), display="RIG-1", actor="tester")["id"]
|
|
18584
|
-
DY.write_edr(DY.synthetic_record(False, seed=5), str(d / "sound.csv"))
|
|
18584
|
+
DY.write_edr(DY.synthetic_record(False, seed=5, ends_now=True), str(d / "sound.csv"))
|
|
18585
18585
|
wid2 = ws.add_well_file(str(d / "sound.csv"), display="RIG-2", actor="tester")["id"]
|
|
18586
18586
|
pg = DY.page(ws)
|
|
18587
18587
|
w1 = next(w_ for w_ in pg["wells"] if w_["well"] == wid); w2 = next(w_ for w_ in pg["wells"] if w_["well"] == wid2)
|
|
@@ -18763,7 +18763,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18763
18763
|
plain = MC._plain({"a": np.float64(1.5), "_work": [1, 2], "b": [np.int64(3), float("nan")], "c": np.arange(4), "d": (1, "x")})
|
|
18764
18764
|
c1 = {
|
|
18765
18765
|
"selftest": st["ok"] and len(st["checks"]) >= 7,
|
|
18766
|
-
"tools": len(defs) ==
|
|
18766
|
+
"tools": len(defs) == 24 and defs[0]["name"] == "site" and all(d_["annotations"]["readOnlyHint"] is True and d_["annotations"]["destructiveHint"] is False and d_["annotations"]["openWorldHint"] is False
|
|
18767
18767
|
and d_["inputSchema"]["type"] == "object" and d_["inputSchema"]["additionalProperties"] is False and d_["title"] for d_ in defs)
|
|
18768
18768
|
and "well" in defs[1]["inputSchema"]["properties"] and "json" in defs[2]["inputSchema"]["properties"] and "json" not in MC.tool_definition("help")["inputSchema"]["properties"]
|
|
18769
18769
|
and not [n_ for n_ in MC.NAMES if any(w_ in n_ for w_ in ("write", "set", "declare", "attach", "remove", "delete", "run"))],
|
|
@@ -18775,7 +18775,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18775
18775
|
failed1 = [k_ for k_, v in c1.items() if not v]
|
|
18776
18776
|
ok(not failed1,
|
|
18777
18777
|
"EH1 the MCP server: the self-test (a client of an earlier revision through its handshake and a client of revision 2026-07-28 statelessly, each listing and calling the tools; a line that is "
|
|
18778
|
-
"not JSON, a tool, a well, an argument and a method that do not exist, a batch; a withheld tool; the access log; an assistant's configuration file added to and restored); twenty-
|
|
18778
|
+
"not JSON, a tool, a well, an argument and a method that do not exist, a batch; a withheld tool; the access log; an assistant's configuration file added to and restored); twenty-four tools, "
|
|
18779
18779
|
"each read-only by its own declaration with its arguments closed, none named for a change; the revisions spoken; the command a client starts - the console interpreter, never the windowless "
|
|
18780
18780
|
"one; a page as plain JSON with the working arrays left out" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
18781
18781
|
|
|
@@ -18853,12 +18853,12 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18853
18853
|
and "SIMULATION" in answers["pressure_plume"]["text"].splitlines()[0] and "RIG-1" in answers["site"]["text"] and _ver in answers["site"]["text"],
|
|
18854
18854
|
"json": all(isinstance(v, (dict, list)) for n_, v in parsed.items() if n_ != "well") and parsed["well"] is None and as_json["well"]["is_error"] and parsed["roadmap"]["status"] == "OK" and not [k_ for k_ in parsed["rig_time"] if str(k_).startswith("_")]
|
|
18855
18855
|
and len(parsed["drilling_alerts"]["wells"]) == 2,
|
|
18856
|
-
"child_legacy": rc_o == 0 and len(out_o) == 4 and out_o[0]["result"]["protocolVersion"] == "2025-11-25" and len(out_o[1]["result"]["tools"]) ==
|
|
18856
|
+
"child_legacy": rc_o == 0 and len(out_o) == 4 and out_o[0]["result"]["protocolVersion"] == "2025-11-25" and len(out_o[1]["result"]["tools"]) == 24 and "resultType" not in out_o[1]["result"]
|
|
18857
18857
|
and out_o[2]["result"]["content"][0]["text"] == answers["rig_time"]["text"] and "motor stall" in out_o[3]["result"]["content"][0]["text"] and "Traceback" not in err_o,
|
|
18858
18858
|
"child_modern": rc_m == 0 and len(out_m) == 4 and out_m[0]["result"]["supportedVersions"] == list(MC.SUPPORTED) and out_m[1]["result"]["resultType"] == "complete"
|
|
18859
18859
|
and out_m[1]["result"]["cacheScope"] == "private" and out_m[2]["result"]["_meta"][MC.K_SERVER] == {"name": "gea-program", "title": "GEA-Program", "version": _ver}
|
|
18860
18860
|
and out_m[2]["result"]["isError"] is False and out_m[3]["error"]["code"] == -32022 and out_m[3]["error"]["data"]["requested"] == "2099-01-01" and "Traceback" not in err_m,
|
|
18861
|
-
"withheld": kept["tools"] is not None and "audit" not in kept["tools"] and rc_w == 0 and "audit" not in [t_["name"] for t_ in out_w[0]["result"]["tools"]] and len(out_w[0]["result"]["tools"]) ==
|
|
18861
|
+
"withheld": kept["tools"] is not None and "audit" not in kept["tools"] and rc_w == 0 and "audit" not in [t_["name"] for t_ in out_w[0]["result"]["tools"]] and len(out_w[0]["result"]["tools"]) == 23
|
|
18862
18862
|
and out_w[1]["error"]["code"] == -32602 and "[cut at 3,000 of" in out_w[2]["result"]["content"][0]["text"],
|
|
18863
18863
|
"narrowed": rc_a == 0 and [t_["name"] for t_ in out_a[0]["result"]["tools"]] == ["site"] and out_a[1]["error"]["code"] == -32602,
|
|
18864
18864
|
"no_workspace": rc_x.returncode == 2 and rc_x.stdout == b"" and b"not a workspace" in rc_x.stderr,
|
|
@@ -18926,7 +18926,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18926
18926
|
its = (pkg / "help" / "IT_SECURITY.md").read_text(encoding="utf-8")
|
|
18927
18927
|
backups = sorted(p_.name for p_ in cfgp.parent.iterdir() if ".before-gea-" in p_.name)
|
|
18928
18928
|
c3 = {
|
|
18929
|
-
"api": s_vg == 200 and len(vg["tools"]) ==
|
|
18929
|
+
"api": s_vg == 200 and len(vg["tools"]) == 24 and all(t_["offered"] for t_ in vg["tools"]) and vg["config"]["mcpServers"]["gea"]["args"][-1] == os.path.abspath(wsp) and len(vg["log"]) >= 6
|
|
18930
18930
|
and vg["claude_desktop"]["found"] and not vg["claude_desktop"]["installed"] and s_vs == 403 and s_os == 200 and os_["offered"] == ["site", "roadmap", "help"] and os_["max_chars"] == 20000
|
|
18931
18931
|
and s_bs == 400 and s_oa == 200,
|
|
18932
18932
|
"claude_desktop": s_oc == 403 and s_ac == 200 and len(ac["done"]) == 1 and cfg_added["globalShortcut"] == "Ctrl+Space" and cfg_added["mcpServers"]["files"] == {"command": "npx", "args": ["-y", "x"]}
|
|
@@ -18954,6 +18954,212 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18954
18954
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
18955
18955
|
|
|
18956
18956
|
|
|
18957
|
+
def section_ei_public_pad_benchmark(tmp: str) -> None:
|
|
18958
|
+
"""Section EI - a pad from public data, and the benchmark: the self-tests; the recorder exports read without an
|
|
18959
|
+
on-bottom flag, a depth reamed back through hole already drilled, a ten-second record's pipe speeds, a stand no bit
|
|
18960
|
+
could have drilled; the published layouts converted (stand-ins under the published names) and the site made, with
|
|
18961
|
+
each file's size and hash kept and the credit on every page; the benchmark over it - the counts, the ranks, each
|
|
18962
|
+
well against the pad's best; the routes, the tabs, the commands, the assistant's tool, the help, the README and
|
|
18963
|
+
the lessons."""
|
|
18964
|
+
import http.cookiejar
|
|
18965
|
+
import io as _io
|
|
18966
|
+
import subprocess as _sp
|
|
18967
|
+
import urllib.error
|
|
18968
|
+
import urllib.request
|
|
18969
|
+
from datetime import datetime as _dtm, timedelta as _td
|
|
18970
|
+
from . import __version__ as _ver
|
|
18971
|
+
from . import alerts as AL
|
|
18972
|
+
from . import benchmark as BM
|
|
18973
|
+
from . import dysfunction as DY
|
|
18974
|
+
from . import edr as E
|
|
18975
|
+
from . import helplib as H
|
|
18976
|
+
from . import mcp_server as MC
|
|
18977
|
+
from . import public_pad as PP
|
|
18978
|
+
from . import rig_state as RS
|
|
18979
|
+
from . import roadmap as RM
|
|
18980
|
+
from . import tutorial as TU
|
|
18981
|
+
from .service import Service, Users
|
|
18982
|
+
from .workspace import Workspace
|
|
18983
|
+
pkg = Path(__file__).parent
|
|
18984
|
+
d = Path(tmp, "ei"); d.mkdir()
|
|
18985
|
+
os.environ["GEA_WORKSPACES_FILE"] = str(d / "workspaces.json")
|
|
18986
|
+
# -- EI1 what the published records made the drilling record learn ------------------------------------------------------
|
|
18987
|
+
st_p, st_b = PP.selftest(), BM.selftest()
|
|
18988
|
+
hdr = "YYYY/MM/DD,HH:MM:SS,Hole Depth (feet),Bit Depth (feet),Rate Of Penetration (ft_per_hr),Weight on Bit (klbs),Rotary RPM (RPM),Hook Load (klbs),Standpipe Pressure (psi),Total Pump Output (gal_per_min),Block Height (feet)"
|
|
18989
|
+
t0 = _dtm(2026, 5, 1, 0, 0, 0)
|
|
18990
|
+
|
|
18991
|
+
def write(path, rows, step=1):
|
|
18992
|
+
with open(path, "w", encoding="utf-8", newline="") as f:
|
|
18993
|
+
f.write(hdr + "\n")
|
|
18994
|
+
for k, (hole, bit, rop, wob, rpm) in enumerate(rows):
|
|
18995
|
+
ts = t0 + _td(seconds=k * step)
|
|
18996
|
+
f.write(f"{ts:%Y/%m/%d},{ts:%H:%M:%S},{hole:.2f},{bit:.2f},{rop:.1f},{wob:.1f},{rpm:.1f},180.0,2500.0,550.0,50.0\n")
|
|
18997
|
+
# drilled 1,000 to 2,500 ft at 180 ft/h with 30 klbf; the depth set back to 1,100 and reamed back to 2,400 at 900 ft/h with 3 klbf; then drilled on to 2,700
|
|
18998
|
+
rows = [(1000.0 + 0.05 * k, 1000.0 + 0.05 * k, 180.0, 30.0, 80.0) for k in range(30000)]
|
|
18999
|
+
rows += [(1100.0 + 0.25 * k, 1100.0 + 0.25 * k, 900.0, 3.0, 60.0) for k in range(5200)]
|
|
19000
|
+
rows += [(2400.0 + 0.25 * k, 2400.0 + 0.25 * k, 900.0, 3.0, 60.0) for k in range(400)] # the old depth regained at 2,500
|
|
19001
|
+
rows += [(2500.0 + 0.05 * k, 2500.0 + 0.05 * k, 180.0, 30.0, 80.0) for k in range(4000)]
|
|
19002
|
+
write(str(d / "reamed.csv"), rows)
|
|
19003
|
+
s_r = E.read(str(d / "reamed.csv")); de = E.depth_events(s_r); rec_r = E.record(s_r, de)
|
|
19004
|
+
ev = [e for e in de["events"] if e["type"] == "REAMED BACK"]
|
|
19005
|
+
# the same fall, but the regain is drilled as the hole was (a redrill): not reamed back
|
|
19006
|
+
rows2 = rows[:30000] + [(1100.0 + 0.05 * k, 1100.0 + 0.05 * k, 180.0, 30.0, 80.0) for k in range(8000)]
|
|
19007
|
+
write(str(d / "redrilled.csv"), rows2)
|
|
19008
|
+
de2 = E.depth_events(E.read(str(d / "redrilled.csv")))
|
|
19009
|
+
on, how = E.on_bottom(s_r)
|
|
19010
|
+
# a ten-second record: the bit pulled 600 ft at 1 ft/s is tripping out, not standing still
|
|
19011
|
+
n10 = 400; t10 = np.arange(n10) * 10.0
|
|
19012
|
+
bit10 = np.where(t10 < 600.0, 9000.0 - t10, 8400.0)
|
|
19013
|
+
c10 = RS.classify(t10, {"hookload": np.full(n10, 200.0), "block": np.full(n10, 50.0), "bit": bit10, "hole": np.full(n10, 9700.0), "flow": np.zeros(n10), "spp": None, "rpm": np.zeros(n10)},
|
|
19014
|
+
np.zeros(n10, bool), block_weight=40.0)
|
|
19015
|
+
tq = np.arange(0.0, 3600.0)
|
|
19016
|
+
hole_q = 5000.0 + np.where(tq < 1800.0, tq * 0.05, 90.0 + (tq - 1800.0) * 2.0) # 90 ft drilled at 180 ft/h, then the depth run on at 7,200 ft/h
|
|
19017
|
+
stq = RM.stands_of(tq, hole_q, np.ones(len(tq), bool), np.ones(len(tq), bool), {})
|
|
19018
|
+
c1 = {
|
|
19019
|
+
"selftests": st_p["ok"] and st_b["ok"] and len(st_p["checks"]) >= 9 and len(st_b["checks"]) >= 3,
|
|
19020
|
+
"on_bottom": how is not None and "no On Bottom channel" in how and bool(on.all()) and any("no On Bottom channel" in n_ for n_ in rec_r["notes"]) and E.ON_BOTTOM_FT == 0.1,
|
|
19021
|
+
"reamed_back": len(ev) == 1 and "reamed back in" in ev[0]["effect"] and "3 klbf on the bit where it was drilled with 30" in ev[0]["effect"] and abs(rec_r["feet_drilled"] - 1700.0) < 5.0
|
|
19022
|
+
and not [e for e in de2["events"] if e["type"] == "REAMED BACK"] and [e["type"] for e in de2["events"] if e["from_ft"] > 2000] == ["UNRESOLVED"],
|
|
19023
|
+
"ten_second": float((c10["state"][:55] == RS.TOUT).mean()) > 0.9 and int((c10["state"][70:] == RS.TOUT).sum()) == 0,
|
|
19024
|
+
"implausible": stq["implausible"] >= 30 and stq["n"] == 1 and float(stq["rop"][0]) < 250.0 and float(stq["feet"].sum()) <= 100.0,
|
|
19025
|
+
}
|
|
19026
|
+
failed1 = [k_ for k_, v in c1.items() if not v]
|
|
19027
|
+
ok(not failed1,
|
|
19028
|
+
"EI1 what the published records taught the drilling record, each on a labelled file: an export with no on-bottom flag is read with the bit within 0.1 ft of the hole depth as on bottom, and "
|
|
19029
|
+
"says so; a depth set back 1,400 ft and regained through hole already drilled at five times the rate with a tenth of the weight is the string reamed back in, excluded, and the footage is the "
|
|
19030
|
+
"hole's own 1,700 ft - while the same fall drilled again as it was first drilled is left for the daily report to decide; a ten-second record's pipe pulled at a foot a second is a trip out; "
|
|
19031
|
+
"the stand drilled at 180 ft/h is kept and the thirty-odd behind it, counted at 7,200 ft/h, are left out and counted as such; the public-pad and benchmark self-tests" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
19032
|
+
|
|
19033
|
+
# -- EI2 the site made from the published layouts, and the benchmark over it -------------------------------------------
|
|
19034
|
+
folder, site = str(d / "files"), str(d / "forge-site")
|
|
19035
|
+
made = PP.standins(folder, stands=24)
|
|
19036
|
+
st0 = PP.status(folder, verify=True)
|
|
19037
|
+
seen = []
|
|
19038
|
+
r = PP.build(folder, site, "tester", progress=seen.append)
|
|
19039
|
+
ws = Workspace(site); rec = PP.record(ws); by = {e["well"]: e for e in rec["wells"]}
|
|
19040
|
+
bm = BM.page(ws); rm = RM.page(ws); dy = DY.page(ws)
|
|
19041
|
+
bw = {w_["display"]: w_ for w_ in bm["wells"]}
|
|
19042
|
+
wr = BM.write_report(ws, _ver, "tester")
|
|
19043
|
+
rows_b = (Path(wr["folder"]) / "benchmark.csv").read_text(encoding="utf-8").strip().splitlines()
|
|
19044
|
+
rows_s = (Path(wr["folder"]) / "stretches.csv").read_text(encoding="utf-8").strip().splitlines()
|
|
19045
|
+
raised = AL.check_conditions(ws, None, force=True)
|
|
19046
|
+
again = PP.build(folder, site, "tester")
|
|
19047
|
+
os.remove(os.path.join(folder, "16B(78)-32 Well Survey.zip"))
|
|
19048
|
+
r_ns = PP.build(folder, str(d / "forge-nosurvey"), "tester", wells=["56-32", "16B(78)-32"], verify=False)
|
|
19049
|
+
by_ns = {e["well"]: e for e in r_ns["record"]["wells"]}
|
|
19050
|
+
site_txt = MC.call_tool(ws, "site", {})["text"]; bm_txt = MC.call_tool(ws, "benchmark", {})
|
|
19051
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
19052
|
+
plain = Workspace.create(str(d / "plain"), "Plain", actor="tester")
|
|
19053
|
+
c2 = {
|
|
19054
|
+
"status": st0["present"] == 5 and st0["ready"] and all(r_["present"] and r_["size_matches"] is False and r_["hash_matches"] is False and len(r_["sha256"]) == 64 for r_ in st0["files"])
|
|
19055
|
+
and [r_["well"] for r_ in st0["files"]] == ["58-32", "16A(78)-32", "56-32", "78B-32", "16B(78)-32"] and st0["total_bytes"] > 2.7e9 and all(r_["page"].startswith("https://gdr.openei.org/submissions/") for r_ in st0["files"]),
|
|
19056
|
+
"built": r["added"] == [r_["well"] for r_ in st0["files"]] and ws.manifest.get("name") == "Utah FORGE - public data" and len(ws.wells()) == 5 and seen[-1] == {"step": "done", "added": r["added"]}
|
|
19057
|
+
and {s_["step"] for s_ in seen} >= {"hashing", "converting", "attaching", "done"} and again["added"] == [] and "public_pad.build" in audit and str(d / "workspaces.json") and Path(d / "workspaces.json").is_file(),
|
|
19058
|
+
"provenance": rec["licence"]["url"].endswith("/by/4.0/") and "U.S. Department of Energy" in rec["credit"] and all(e["sha256"] and e["hash_matches"] is False and e["bytes"] > 0 and e["well_id"] for e in rec["wells"])
|
|
19059
|
+
and by["16A(78)-32"]["bit_depth_reconstructed"] and by["16B(78)-32"]["tvd_from_survey"] and "attached as it is" in by["56-32"]["notes"][-1]
|
|
19060
|
+
and not by_ns["16B(78)-32"]["tvd_from_survey"] and any("measured depth stands in" in n_ for n_ in by_ns["16B(78)-32"]["notes"]),
|
|
19061
|
+
"pages_credit": all(p_["lines"][-1].startswith("Data: Utah FORGE, public, under Creative Commons Attribution 4.0") and p_["public_source"]["name"] == "Utah FORGE" for p_ in (bm, rm, dy))
|
|
19062
|
+
and any("reconstructed" in n_ for n_ in bm["notes"]) and "Data: Utah FORGE" in site_txt and PP.credit(plain) is None and "public_source" not in BM.page(plain),
|
|
19063
|
+
"not_live": all(not w_["live"] for w_ in dy["wells"]) and not [e for e in raised if e["event"].startswith("drilling.")],
|
|
19064
|
+
"benchmark": bm["status"] == "OK" and len(bm["wells"]) == 5 and all(abs(w_["drilled_ft"] - round(made[w_["display"]]["hole_to"] - made[w_["display"]]["hole_from"], -2)) <= 200 and 140 <= w_["rop_ft_h"] <= 160
|
|
19065
|
+
and w_["connections"] >= 20 and 5.0 <= w_["w2w_median_min"] <= 6.5 and w_["gap_h"] >= 0 and w_["compared_h"] > 0 for w_ in bm["wells"])
|
|
19066
|
+
and set(bm["ranks"]["rop_ft_h"].values()) <= {1, 2, 3, 4, 5} and 1 in bm["ranks"]["feet_per_day"].values() and len(bm["curves"]) == 5 and all(len(c_) >= 10 and c_[0][1] < c_[-1][1] for c_ in bm["curves"].values())
|
|
19067
|
+
and bm["pad_best_connection_min"] is not None and len(bm["stretches"]) >= 3 and all(s_["best_well"] in bm["names"] for s_ in bm["stretches"] if s_["best_rop_ft_h"]),
|
|
19068
|
+
"report": set(wr["files"]) == {"benchmark.json", "benchmark.md", "benchmark.csv", "stretches.csv"} and len(rows_b) == 6 and rows_b[0].startswith("display,drilled_ft,days,feet_per_day") and len(rows_s) == len(bm["stretches"]) + 1
|
|
19069
|
+
and "benchmark.report" in audit,
|
|
19070
|
+
"tool": not bm_txt["is_error"] and bm_txt["text"] == BM.text(BM.page(ws)) and "benchmark" in MC.NAMES and len(MC.NAMES) == 24,
|
|
19071
|
+
}
|
|
19072
|
+
failed2 = [k_ for k_, v in c2.items() if not v]
|
|
19073
|
+
ok(not failed2,
|
|
19074
|
+
"EI2 the public pad from stand-ins written in each of the five published layouts under the published names: the folder read against the list (every file there, none the published size or "
|
|
19075
|
+
"hash, and said so); the site made and registered, five wells, each source's hash on the record, the licence and the credit; 16A's bit depth marked reconstructed, 16B's true vertical depth "
|
|
19076
|
+
"from its survey and, without the survey, its measured depth standing in and said to; the credit as the last line of the roadmap, the drilling alerts and the benchmark, and on the "
|
|
19077
|
+
"assistant's site tool; records dated months ago raise no drilling alert though their files are new; built again it adds nothing. The benchmark over it: every well's footage, rate and "
|
|
19078
|
+
"connections, the ranks, the curves, the pad's best and each well's gap; its report with a row a well and a row a stretch; the assistant's benchmark tool the page's own text"
|
|
19079
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
19080
|
+
|
|
19081
|
+
# -- EI3 the routes, the commands, the tabs, the help -------------------------------------------------------------------
|
|
19082
|
+
Users(str(Path(site, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(site, "users.json"))).add("op", "op-pass-123", "operator"); Users(str(Path(site, "users.json"))).add("ad", "admin-pass-12", "admin")
|
|
19083
|
+
svc = Service(site, port=0, scheduler=False).start()
|
|
19084
|
+
base_url = svc.url.rstrip("/")
|
|
19085
|
+
|
|
19086
|
+
def opener(name, pw_):
|
|
19087
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
19088
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
19089
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
19090
|
+
return o
|
|
19091
|
+
|
|
19092
|
+
def call(o, method, path, body=None):
|
|
19093
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
19094
|
+
if method == "POST":
|
|
19095
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
19096
|
+
try:
|
|
19097
|
+
with o.open(rq, timeout=300) as rr_:
|
|
19098
|
+
return rr_.status, json.loads(rr_.read())
|
|
19099
|
+
except urllib.error.HTTPError as e:
|
|
19100
|
+
return e.code, json.loads(e.read())
|
|
19101
|
+
from urllib.parse import quote as _q
|
|
19102
|
+
try:
|
|
19103
|
+
V, O, A = opener("v", "viewer-pass-1"), opener("op", "op-pass-123"), opener("ad", "admin-pass-12")
|
|
19104
|
+
s_vb, vb = call(V, "GET", "/api/benchmark")
|
|
19105
|
+
s_vw, _ = call(V, "POST", "/api/benchmark/write", {})
|
|
19106
|
+
s_ow, ow = call(O, "POST", "/api/benchmark/write", {})
|
|
19107
|
+
s_vp, vp = call(V, "GET", "/api/public-pad")
|
|
19108
|
+
s_vf, _ = call(V, "GET", "/api/public-pad?folder=" + _q(folder))
|
|
19109
|
+
s_af, af = call(A, "GET", "/api/public-pad?folder=" + _q(folder))
|
|
19110
|
+
s_ob, _ = call(O, "POST", "/api/public-pad/build", {"folder": folder, "path": str(d / "forge-api")})
|
|
19111
|
+
s_ab, ab = call(A, "POST", "/api/public-pad/build", {"folder": folder, "path": str(d / "forge-api")})
|
|
19112
|
+
job = {}
|
|
19113
|
+
for _ in range(240):
|
|
19114
|
+
_, pj = call(A, "GET", "/api/public-pad")
|
|
19115
|
+
job = pj["job"]
|
|
19116
|
+
if job.get("state") != "running":
|
|
19117
|
+
break
|
|
19118
|
+
time.sleep(0.5)
|
|
19119
|
+
s_bad, _ = call(A, "POST", "/api/public-pad/build", {"folder": str(d / "nowhere"), "path": str(d / "forge-bad")})
|
|
19120
|
+
job_bad = {}
|
|
19121
|
+
for _ in range(60):
|
|
19122
|
+
_, pj = call(A, "GET", "/api/public-pad")
|
|
19123
|
+
job_bad = pj["job"]
|
|
19124
|
+
if job_bad.get("state") != "running":
|
|
19125
|
+
break
|
|
19126
|
+
time.sleep(0.25)
|
|
19127
|
+
finally:
|
|
19128
|
+
svc.stop()
|
|
19129
|
+
env = {**os.environ, "PYTHONPATH": str(pkg.parent) + os.pathsep + os.environ.get("PYTHONPATH", "")}
|
|
19130
|
+
run = lambda *a_: _sp.run([sys.executable, "-m", "gea", *a_], capture_output=True, text=True, env=env, cwd=str(d), timeout=600)
|
|
19131
|
+
cli_l, cli_f, cli_v = run("public-pad", "--list"), run("public-pad", "--folder", folder), run("public-pad", "--folder", folder, "--verify", "--json")
|
|
19132
|
+
cli_b, cli_n = run("public-pad", "--folder", folder, "--build", "--site", str(d / "forge-cli")), run("public-pad", "--folder", folder, "--build")
|
|
19133
|
+
cli_bm, cli_bj, cli_bw = run("benchmark", "--workspace", site), run("benchmark", "--workspace", site, "--json"), run("benchmark", "--workspace", site, "--write")
|
|
19134
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
19135
|
+
readme = (pkg.parent / "README.md").read_text(encoding="utf-8") if (pkg.parent / "README.md").is_file() else ""
|
|
19136
|
+
lesson = (pkg / "help" / "tutorial" / "13-drilling-pages.md").read_text(encoding="utf-8")
|
|
19137
|
+
c3 = {
|
|
19138
|
+
"api_benchmark": s_vb == 200 and vb["status"] == "OK" and len(vb["wells"]) == 5 and s_vw == 403 and s_ow == 200 and "stretches.csv" in ow["files"],
|
|
19139
|
+
"api_public": s_vp == 200 and vp["folder"] == "" and len(vp["files"]) == 5 and vp["this_site"]["name"] == "Utah FORGE" and s_vf == 403 and s_af == 200 and af["present"] == 5 and s_ob == 403 and s_ab == 200
|
|
19140
|
+
and ab["state"] == "running" and job.get("state") == "done" and job["result"]["wells"] == ["58-32", "16A(78)-32", "56-32", "78B-32", "16B(78)-32"] and len(Workspace(str(d / "forge-api")).wells()) == 5
|
|
19141
|
+
and Path(d / "forge-api", "users.json").is_file() and job_bad.get("state") == "failed" and "no such folder" in job_bad.get("error", ""),
|
|
19142
|
+
"cli": cli_l.returncode == 0 and "Well_58-32_raw_pason_log.csv" in cli_l.stdout and "doi:10.15121/1998591" in cli_l.stdout and cli_f.returncode == 0 and "5 of 5 recorder files" in cli_f.stdout
|
|
19143
|
+
and cli_v.returncode == 0 and json.loads(cli_v.stdout)["files"][0]["hash_matches"] is False and cli_b.returncode == 0 and "added 58-32, 16A(78)-32, 56-32, 78B-32, 16B(78)-32" in cli_b.stdout
|
|
19144
|
+
and "RECONSTRUCTED" in cli_b.stdout and cli_n.returncode != 0 and "--site" in cli_n.stderr and cli_bm.returncode == 0 and "Benchmark: the wells against one another" in cli_bm.stdout
|
|
19145
|
+
and "Data: Utah FORGE" in cli_bm.stdout and cli_bj.returncode == 0 and len(json.loads(cli_bj.stdout)["wells"]) == 5 and cli_bw.returncode == 0 and "stretches.csv" in cli_bw.stdout,
|
|
19146
|
+
"page": all(x in page_src for x in ("VIEWS.benchmark", "['#/benchmark', 'Benchmark']", "bmCurves", "/api/benchmark/write", "help('benchmark')", "VIEWS.publicpad", "['#/publicpad', 'Public data']",
|
|
19147
|
+
"/api/public-pad/build", "help('publicpad')", "does not contain them and does not fetch them")),
|
|
19148
|
+
"help": not H.check("benchmark") and not H.check("public-data") and not H.check("edr") and H.VIEW_TOPIC.get("benchmark") == "benchmark" and H.VIEW_TOPIC.get("publicpad") == "public-data"
|
|
19149
|
+
and all(x in (H.page("public-data") or "") for x in ("gea public-pad --folder C:\\forge --build --site C:\\forge-site", "RECONSTRUCTED", "CC BY 4.0", "does not fetch them", "REAMED BACK"))
|
|
19150
|
+
and all(x in (H.page("benchmark") or "") for x in ("gea benchmark --workspace C:\\site", "300 ft or more", "25th percentile")) and "REAMED BACK" in (H.page("edr") or "") and "within 0.1 ft" in (H.page("edr") or "")
|
|
19151
|
+
and "`benchmark`" in (H.page("mcp") or ""),
|
|
19152
|
+
"readme_lesson": (not readme or ("### Benchmark" in readme and "### Public data: a real pad" in readme and "`gea public-pad`" in readme and "`gea benchmark`" in readme))
|
|
19153
|
+
and "**Benchmark**" in lesson and "**Public data**" in lesson and "benchmark" in lesson.split("Help:")[-1] and "public-data" in lesson.split("Help:")[-1] and not TU.check("drilling-pages"),
|
|
19154
|
+
}
|
|
19155
|
+
failed3 = [k_ for k_, v in c3.items() if not v]
|
|
19156
|
+
ok(not failed3,
|
|
19157
|
+
"EI3 on the API (anyone reads the benchmark and the list of public files; only an operator writes the benchmark's report; only an administrator has a folder of the computer looked into or a "
|
|
19158
|
+
"site made - made in the background with its progress asked after, the accounts copied, and a folder that is not there a failure that says so), the commands (the list with where each file "
|
|
19159
|
+
"is published, the folder, the hashes as JSON, the site built with what was done to each well, a build with no site named stopped; the benchmark, as JSON, its report), the Benchmark and "
|
|
19160
|
+
"Public data tabs, the help pages, the README and lesson 13" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
19161
|
+
|
|
19162
|
+
|
|
18957
19163
|
def main() -> int:
|
|
18958
19164
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
18959
19165
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -19095,6 +19301,7 @@ def main() -> int:
|
|
|
19095
19301
|
section_ef_roadmap(tmp)
|
|
19096
19302
|
section_eg_dysfunction(tmp)
|
|
19097
19303
|
section_eh_mcp(tmp)
|
|
19304
|
+
section_ei_public_pad_benchmark(tmp)
|
|
19098
19305
|
if _FAILS:
|
|
19099
19306
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
19100
19307
|
for f in _FAILS:
|