module
Environment
The only Python path to the database. Every other module reads and writes shared persisted truth through this seam, so there is exactly one place where the schema, the credentials and the RPC surface are known.
The boundary
No module outside signalise.environment may import a database driver. This is enforced, not documented: tests/architecture/test_module_boundaries.py fails the build if any other package imports one.
Decisions on record (15)
Inferred: decisions whose title names this module, or whose body references it as code. ADRs carry no declared statement of what they govern, so a decision that governs this module without naming it will be missing.
Public surface
Environmentclient.py · 53 public methods
clear_plant_flowsheet_entities · create_dataset · create_flowsheet · create_plan · create_plant · create_run · create_telecommands · delete_datasets · delete_plans · delete_plant · delete_runs · delete_setting · delete_steps · delete_telecommands · download_artifact · get_controllers · get_datasets · get_equipment · get_flowsheet · get_flowsheets · get_materials · get_nodes · get_operations · get_plans · get_plant · get_plants · get_run_summaries · get_runs · get_settings · get_settings_rows · get_state · get_step_hashes · get_steps · get_telecommands · get_telemetry · set_controller_historian_health · set_controller_opc_health · subscribe_telecommands · update_datasets · update_equipment · update_materials · update_node_tag · update_node_tags · update_plans · update_runs · update_steps · update_telecommands · upload_artifact · upsert_flowsheet_geojson · upsert_setting · upsert_state · upsert_steps · upsert_telemetry
EnvironmentModulemain.py · 58 public methods
api_key · bootstrap · clear_plant_flowsheet_entities · create_dataset · create_flowsheet · create_plan · create_plant · create_run · create_telecommands · credentials · delete_datasets · delete_plans · delete_plant · delete_runs · delete_setting · delete_steps · delete_telecommands · download_artifact · get_controllers · get_datasets · get_equipment · get_flowsheet · get_flowsheets · get_materials · get_nodes · get_operations · get_plans · get_plant · get_plants · get_run_summaries · get_runs · get_settings · get_settings_rows · get_state · get_step_hashes · get_steps · get_telecommands · get_telemetry · normalize_url · reset_plant_seed_data · set_controller_historian_health · set_controller_opc_health · subscribe_telecommands · update_datasets · update_equipment · update_materials · update_node_tag · update_node_tags · update_plans · update_runs · update_steps · update_telecommands · upload_artifact · upsert_flowsheet_geojson · upsert_setting · upsert_state · upsert_steps · upsert_telemetry
RealtimeSubscriptionrealtime.py · 1 public methods
unsubscribe
Commands
signalise environment bootstrap signalise environment create-plant signalise environment delete-plant signalise environment get-plant signalise environment get-telecommands signalise environment get-telemetry signalise environment reset-plant signalise environment status
Enforced invariants (33)
environment imports no domain module
test_environment_imports_no_domain_module
credentials load
test_credentials_load
url is http
test_url_is_http
EnvironmentModule can reach the local Supabase instance.
test_client_connects
the boundary exposes one read and one write
test_the_boundary_exposes_one_read_and_one_write
the dead per sample surface is gone
test_the_dead_per_sample_surface_is_gone
the schema declares exactly one telemetry table
test_the_schema_declares_exactly_one_telemetry_table
Its columns were per-sample (`value_numeric`, `source_timestamp`); the minute tier has neither.
test_no_migration_still_addresses_the_deleted_table
upsert and get global
test_upsert_and_get_global
update global
test_update_global
get missing global returns empty
test_get_missing_global_returns_empty
get all global modules
test_get_all_global_modules
upsert and get plant
test_upsert_and_get_plant
update plant
test_update_plant
get missing plant returns empty
test_get_missing_plant_returns_empty
get all plant modules
test_get_all_plant_modules
named key is independent of default
test_named_key_is_independent_of_default
merged fetch plant overrides global
test_merged_fetch_plant_overrides_global
merged fetch global only when no plant override
test_merged_fetch_global_only_when_no_plant_override
merged fetch single module
test_merged_fetch_single_module
delete setting
test_delete_setting
over wins on scalar
test_over_wins_on_scalar
The core invariant: a plant override of one nested key must NOT drop the sibling keys global set.
test_deep_merge_keeps_sibling_keys_no_shadowing
over only keys are added and base only keys survive
test_over_only_keys_are_added_and_base_only_keys_survive
scalar replaces dict and vice versa no partial merge across types
test_scalar_replaces_dict_and_vice_versa_no_partial_merge_across_types
base is not mutated
test_base_is_not_mutated
A default would put the hidden span-to-stride policy straight back.
test_interval_minutes_is_required_at_every_layer
It lived here AND in TypeScript, and the two had to agree or slot lookups misaligned.
test_the_span_to_stride_ladder_is_gone_from_sql
`recent` is a page (interval=1, desc, limit). Coverage is MIN/MAX on the PK — 1ms against
test_recent_is_absorbed_but_bounds_is_not
Coverage was briefly carried on every row; a data row is the wrong place for a table fact.
test_the_read_returns_data_not_metadata
A persistence method the boundary cannot reach may as well not exist — and because callers use
test_every_client_method_is_reachable_through_the_facade
The facade's own surface is small and named. A method appearing here without a counterpart on
test_the_facade_adds_nothing_it_has_not_declared
A one-line pass-through is safe to duplicate. Logic in the facade is not: it would mean the
test_the_delegations_stay_delegations
Sources
Generated from the repository. Every section is derived from an artifact the build enforces — ADR frontmatter, the architecture tests, the module's AST, its test docstrings, and the CLI's own help. Nothing here is hand-written prose, so nothing here can drift from the code without the code changing first.