pycontrol-core 3.0.0b2__tar.gz → 3.0.0b4__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.
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/PKG-INFO +11 -8
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/README.md +10 -7
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/addon-settings.md +33 -26
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/architecture.md +66 -64
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/changelog.md +263 -3
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/cli-reference.md +101 -23
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/contracts.md +46 -11
- pycontrol_core-3.0.0b4/docs/core-walkthrough.md +198 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/data-format.md +253 -18
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/experiment-handlers.md +101 -9
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/getting-started.md +23 -11
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/hardware-definitions.md +2 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/maintainability.md +15 -3
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/migration-from-official.md +15 -12
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/public-api.md +208 -40
- pycontrol_core-3.0.0b4/docs/release-acceptance.md +186 -0
- pycontrol_core-3.0.0b4/docs/sharing.md +171 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/subscriber-api.md +43 -24
- pycontrol_core-3.0.0b4/docs/task-folders.md +181 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/task-handlers.md +145 -17
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/testing.md +32 -7
- pycontrol_core-3.0.0b4/docs/threading-and-state.md +194 -0
- pycontrol_core-3.0.0b4/docs/troubleshooting.md +344 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/wire-protocol.md +68 -12
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/writing-tasks.md +17 -11
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/__init__.py +1 -1
- pycontrol_core-3.0.0b4/src/pycontrol/addons/README.md +42 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/addons/__init__.py +26 -18
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/addons/experiment_api.py +37 -4
- pycontrol_core-3.0.0b4/src/pycontrol/addons/loader.py +481 -0
- pycontrol_core-3.0.0b4/src/pycontrol/addons/resources.py +264 -0
- pycontrol_core-3.0.0b4/src/pycontrol/addons/run_context.py +197 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/addons/task_api.py +100 -6
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/analysis/data_import.py +18 -9
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/README.md +1 -1
- pycontrol_core-3.0.0b4/src/pycontrol/bundles/collect.py +127 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/models.py +74 -22
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/protocol.py +65 -18
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/run.py +91 -21
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/zipio.py +45 -5
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bus/README.md +9 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bus/__init__.py +14 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bus/events.py +1 -1
- pycontrol_core-3.0.0b4/src/pycontrol/bus/status.py +241 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/common.py +10 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/experiment_impl.py +1 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/run.py +1 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/run_impl.py +3 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/config/models.py +2 -2
- pycontrol_core-3.0.0b4/src/pycontrol/experiment/README.md +39 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/__init__.py +2 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/hooks.py +36 -8
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/models.py +26 -4
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/planning.py +16 -3
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/run.py +184 -51
- pycontrol_core-3.0.0b4/src/pycontrol/experiment/run_recording.py +214 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/experiment/supervisor.py +70 -42
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/README.md +15 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/__init__.py +1 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/breakout_6port_r0_2_h7.py +2 -5
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/breakout_6port_r1_2_f4.py +1 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/framework.py +43 -9
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/hardware.py +31 -5
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/decoder.py +1 -6
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/provenance/README.md +3 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/provenance/__init__.py +4 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/provenance/archive.py +33 -17
- pycontrol_core-3.0.0b4/src/pycontrol/provenance/collect.py +492 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/provenance/hashing.py +50 -7
- pycontrol_core-3.0.0b4/src/pycontrol/provenance/layout.py +131 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/provenance/models.py +38 -3
- pycontrol_core-3.0.0b4/src/pycontrol/provenance/source.py +51 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/README.md +4 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/native_event_logger.py +31 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/README.md +6 -3
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/README.md +10 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/board_session.py +108 -47
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/device_resolution.py +1 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/protocols.py +16 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/pump.py +20 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/README.md +6 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace/README.md +5 -4
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace/__init__.py +196 -42
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace/creation.py +1 -5
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace/hwdef_inspect.py +2 -2
- pycontrol_core-3.0.0b4/src/pycontrol/workspace/task_inspect.py +322 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/experiments/blink_demo.json +1 -1
- pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/README.md +65 -0
- {pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/tasks/examples → pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker}/blinker-pattern-h7.py +4 -3
- pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker/blinker_dialog.py +28 -0
- pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker/blinker_status.py +38 -0
- {pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/experiment_handlers → pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker}/notion_logger.py +4 -3
- {pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/task_handlers → pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker}/run_notify.py +3 -2
- {pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/experiment_handlers → pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker}/s3_data_exporter.py +4 -3
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/CLASSIFICATION.md +2 -1
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_board_session.py +2 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_cli_workspace.py +39 -29
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_experiment_runner.py +212 -19
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_repl.py +0 -29
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_run.py +304 -24
- pycontrol_core-3.0.0b4/tests/integration/test_run_resources.py +390 -0
- pycontrol_core-3.0.0b4/tests/integration/test_session_failures.py +330 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_hardware_uses_profile.py +4 -10
- pycontrol_core-3.0.0b4/tests/unit/firmware/test_run_sequence.py +396 -0
- pycontrol_core-3.0.0b4/tests/unit/firmware/test_runtime_variable_commands.py +113 -0
- pycontrol_core-3.0.0b4/tests/unit/test_addons.py +850 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_bundles_collect.py +118 -72
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_cli.py +26 -9
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_cli_setups.py +23 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_device_resolution.py +1 -2
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_device_table_consistency.py +0 -6
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_experiment_hook_sequencer.py +8 -4
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_experiment_planning.py +25 -2
- pycontrol_core-3.0.0b4/tests/unit/test_experiment_run_context.py +263 -0
- pycontrol_core-3.0.0b4/tests/unit/test_legacy_run_bundles.py +309 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_protocol_decoder.py +30 -7
- pycontrol_core-3.0.0b4/tests/unit/test_provenance.py +706 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_recording.py +84 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_run_bundle_format.py +68 -20
- pycontrol_core-3.0.0b4/tests/unit/test_run_bundle_v2.py +576 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_run_data_durability.py +23 -13
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_run_recovery.py +21 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_session_pump.py +6 -5
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_session_variables.py +0 -2
- pycontrol_core-3.0.0b4/tests/unit/test_status_fields.py +137 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_supervisor_join.py +109 -1
- pycontrol_core-3.0.0b4/tests/unit/test_task_folders.py +294 -0
- pycontrol_core-3.0.0b4/tests/unit/test_task_resources.py +636 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_workspace.py +27 -54
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_workspace_hwdef_inspect.py +5 -5
- pycontrol_core-3.0.0b4/tests/unit/test_workspace_template.py +46 -0
- pycontrol_core-3.0.0b2/docs/core-walkthrough.md +0 -109
- pycontrol_core-3.0.0b2/docs/release-acceptance.md +0 -115
- pycontrol_core-3.0.0b2/docs/sharing.md +0 -145
- pycontrol_core-3.0.0b2/docs/threading-and-state.md +0 -227
- pycontrol_core-3.0.0b2/docs/troubleshooting.md +0 -257
- pycontrol_core-3.0.0b2/src/pycontrol/addons/README.md +0 -40
- pycontrol_core-3.0.0b2/src/pycontrol/addons/loader.py +0 -363
- pycontrol_core-3.0.0b2/src/pycontrol/bundles/collect.py +0 -265
- pycontrol_core-3.0.0b2/src/pycontrol/bus/status.py +0 -106
- pycontrol_core-3.0.0b2/src/pycontrol/experiment/README.md +0 -35
- pycontrol_core-3.0.0b2/src/pycontrol/experiment/run_recording.py +0 -164
- pycontrol_core-3.0.0b2/src/pycontrol/provenance/collect.py +0 -423
- pycontrol_core-3.0.0b2/src/pycontrol/provenance/source.py +0 -32
- pycontrol_core-3.0.0b2/src/pycontrol/workspace/task_inspect.py +0 -30
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/controls/README.md +0 -113
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/controls/example_dialog.py +0 -20
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/experiment_handlers/README.md +0 -94
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/plotters/README.md +0 -103
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/task_handlers/README.md +0 -86
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/task_handlers/example_handler.py +0 -32
- pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/task_handlers/trial_summary.py +0 -31
- pycontrol_core-3.0.0b2/tests/unit/firmware/test_run_sequence.py +0 -84
- pycontrol_core-3.0.0b2/tests/unit/test_addons.py +0 -620
- pycontrol_core-3.0.0b2/tests/unit/test_provenance.py +0 -348
- pycontrol_core-3.0.0b2/tests/unit/test_status_fields.py +0 -73
- pycontrol_core-3.0.0b2/tests/unit/test_workspace_template.py +0 -36
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.complexipy_cache/.gitignore +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.complexipy_cache/CACHEDIR.TAG +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.complexipy_cache/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.complexipy_cache/v/cache/functions +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.gitignore +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.pre-commit-config.yaml +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/.python-version +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/CONTRIBUTING.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/LICENSE.txt +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/design-history/simplified-pycontrol-provenance-and-sharing-motivation.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/docs/design-history/simplified-pycontrol-provenance-and-sharing-plan.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/pyproject.toml +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/addons/controls_context.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/analysis/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/analysis/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bundles/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/bus/subscriber.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/board.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/board_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/data.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/data_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/experiment.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/firmware.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/firmware_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/gui.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/gui_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/setups.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/setups_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/vars.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/vars_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/workspace.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/commands/workspace_impl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/cli/main.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/config/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/config/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/config/io.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/device_helpers.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/LED_driver.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/MCP.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/VL53L4.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/analog_LED.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/audio_board.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/audio_player.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/breakout_10port_r0_4_h7.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/breakout_10port_r0_8_h7.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/breakout_6port_r0_1_h7.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/five_poke.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/frame_logger.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/frame_trigger.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/grid_maze.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/lickometer.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/load_cell.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/nine_poke.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/poke.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/port_expander.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/rotary_encoder.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/schmitt_trigger.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/solenoid_driver.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/stepper_motor.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/uRFID.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/devices/uart_handler.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/audio.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/profiles.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/state_machine.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/timer.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/firmware/pycontrol/utility.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/fsutil.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/_queue.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/notify/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/notify/slack.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/integrations/notify/telegram.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/mcu.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/analog.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/encoder.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/protocol/messages.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/analog_writer.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/console.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/recording/event_rows.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/device_helpers.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/file_transfer.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/json_repl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/repl/raw_repl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/info.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/link.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/phases.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/rows.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/services/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/services/firmware.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/services/maintenance.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/services/setup.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/services/sync.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/types.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/session/variables.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/testing/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/testing/fake_board.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/testing/frames.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/base.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/mock.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/replay.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/transport/serial.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/devices/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/devices/example_device.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/settings.json +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/src/pycontrol/workspace_template/setups.json +0 -0
- {pycontrol_core-3.0.0b2/src/pycontrol/workspace_template/addons/controls → pycontrol_core-3.0.0b4/src/pycontrol/workspace_template/tasks/examples/blinker}/blinker_gui.json +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/contracts/test_wire_contract.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/machine.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/micropython.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/pyb.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/ucollections.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/firmware_stubs/ujson.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/blinker_real.in.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/blinker_real.out.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/counter_demo_real.in.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/counter_demo_real.out.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/encoder_real.in.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/frames/encoder_real.out.bin +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/replay.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/blinker_real.meta.json +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/blinker_real.tsv +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/counter_demo_real.meta.json +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/counter_demo_real.tsv +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/encoder_real.meta.json +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/encoder_real.tsv +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/encoder_real_encoder.data.npy +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/sessions/encoder_real_encoder.time.npy +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/tasks/blinker_real.task.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/tasks/counter_demo_real.task.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/golden/tasks/encoder_real.task.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/integration/test_real_hardware_replay.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/__init__.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/conftest.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_analog_trigger_variables.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_audio.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_breakout_qwiic.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_device_helpers.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_devices_init.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_profiles.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_rotary_encoder.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_schmitt_trigger_threshold.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_state_machine_variables.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_timer_rounding.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_utility_log.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/firmware/test_vl53l4.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_analysis_data_import.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_board_link.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_bus_subscriber.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_config_models.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_file_transfer_errors.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_firmware_root.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_firmware_service.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_firmware_status.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_integrations_notify.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_maintenance_service.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_phases.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_protocol_encoder.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_public_api.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_raw_repl.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_serial_transport.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_session_rows.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_setup_identity.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_subject_id.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tests/unit/test_transport_mock.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tools/README.md +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tools/capture_fixtures.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tools/hardware_acceptance.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tools/maintainability_metrics.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/tools/run_tests.py +0 -0
- {pycontrol_core-3.0.0b2 → pycontrol_core-3.0.0b4}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pycontrol-core
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.0b4
|
|
4
4
|
Summary: Sans-IO host library for the pyControl behavioural-experiment framework.
|
|
5
5
|
Project-URL: Homepage, https://github.com/pyControl/core
|
|
6
6
|
Author: pyControl contributors
|
|
@@ -91,11 +91,15 @@ uv sync --extra test --extra lint
|
|
|
91
91
|
Run checks:
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
uv run
|
|
94
|
+
uv run python tools/run_tests.py -q
|
|
95
95
|
uv run ruff check src tests
|
|
96
|
+
uv run ruff format --check src tests
|
|
96
97
|
uv run mypy
|
|
97
98
|
```
|
|
98
99
|
|
|
100
|
+
The test runner enforces a process deadline and reports thread traces if a test
|
|
101
|
+
hangs. See [Testing](docs/testing.md) for focused checks and hardware limits.
|
|
102
|
+
|
|
99
103
|
## Create A Workspace
|
|
100
104
|
|
|
101
105
|
Most lab-authored files live in a workspace, not inside this package.
|
|
@@ -110,13 +114,9 @@ The workspace contains:
|
|
|
110
114
|
|
|
111
115
|
| Path | Purpose |
|
|
112
116
|
| --- | --- |
|
|
113
|
-
| `tasks/` | Task files uploaded to the board. |
|
|
117
|
+
| `tasks/` | Task files uploaded to the board, each with its host-side addons (task and experiment handlers, GUI plotters and controls) in its task folder ([task-folders.md](docs/task-folders.md)). |
|
|
114
118
|
| `hardware_definitions/` | Rig wiring files uploaded as `hardware_definition.py`. |
|
|
115
119
|
| `devices/` | Workspace device classes uploaded when referenced. |
|
|
116
|
-
| `addons/task_handlers/` | Host-side task automation. |
|
|
117
|
-
| `addons/experiment_handlers/` | Whole-experiment automation. |
|
|
118
|
-
| `addons/plotters/` | Optional GUI plotters. |
|
|
119
|
-
| `addons/controls/` | Optional GUI control panels. |
|
|
120
120
|
| `experiments/*.json` | Multi-subject experiment definitions. |
|
|
121
121
|
| `settings.json` / `setups.json` | Workspace settings and setup registry. |
|
|
122
122
|
| `data/` | Default output folder for native `.pycontrol.zip` run bundles. |
|
|
@@ -126,7 +126,7 @@ For a full walkthrough, use [getting-started.md](docs/getting-started.md).
|
|
|
126
126
|
## Run A Task
|
|
127
127
|
|
|
128
128
|
```bash
|
|
129
|
-
pycontrol run --setup BoxA --task examples/blinker \
|
|
129
|
+
pycontrol run --setup BoxA --task examples/blinker/blinker-pattern-h7 \
|
|
130
130
|
--subject mouse42 --duration 10
|
|
131
131
|
```
|
|
132
132
|
|
|
@@ -197,6 +197,9 @@ See [public-api.md](docs/public-api.md) for the supported import surface.
|
|
|
197
197
|
Start with [Understanding one run](docs/core-walkthrough.md), then use the
|
|
198
198
|
references below. [Release acceptance](docs/release-acceptance.md) distinguishes
|
|
199
199
|
host verification from the hardware evidence required for lab deployment.
|
|
200
|
+
Ownership and completion rules are detailed in
|
|
201
|
+
[Threading and state](docs/threading-and-state.md). The tradeoffs to
|
|
202
|
+
preserve are recorded in [Maintainability decisions](docs/maintainability.md).
|
|
200
203
|
|
|
201
204
|
Orientation and operation:
|
|
202
205
|
|
|
@@ -49,11 +49,15 @@ uv sync --extra test --extra lint
|
|
|
49
49
|
Run checks:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
uv run
|
|
52
|
+
uv run python tools/run_tests.py -q
|
|
53
53
|
uv run ruff check src tests
|
|
54
|
+
uv run ruff format --check src tests
|
|
54
55
|
uv run mypy
|
|
55
56
|
```
|
|
56
57
|
|
|
58
|
+
The test runner enforces a process deadline and reports thread traces if a test
|
|
59
|
+
hangs. See [Testing](docs/testing.md) for focused checks and hardware limits.
|
|
60
|
+
|
|
57
61
|
## Create A Workspace
|
|
58
62
|
|
|
59
63
|
Most lab-authored files live in a workspace, not inside this package.
|
|
@@ -68,13 +72,9 @@ The workspace contains:
|
|
|
68
72
|
|
|
69
73
|
| Path | Purpose |
|
|
70
74
|
| --- | --- |
|
|
71
|
-
| `tasks/` | Task files uploaded to the board. |
|
|
75
|
+
| `tasks/` | Task files uploaded to the board, each with its host-side addons (task and experiment handlers, GUI plotters and controls) in its task folder ([task-folders.md](docs/task-folders.md)). |
|
|
72
76
|
| `hardware_definitions/` | Rig wiring files uploaded as `hardware_definition.py`. |
|
|
73
77
|
| `devices/` | Workspace device classes uploaded when referenced. |
|
|
74
|
-
| `addons/task_handlers/` | Host-side task automation. |
|
|
75
|
-
| `addons/experiment_handlers/` | Whole-experiment automation. |
|
|
76
|
-
| `addons/plotters/` | Optional GUI plotters. |
|
|
77
|
-
| `addons/controls/` | Optional GUI control panels. |
|
|
78
78
|
| `experiments/*.json` | Multi-subject experiment definitions. |
|
|
79
79
|
| `settings.json` / `setups.json` | Workspace settings and setup registry. |
|
|
80
80
|
| `data/` | Default output folder for native `.pycontrol.zip` run bundles. |
|
|
@@ -84,7 +84,7 @@ For a full walkthrough, use [getting-started.md](docs/getting-started.md).
|
|
|
84
84
|
## Run A Task
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
pycontrol run --setup BoxA --task examples/blinker \
|
|
87
|
+
pycontrol run --setup BoxA --task examples/blinker/blinker-pattern-h7 \
|
|
88
88
|
--subject mouse42 --duration 10
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -155,6 +155,9 @@ See [public-api.md](docs/public-api.md) for the supported import surface.
|
|
|
155
155
|
Start with [Understanding one run](docs/core-walkthrough.md), then use the
|
|
156
156
|
references below. [Release acceptance](docs/release-acceptance.md) distinguishes
|
|
157
157
|
host verification from the hardware evidence required for lab deployment.
|
|
158
|
+
Ownership and completion rules are detailed in
|
|
159
|
+
[Threading and state](docs/threading-and-state.md). The tradeoffs to
|
|
160
|
+
preserve are recorded in [Maintainability decisions](docs/maintainability.md).
|
|
158
161
|
|
|
159
162
|
Orientation and operation:
|
|
160
163
|
|
|
@@ -6,20 +6,22 @@ Use addon settings for values that should not live in a task file or experiment
|
|
|
6
6
|
|
|
7
7
|
## Supported Addon Types
|
|
8
8
|
|
|
9
|
-
Settings can be declared by
|
|
9
|
+
Settings can be declared by the task handlers, experiment handlers and task
|
|
10
|
+
plotters in a [task folder](task-folders.md).
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
The settings are stored separately by addon type and file stem:
|
|
12
|
+
The settings are stored in the workspace `settings.json`, never in the task
|
|
13
|
+
folder, separately by addon type and keyed by the addon's path relative to
|
|
14
|
+
`tasks/` (without `.py`), so same-named addons in two folders keep separate
|
|
15
|
+
settings:
|
|
16
16
|
|
|
17
17
|
```python
|
|
18
|
-
settings.addons.task_handlers["run_notify"]
|
|
19
|
-
settings.addons.experiment_handlers["training_summary"]
|
|
20
|
-
settings.addons.plotters["
|
|
18
|
+
settings.addons.task_handlers["sequence/run_notify"]
|
|
19
|
+
settings.addons.experiment_handlers["training/training_summary"]
|
|
20
|
+
settings.addons.plotters["sequence/sequence_plotter"]
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
The GUI's built-in plot keeps the key `settings.addons.plotters["DefaultPlotter"]`.
|
|
24
|
+
|
|
23
25
|
## Declaring Settings
|
|
24
26
|
|
|
25
27
|
Add a `SETTINGS` tuple to the addon module. Each entry should be made with `BoolSetting`, `IntSetting`, or `StringSetting`.
|
|
@@ -83,6 +85,12 @@ StringSetting("bot_token", "Bot token", secret=True)
|
|
|
83
85
|
|
|
84
86
|
Secret fields are masked in the Settings dialog, but they are still saved in the workspace `settings.json`.
|
|
85
87
|
|
|
88
|
+
A run bundle records the settings each task handler and experiment handler
|
|
89
|
+
was configured with when it loaded, minus the secret ones, whose names it
|
|
90
|
+
lists under `redacted_settings`. Which names are secret is read from the
|
|
91
|
+
`SETTINGS` of the loaded code (module level, or on a class the module
|
|
92
|
+
defines); when that cannot be read, every value of the addon is redacted.
|
|
93
|
+
|
|
86
94
|
All setting helpers accept `hint="..."`. When provided, the Settings dialog shows
|
|
87
95
|
the hint as a tooltip when the user hovers over the setting label.
|
|
88
96
|
|
|
@@ -91,14 +99,14 @@ the hint as a tooltip when the user hovers over the setting label.
|
|
|
91
99
|
At runtime, the addon receives two attributes:
|
|
92
100
|
|
|
93
101
|
```python
|
|
94
|
-
self.addon_settings # dict for this addon
|
|
102
|
+
self.addon_settings # dict for this addon, keyed by its path relative to tasks/
|
|
95
103
|
self.workspace_settings # full workspace Settings object
|
|
96
104
|
```
|
|
97
105
|
|
|
98
|
-
For a task handler file
|
|
106
|
+
For a task handler file `tasks/sequence/run_notify.py`, settings are passed from:
|
|
99
107
|
|
|
100
108
|
```python
|
|
101
|
-
self.workspace_settings.addons.task_handlers["run_notify"]
|
|
109
|
+
self.workspace_settings.addons.task_handlers["sequence/run_notify"]
|
|
102
110
|
```
|
|
103
111
|
|
|
104
112
|
and are usually read through:
|
|
@@ -112,14 +120,14 @@ enabled = self.addon_settings.get("slack_enabled", False)
|
|
|
112
120
|
Task-addon settings are configured for `pycontrol run`, `pycontrol
|
|
113
121
|
experiment`, and GUI-run sessions before callbacks run.
|
|
114
122
|
|
|
115
|
-
For an experiment handler file
|
|
123
|
+
For an experiment handler file `tasks/training/training_summary.py`, settings are passed from:
|
|
116
124
|
|
|
117
125
|
```python
|
|
118
|
-
self.workspace_settings.addons.experiment_handlers["training_summary"]
|
|
126
|
+
self.workspace_settings.addons.experiment_handlers["training/training_summary"]
|
|
119
127
|
```
|
|
120
128
|
|
|
121
129
|
Task plotters use the same stored settings through
|
|
122
|
-
`settings.addons.plotters[stem]`. In the GUI, `PlotterHost` passes that
|
|
130
|
+
`settings.addons.plotters["<folder>/<stem>"]`. In the GUI, `PlotterHost` passes that
|
|
123
131
|
dict to custom plotter constructors as `addon_settings` when the constructor
|
|
124
132
|
accepts that keyword argument.
|
|
125
133
|
|
|
@@ -169,7 +177,7 @@ class RunNotify(TaskHandler):
|
|
|
169
177
|
self._notify.close()
|
|
170
178
|
```
|
|
171
179
|
|
|
172
|
-
|
|
180
|
+
Put the file in the task's folder and select it in the task file:
|
|
173
181
|
|
|
174
182
|
```python
|
|
175
183
|
v.handler = "run_notify"
|
|
@@ -197,19 +205,18 @@ class TelegramExperimentNotify(ExperimentHandler):
|
|
|
197
205
|
print(f"Would notify {chat_id} that {context.experiment_name} finished.")
|
|
198
206
|
```
|
|
199
207
|
|
|
200
|
-
|
|
208
|
+
Put the file in the folder of the experiment's task and select it with the
|
|
209
|
+
experiment setup `Experiment handler` picker.
|
|
201
210
|
|
|
202
211
|
## Settings Dialog Discovery
|
|
203
212
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
addons
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
Files whose names start with `_` are skipped. Files with no valid `SETTINGS` are still valid addons, but they do not get a Settings dialog group.
|
|
213
|
+
When it opens, the Settings dialog lists the task handlers, experiment
|
|
214
|
+
handlers and plotters of every task folder. They are found statically, by a
|
|
215
|
+
class deriving from `TaskHandler`, `ExperimentHandler` or `TaskPlotter`
|
|
216
|
+
(`pycontrol.workspace.classify_task_folder`), then imported to read
|
|
217
|
+
`SETTINGS`. Files whose names start with `_` are helpers and are skipped.
|
|
218
|
+
Files with no valid `SETTINGS` are still valid addons, but they do not get a
|
|
219
|
+
Settings dialog group.
|
|
213
220
|
|
|
214
221
|
Each configurable file page has a `Use defaults` button. It resets only the
|
|
215
222
|
currently selected addon or plotter settings group to the defaults declared
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
This document describes the implemented `pycontrol-core` architecture. It is the
|
|
4
4
|
engine shared by the CLI, `pycontrol-gui`, tests, and downstream Python tools.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Start with [core-walkthrough.md](core-walkthrough.md) for the reading order,
|
|
6
|
+
ownership, and normal and failed runs. This page is the
|
|
7
|
+
package map. [contracts.md](contracts.md) and [public-api.md](public-api.md)
|
|
8
|
+
distinguish frozen compatibility contracts from provisional frontend APIs.
|
|
9
9
|
|
|
10
|
-
The
|
|
10
|
+
The acquisition path is:
|
|
11
11
|
|
|
12
12
|
```text
|
|
13
13
|
Pyboard <-> transport bytes <-> sans-IO protocol <-> BoardSession
|
|
@@ -35,23 +35,27 @@ they are not installed into `pycontrol-core`.
|
|
|
35
35
|
flowchart TD
|
|
36
36
|
Frontends["Frontends: pycontrol CLI, pycontrol-gui, Python APIs"]
|
|
37
37
|
Workspace["workspace/ + config/: discover tasks, setups, experiments, settings"]
|
|
38
|
-
|
|
38
|
+
Run["experiment/ Run: prepare, start, finish"]
|
|
39
|
+
Session["session/ BoardSession: lifecycle, REPL setup, run commands"]
|
|
39
40
|
Pump["session/pump.py SessionPump: read run bytes"]
|
|
40
41
|
Bus["bus/ SubscriberRegistry + typed events"]
|
|
41
42
|
Protocol["protocol/: sans-IO decoder/encoder"]
|
|
42
|
-
Transport["transport/: Serial, Mock, Replay
|
|
43
|
+
Transport["transport/: Serial, Mock, Replay"]
|
|
43
44
|
Board["Pyboard + vendored MicroPython framework"]
|
|
44
45
|
Recording["recording/: NativeEventLogger, analog writer, console"]
|
|
45
46
|
Provenance["provenance/: collect, hash, stage, finalize"]
|
|
46
47
|
Bundles["bundles/: run and protocol ZIP formats"]
|
|
47
|
-
Experiment["experiment/: Supervisor
|
|
48
|
+
Experiment["experiment/: Supervisor + experiment hooks"]
|
|
48
49
|
Addons["addons/: task/experiment APIs, controls specs, loaders"]
|
|
49
50
|
Analysis["analysis/: read run bundles into Python data structures"]
|
|
50
51
|
Firmware["firmware/: on-board framework, devices, profiles"]
|
|
51
52
|
|
|
52
53
|
Frontends --> Workspace
|
|
53
|
-
Frontends -->
|
|
54
|
-
|
|
54
|
+
Frontends --> Run
|
|
55
|
+
Frontends --> Experiment
|
|
56
|
+
Experiment --> Run
|
|
57
|
+
Workspace --> Run
|
|
58
|
+
Run --> Session
|
|
55
59
|
Session --> Transport
|
|
56
60
|
Transport <--> Board
|
|
57
61
|
Transport --> Protocol
|
|
@@ -61,8 +65,8 @@ flowchart TD
|
|
|
61
65
|
Session --> Bus
|
|
62
66
|
Bus --> Recording
|
|
63
67
|
Bus --> Addons
|
|
64
|
-
|
|
65
|
-
Recording -->
|
|
68
|
+
Run --> Provenance
|
|
69
|
+
Recording --> Bundles
|
|
66
70
|
Provenance --> Bundles
|
|
67
71
|
Bundles --> Analysis
|
|
68
72
|
Firmware -. synced to .-> Board
|
|
@@ -79,9 +83,9 @@ flowchart TD
|
|
|
79
83
|
| `provenance/` | File identity, hashing, run staging, protocol references, and run-bundle finalization. |
|
|
80
84
|
| `bundles/` | Run bundle and protocol bundle ZIP readers/writers, manifests, and validation. |
|
|
81
85
|
| `analysis/` | Post-run helpers for reading bundle event tables and session dataframes. |
|
|
82
|
-
| `experiment/` |
|
|
86
|
+
| `experiment/` | Shared single-run `Run`/`RunPlan`, task loading and connection helpers, headless `Supervisor`, rig outcomes and experiment hooks. |
|
|
83
87
|
| `addons/` | Task handlers, experiment handlers, task-controls specs, addon loaders, and settings collection. |
|
|
84
|
-
| `workspace/` | Workspace discovery, path resolution, data-directory resolution, addon lookup, and hwdef inspection. |
|
|
88
|
+
| `workspace/` | Workspace discovery, path resolution, data-directory resolution, task detection, task folders and addon lookup, and hwdef inspection. |
|
|
85
89
|
| `config/` | Pydantic models and load/save helpers for `settings.json`, `setups.json`, and experiments. |
|
|
86
90
|
| `firmware/` | Vendored on-board pyControl framework, board profiles, breakouts, and device drivers. |
|
|
87
91
|
| `integrations/` | Optional notification/storage primitives used by trusted workspace addons. |
|
|
@@ -97,8 +101,8 @@ services (`FirmwareService`, `StateMachineSetupService`,
|
|
|
97
101
|
the stored results (`identity`, `firmware`, `device_sync`, `last_erase`).
|
|
98
102
|
Services never reach back into the session; the one upward call is the link's
|
|
99
103
|
`on_repl_reset` hook, which tells the session to forget its loaded task after a
|
|
100
|
-
recovery soft-reset. The
|
|
101
|
-
|
|
104
|
+
recovery soft-reset. The compatibility tier of each documented surface is listed in
|
|
105
|
+
[public-api.md](public-api.md); internal file layout is not a contract.
|
|
102
106
|
|
|
103
107
|
## Single-Run Pipeline
|
|
104
108
|
|
|
@@ -140,8 +144,9 @@ sequenceDiagram
|
|
|
140
144
|
Run-->>Driver: RunResult(bundle_path | staging_dir + error)
|
|
141
145
|
```
|
|
142
146
|
|
|
143
|
-
`Run.finish()` is the
|
|
144
|
-
|
|
147
|
+
`Run.finish()` is the shared driver entry point that closes and packages a
|
|
148
|
+
recording; lower-level bundle/recovery helpers implement those operations.
|
|
149
|
+
It never reports a packaging failure as success: a missing bundle is an ERROR log, a
|
|
145
150
|
`RunObserver.on_data_at_risk(staging_dir, error)` call, and a non-`ok`
|
|
146
151
|
`RunResult` naming the staging directory. Drivers map that onto their own
|
|
147
152
|
surface (CLI exit 1 + stderr, `RigOutcome.error`, GUI `error` signal).
|
|
@@ -150,6 +155,10 @@ The recorder opens explicitly before framework startup. It stays open through
|
|
|
150
155
|
task-handler end hooks; `Run.finish()` closes it after confirmed completion.
|
|
151
156
|
A recorder error is sticky and makes the result fail even when cleanup succeeds.
|
|
152
157
|
Task/transport failures also produce failed results when partial data is saved.
|
|
158
|
+
An uncertain startup retains its original error and attempted-start metadata,
|
|
159
|
+
then keeps staging instead of packaging it. A completion timeout leaves the
|
|
160
|
+
recorder and resource store owned by `Run` for a later retry. The GUI establishes
|
|
161
|
+
that ownership before calling `Run.start()`.
|
|
153
162
|
|
|
154
163
|
The default completed artifact is a `.pycontrol.zip` native run bundle. During a
|
|
155
164
|
run, `NativeEventLogger` writes the native event table and analog payloads into a
|
|
@@ -175,9 +184,18 @@ Experiment-addon hooks are sequenced by `ExperimentHookSequencer`
|
|
|
175
184
|
`experiment_cancelled` and builds every `ExperimentHookContext` from a
|
|
176
185
|
`{subject_id: RigOutcome}` mapping. `Supervisor` and the GUI's experiment run
|
|
177
186
|
view both drive the same sequencer (the GUI's `SubjectOutcome` *is* a
|
|
178
|
-
`RigOutcome`), so
|
|
187
|
+
`RigOutcome`), so both drivers share the once-only hooks and context construction.
|
|
179
188
|
*When* a rig counts as started or finished stays with each driver.
|
|
180
189
|
|
|
190
|
+
Each experiment run (a GUI run of an experiment, a `Supervisor.run()` call)
|
|
191
|
+
has one fresh experiment handler instance and one `ExperimentRunContext`
|
|
192
|
+
(`addons/run_context.py`), made by `ExperimentRunContext.create` before any
|
|
193
|
+
rig is prepared: a unique `experiment_run_id` plus the frozen JSON
|
|
194
|
+
`shared_data` the handler returns from `shared_run_data()`. The same object
|
|
195
|
+
goes into every rig's `RunPlan.experiment_run` (bound to the task handler by
|
|
196
|
+
`Run.start()` before `prepare_run`) and every hook context, so rigs never wait
|
|
197
|
+
for experiment callbacks to learn which run they belong to.
|
|
198
|
+
|
|
181
199
|
```mermaid
|
|
182
200
|
flowchart LR
|
|
183
201
|
Exp["Experiment config"] --> Supervisor["Supervisor"]
|
|
@@ -194,7 +212,11 @@ flowchart LR
|
|
|
194
212
|
driver calls it directly any more.
|
|
195
213
|
|
|
196
214
|
Each rig records independently. Cross-rig coordination is experiment-hook
|
|
197
|
-
sequencing, not a merged event stream.
|
|
215
|
+
sequencing, not a merged event stream. Duplicate setup assignments are rejected
|
|
216
|
+
before sessions open. The Supervisor uses a finite join grace after its duration
|
|
217
|
+
or stop condition; slow preparation/finalization can consume that grace. A rig
|
|
218
|
+
reported as timed out may still have a daemon thread alive when the CLI exits.
|
|
219
|
+
The workload/timeout decision remains a release gate.
|
|
198
220
|
|
|
199
221
|
## Protocol, Transport, And REPL
|
|
200
222
|
|
|
@@ -218,33 +240,20 @@ fast commands such as `set_variable`, `get_variable`, `trigger_event`, and
|
|
|
218
240
|
|
|
219
241
|
## BoardSession Lifecycle
|
|
220
242
|
|
|
221
|
-
`BoardSession`
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
DISCONNECTED -> CONNECTING -> CONNECTED -> READY -> RUNNING -> STOPPED
|
|
227
|
-
any non-closed state -> CLOSED
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
Valid transitions:
|
|
243
|
+
`BoardSession` alone owns lifecycle state. A normal run follows
|
|
244
|
+
`DISCONNECTED → CONNECTING → CONNECTED → READY → RUNNING → STOPPED`.
|
|
245
|
+
A new task setup moves STOPPED back to READY. The command owner confirms pump
|
|
246
|
+
completion and join before STOPPED; receiving an end marker or bus notification
|
|
247
|
+
alone does not make that transition.
|
|
231
248
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
| `CONNECTED` | `setup_state_machine()` | `READY` |
|
|
238
|
-
| `STOPPED` | `setup_state_machine()` | `READY` |
|
|
239
|
-
| `READY` | `start()` | `RUNNING` |
|
|
240
|
-
| `RUNNING` | `stop()` or board end-of-run marker | `STOPPED` |
|
|
241
|
-
| any non-closed state | `close()` | `CLOSED` |
|
|
249
|
+
Uncertain startup or reader failure makes the session unusable: request stop
|
|
250
|
+
best-effort, complete callbacks, and invalidate to CLOSED. `close()` also reaches
|
|
251
|
+
CLOSED, but raises and remains retryable while callbacks are alive. After
|
|
252
|
+
callbacks finish, transport-disposal errors are logged once and disposal is
|
|
253
|
+
terminal. CLOSED is no proof of physical board stop or OS handle release.
|
|
242
254
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
See `threading-and-state.md` for the authoritative threading and transition
|
|
247
|
-
contract.
|
|
255
|
+
Use [threading-and-state.md](threading-and-state.md) for the authoritative state
|
|
256
|
+
transitions, callback contexts and shutdown barriers.
|
|
248
257
|
|
|
249
258
|
## Event Bus And Subscribers
|
|
250
259
|
|
|
@@ -283,7 +292,8 @@ The bundle contains:
|
|
|
283
292
|
- `meta.json` with run identity, board identity, software versions, variables,
|
|
284
293
|
setup/experiment metadata, and provenance references.
|
|
285
294
|
- Native `events.tsv` with typed rows for info, state, event, variable,
|
|
286
|
-
threshold, print (including operator notes), log, status, warning, and
|
|
295
|
+
threshold, print (including operator notes), log, status, warning, error and
|
|
296
|
+
runtime resource capture.
|
|
287
297
|
- Analog payloads.
|
|
288
298
|
- Snapshots and hashes for task, hardware definition, devices, addons, and
|
|
289
299
|
relevant workspace settings.
|
|
@@ -381,26 +391,18 @@ addon loading around those core surfaces. A future web or service frontend
|
|
|
381
391
|
should be able to use the same core surfaces without changing protocol,
|
|
382
392
|
transport, session, or recording code.
|
|
383
393
|
|
|
384
|
-
##
|
|
385
|
-
|
|
386
|
-
Stable contracts:
|
|
387
|
-
|
|
388
|
-
- Wire protocol and deployed firmware frame semantics.
|
|
389
|
-
- Session state names and valid lifecycle transitions.
|
|
390
|
-
- Bus event dataclass names and callback names.
|
|
391
|
-
- Native run bundle layout.
|
|
392
|
-
- Documented public import surfaces.
|
|
393
|
-
|
|
394
|
-
Implementation details:
|
|
394
|
+
## Compatibility and release readiness
|
|
395
395
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
-
|
|
400
|
-
|
|
396
|
+
The beta freezes addon-author APIs, bus events/callbacks, wire and data formats,
|
|
397
|
+
and the lifecycle rules in [contracts.md](contracts.md). The documented session,
|
|
398
|
+
run, workspace and other frontend Python APIs are **provisional**, as listed in
|
|
399
|
+
[public-api.md](public-api.md). Internal helpers, lock scopes and file layout may
|
|
400
|
+
change while preserving the relevant behavior. Record compatibility changes in
|
|
401
|
+
the contract documents, changelog and behavioral tests.
|
|
401
402
|
|
|
402
|
-
|
|
403
|
-
|
|
403
|
+
A compatibility freeze is not stable-release approval. Physical F4/H7 acceptance,
|
|
404
|
+
a clean release version/dependency-floor pairing, and a Supervisor workload/
|
|
405
|
+
timeout decision remain required; see [release-acceptance.md](release-acceptance.md).
|
|
404
406
|
|
|
405
407
|
## Non-Goals
|
|
406
408
|
|