factorysemantics-mes 0.3.1__tar.gz → 0.4.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.
Files changed (1020) hide show
  1. factorysemantics_mes-0.4.0/.github/scripts/two_nodes_on_one_box.py +369 -0
  2. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/ci.yml +122 -0
  3. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/CHANGELOG.md +159 -1
  4. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/CITATION.cff +2 -2
  5. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/PKG-INFO +2 -2
  6. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/README.md +1 -1
  7. factorysemantics_mes-0.4.0/docker/docker-compose.redundant.yml +184 -0
  8. factorysemantics_mes-0.4.0/docker/nginx.redundant.conf +42 -0
  9. factorysemantics_mes-0.4.0/docker/redundant/fleet.toml +13 -0
  10. factorysemantics_mes-0.4.0/docker/redundant/plant.toml +74 -0
  11. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ARCHITECTURE.md +1 -1
  12. factorysemantics_mes-0.4.0/docs/decisions/0042-one-plant-many-nodes.md +127 -0
  13. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/index.md +1 -0
  14. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/deploy.md +1 -0
  15. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/fleet.md +49 -0
  16. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/packs.md +2 -1
  17. factorysemantics_mes-0.4.0/docs/operate/redundancy.md +395 -0
  18. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/upgrade.md +32 -0
  19. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/releases/0.3.0.md +1 -5
  20. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/releases/0.3.1.md +1 -5
  21. factorysemantics_mes-0.4.0/docs/releases/0.4.0.md +118 -0
  22. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/releases/index.md +1 -0
  23. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/mkdocs.yml +4 -0
  24. factorysemantics_mes-0.4.0/scripts/kill-a-node.sh +264 -0
  25. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/__init__.py +1 -1
  26. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/app.py +10 -2
  27. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/system.py +60 -2
  28. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/cli.py +70 -16
  29. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/config.py +59 -0
  30. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/__init__.py +14 -0
  31. factorysemantics_mes-0.4.0/src/fsmes/domain/leases.py +76 -0
  32. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/commands.py +196 -18
  33. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/console.py +83 -6
  34. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/owned.py +17 -2
  35. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/identity.py +13 -0
  36. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/agent.py +170 -9
  37. factorysemantics_mes-0.4.0/src/fsmes/migrations/versions/b6f0c2a71d58_a_lease_and_a_counter_baseline.py +71 -0
  38. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/modules.py +11 -1
  39. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/check.py +98 -1
  40. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/fleet.py +8 -0
  41. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/format.py +45 -1
  42. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/plant.py +379 -36
  43. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/schema.py +56 -0
  44. factorysemantics_mes-0.4.0/src/fsmes/services/counters.py +69 -0
  45. factorysemantics_mes-0.4.0/src/fsmes/services/leases.py +304 -0
  46. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/operations.py +29 -2
  47. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/common.js +80 -0
  48. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/fleet.css +11 -0
  49. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/fleet.js +72 -0
  50. factorysemantics_mes-0.4.0/tests/test_a_plant_can_run_as_two_nodes_on_one_box_and_the_fleet_knows_both.py +1033 -0
  51. factorysemantics_mes-0.4.0/tests/test_a_plant_on_two_nodes_survives_one_of_them_dying.py +602 -0
  52. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_agent_batching.py +22 -1
  53. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_fleet_create_makes_a_usable_plant.py +67 -0
  54. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_fleet_ownership.py +2 -2
  55. factorysemantics_mes-0.4.0/tests/test_no_command_loses_a_word_of_its_help_to_the_painter.py +78 -0
  56. factorysemantics_mes-0.4.0/tests/test_one_reader_at_a_time_is_a_lease_in_the_database.py +440 -0
  57. factorysemantics_mes-0.4.0/tests/test_the_dashboard_says_which_node_answered_and_who_reads_the_machines.py +318 -0
  58. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_release_body_github_will_accept.py +47 -4
  59. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_simulated_floor_signs_in_again_when_its_login_runs_out.py +31 -0
  60. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.dockerignore +0 -0
  61. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.env.example +0 -0
  62. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/CODEOWNERS +0 -0
  63. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  64. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  65. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/ISSUE_TEMPLATE/integration.yml +0 -0
  66. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/ISSUE_TEMPLATE/plant-pack.yml +0 -0
  67. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  68. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/dependabot.yml +0 -0
  69. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/assistant_folder_from_the_wheel.py +0 -0
  70. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/demo_from_wheel.sh +0 -0
  71. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/doctor_writes_nothing_of_yours.py +0 -0
  72. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/lab_starters.sh +0 -0
  73. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/plant_from_shape.py +0 -0
  74. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/plant_from_wheel.py +0 -0
  75. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/recover_a_half_dead_plant.py +0 -0
  76. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/release_notes.sh +0 -0
  77. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/scripts/upgrade_from_previous_release.sh +0 -0
  78. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/dco.yml +0 -0
  79. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/docs.yml +0 -0
  80. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/erpnext-live.yml +0 -0
  81. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/release.yml +0 -0
  82. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/scorecard.yml +0 -0
  83. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.github/workflows/welcome.yml +0 -0
  84. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/.gitignore +0 -0
  85. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/CODE_OF_CONDUCT.md +0 -0
  86. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/CONTRIBUTING.md +0 -0
  87. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/GOVERNANCE.md +0 -0
  88. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/LICENSE +0 -0
  89. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/MAINTAINERS.md +0 -0
  90. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/NOTICE +0 -0
  91. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/ROADMAP.md +0 -0
  92. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/SECURITY.md +0 -0
  93. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/alembic.ini +0 -0
  94. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/inbound_mapping.json +0 -0
  95. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/inbound_sql.json +0 -0
  96. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/line_layout.json +0 -0
  97. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/tag_map.json +0 -0
  98. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/tag_map_kepsim.json +0 -0
  99. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/config/tag_map_kepware.json +0 -0
  100. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/deploy/README.md +0 -0
  101. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/deploy/fsmes-autoloop.service +0 -0
  102. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/deploy/fsmes-autoloop.timer +0 -0
  103. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/deploy/fsmes-prod-plant@.service +0 -0
  104. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/deploy/promote.sh +0 -0
  105. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docker/Dockerfile +0 -0
  106. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docker/docker-compose.yml +0 -0
  107. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docker/nginx.conf +0 -0
  108. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/LANDSCAPE.md +0 -0
  109. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/agents/connect-mcp-client.md +0 -0
  110. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/agents/evals.md +0 -0
  111. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/agents/index.md +0 -0
  112. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/agents/write-discipline.md +0 -0
  113. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/ASSIST-EVAL.md +0 -0
  114. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/BUDGET.md +0 -0
  115. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/JEV-CALIBRATION.md +0 -0
  116. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/JEV.md +0 -0
  117. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/JUDGMENT-IN-THE-BUILD-LOOP.md +0 -0
  118. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/OBSERVABILITY.md +0 -0
  119. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/assist-eval/2026-09-27-live-admin.md +0 -0
  120. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/assist-eval/2026-09-27-live-operator.md +0 -0
  121. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/assist-eval/2026-09-27-scripted.md +0 -0
  122. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/calibration.md +0 -0
  123. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/d1-against-truth.json +0 -0
  124. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/d1-component-stopped-reporting.svg +0 -0
  125. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/d1-counter-went-backwards.svg +0 -0
  126. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/p1-by-confidence.svg +0 -0
  127. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/full/p1-by-probability.svg +0 -0
  128. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/calibration.md +0 -0
  129. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/d1-against-truth.json +0 -0
  130. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/d1-component-stopped-reporting.svg +0 -0
  131. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/d1-counter-went-backwards.svg +0 -0
  132. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/p1-by-confidence.svg +0 -0
  133. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/ai/calibration/2026-09-17/stopped-not-why/p1-by-probability.svg +0 -0
  134. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/assets/walk.gif +0 -0
  135. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0001-apache-2-with-dco.md +0 -0
  136. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0002-kernel-and-modules.md +0 -0
  137. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0003-one-mcp-server.md +0 -0
  138. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0004-never-invent-production.md +0 -0
  139. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0005-plain-html-no-build-step.md +0 -0
  140. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0006-sqlite-laptop-postgresql-plant.md +0 -0
  141. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0007-fresh-public-history.md +0 -0
  142. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0008-erp-connectors-are-modules.md +0 -0
  143. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0009-organisation-not-personal-account.md +0 -0
  144. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0010-github-discussions-only.md +0 -0
  145. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0011-mkdocs-material-generated-reference.md +0 -0
  146. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0012-contributor-covenant-3.md +0 -0
  147. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0013-governance-is-one-page.md +0 -0
  148. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0014-first-public-version-is-0-1-0.md +0 -0
  149. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0015-mcp-registry-name.md +0 -0
  150. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0016-no-trademark-registration.md +0 -0
  151. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0017-one-public-demo-gated-and-bounded.md +0 -0
  152. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0018-public-on-2026-09-08-and-the-pre-tag-check.md +0 -0
  153. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0019-count-everything-the-machine-counted.md +0 -0
  154. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0020-what-supported-means-for-an-erp-connector.md +0 -0
  155. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0021-one-database-per-plant.md +0 -0
  156. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0022-what-a-plant-pack-may-contain.md +0 -0
  157. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0023-the-fleet-console-observes.md +0 -0
  158. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0024-a-nonconformance-has-a-life.md +0 -0
  159. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0025-performance-is-measured-not-capped.md +0 -0
  160. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0026-counts-that-outrun-the-run-time.md +0 -0
  161. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0027-an-spc-signal-raises-a-hold.md +0 -0
  162. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0028-which-shift-a-minute-belongs-to.md +0 -0
  163. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0029-an-order-does-not-finish-itself.md +0 -0
  164. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0030-a-lost-connection-is-unknown-time.md +0 -0
  165. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0031-a-judgment-is-a-proposal.md +0 -0
  166. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0032-a-hosted-judgment-and-the-shadow.md +0 -0
  167. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0033-availability-is-a-share-of-what-was-watched.md +0 -0
  168. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0034-a-count-is-owed-until-it-is-booked.md +0 -0
  169. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0035-configuration-is-authored-by-roles-and-selected-by-operators.md +0 -0
  170. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0036-the-chart-draws-every-rule-the-plant-chooses-which-hold.md +0 -0
  171. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0038-an-agent-is-an-account-with-a-role-a-budget-and-a-cadence.md +0 -0
  172. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0039-an-analysis-is-recorded-code-that-can-only-read.md +0 -0
  173. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0040-the-chart-type-follows-the-sampling-plan.md +0 -0
  174. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/0041-a-characteristic-the-plant-counts.md +0 -0
  175. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/decisions/TEMPLATE.md +0 -0
  176. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/STYLE.md +0 -0
  177. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/agentic-harness.md +0 -0
  178. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/README.md +0 -0
  179. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/admin-edit-roles.md +0 -0
  180. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/analysis-cards-scaling.md +0 -0
  181. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/assistant-submits-an-inspection.md +0 -0
  182. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/book-output-explicit-order.md +0 -0
  183. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/clickable-kpi-tiles.md +0 -0
  184. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/clickable-machine-breadcrumbs.md +0 -0
  185. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/floor-machines-paginate-and-filter.md +0 -0
  186. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/measurements-card-filtering.md +0 -0
  187. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/measurements-characteristic-filter.md +0 -0
  188. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/nonconformance-lifecycle.md +0 -0
  189. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/opc-integration-suite.md +0 -0
  190. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/order-card-search-finds-a-material.md +0 -0
  191. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/order-lifecycle-actions.md +0 -0
  192. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/orders-creatable-materials.md +0 -0
  193. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/orders-supervisor-filters.md +0 -0
  194. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/persistent-header-menu.md +0 -0
  195. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/review-orders.md +0 -0
  196. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/review-station.md +0 -0
  197. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/scrap-reason-codes.md +0 -0
  198. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/shop-floor-actions-strip.md +0 -0
  199. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/sixty-machine-plant.md +0 -0
  200. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/spc-capability-withheld.md +0 -0
  201. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/specifications-card-filtering.md +0 -0
  202. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/specifications-server-paged.md +0 -0
  203. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/station-quality-card.md +0 -0
  204. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/station-spc.md +0 -0
  205. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/station-view.md +0 -0
  206. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/supervisor-drill-down.md +0 -0
  207. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/backlog/ui-style-drift-bc58fb4f8e4d.md +0 -0
  208. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/config-assistance.md +0 -0
  209. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/config-audit-2026-09-21.md +0 -0
  210. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/deep-analysis.md +0 -0
  211. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/m8-packs-and-fleet.md +0 -0
  212. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/design/pack-in-pack.md +0 -0
  213. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/develop/erp-connectors.md +0 -0
  214. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/develop/experiments.md +0 -0
  215. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/develop/index.md +0 -0
  216. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/develop/your-first-module.md +0 -0
  217. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/history/private-era.md +0 -0
  218. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/hooks/generate.py +0 -0
  219. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/index.md +0 -0
  220. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/onboarding/GUIDE-ENGINEERING.md +0 -0
  221. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/onboarding/GUIDE-IT.md +0 -0
  222. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/onboarding/README.md +0 -0
  223. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/onboarding/worksheet-example.csv +0 -0
  224. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/onboarding/worksheet-template.csv +0 -0
  225. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/administration-numbers.md +0 -0
  226. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/ai.md +0 -0
  227. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/assistant-coverage.md +0 -0
  228. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/backup.md +0 -0
  229. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/compatibility.md +0 -0
  230. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-with-a-lot.json +0 -0
  231. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-with-a-lot.xml +0 -0
  232. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-with-an-over-run.json +0 -0
  233. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-with-an-over-run.xml +0 -0
  234. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-without-a-lot.json +0 -0
  235. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/completion-without-a-lot.xml +0 -0
  236. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-clean.json +0 -0
  237. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-clean.xml +0 -0
  238. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-over-run.json +0 -0
  239. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-over-run.xml +0 -0
  240. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-with-scrap-and-components.json +0 -0
  241. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-examples/operation-with-scrap-and-components.xml +0 -0
  242. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/confirmation-files.md +0 -0
  243. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/coverage.md +0 -0
  244. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/doctor.md +0 -0
  245. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/engineering-numbers.md +0 -0
  246. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/erp-settings.md +0 -0
  247. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/erpnext.md +0 -0
  248. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/first-plant.md +0 -0
  249. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/first-week.md +0 -0
  250. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/images/review-walk-station.png +0 -0
  251. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/images/review-walkthrough.png +0 -0
  252. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/images/shape-equipment.png +0 -0
  253. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/images/shape-timeline.png +0 -0
  254. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/inbound.md +0 -0
  255. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/index.md +0 -0
  256. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/modules.md +0 -0
  257. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/opc-disconnections.md +0 -0
  258. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/opc-readonly.md +0 -0
  259. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/plant-from-your-mes.md +0 -0
  260. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/quality-numbers.md +0 -0
  261. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/quality-severities.md +0 -0
  262. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/registry.md +0 -0
  263. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/releasing.md +0 -0
  264. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/run-it-on-your-own-box.md +0 -0
  265. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/security.md +0 -0
  266. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/shadow-mode.md +0 -0
  267. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/shadow-scorecard.md +0 -0
  268. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/the-simulated-floor.md +0 -0
  269. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/tls.md +0 -0
  270. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/uns.md +0 -0
  271. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/operate/who-names-the-reasons.md +0 -0
  272. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/first-line.md +0 -0
  273. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/images/spc-xbar-and-r.png +0 -0
  274. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/index.md +0 -0
  275. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/never-invent-production.md +0 -0
  276. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/quality-signals.md +0 -0
  277. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/reading-a-trend.md +0 -0
  278. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/reading-oee.md +0 -0
  279. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/plant/shifts.md +0 -0
  280. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/docs/releases/0.2.0.md +0 -0
  281. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/README.md +0 -0
  282. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/analysis/build_notebook.py +0 -0
  283. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/analysis/build_report.py +0 -0
  284. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/analysis/cutlery_run_analysis.ipynb +0 -0
  285. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/analysis/viz.py +0 -0
  286. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/build_config.py +0 -0
  287. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/fill_day.py +0 -0
  288. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/fleet.toml +0 -0
  289. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/init.py +0 -0
  290. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/line.json +0 -0
  291. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/make_tag_map.py +0 -0
  292. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/masterdata/downtime_reasons.json +0 -0
  293. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/masterdata/nc_severities.json +0 -0
  294. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/plant.toml +0 -0
  295. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/run_cutlery.py +0 -0
  296. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/tag_map.json +0 -0
  297. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/walkthroughs/install_walkthroughs.py +0 -0
  298. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/cutlery/walkthroughs/walkthroughs.json +0 -0
  299. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/erpnext/VERSIONS.md +0 -0
  300. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/erpnext/docker-compose.yml +0 -0
  301. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/erpnext/seed_erpnext.py +0 -0
  302. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/lost-connection.toml +0 -0
  303. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/one-line-bad-hour.toml +0 -0
  304. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/over-run.toml +0 -0
  305. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/scrap-burst.toml +0 -0
  306. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/starved-and-blocked.toml +0 -0
  307. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/experiments/two-plants-two-zones.toml +0 -0
  308. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/.env.example +0 -0
  309. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/README.md +0 -0
  310. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/kepware_setup.py +0 -0
  311. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/line.json +0 -0
  312. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/scenario.md +0 -0
  313. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/setup_dsn.ps1 +0 -0
  314. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/kepsim/verify_readback.py +0 -0
  315. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/build_config.py +0 -0
  316. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/fleet.toml +0 -0
  317. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/build_config.py +0 -0
  318. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/init.py +0 -0
  319. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/line.json +0 -0
  320. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/plant.toml +0 -0
  321. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/run_full.py +0 -0
  322. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/seed_breadth.py +0 -0
  323. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/surfaces.py +0 -0
  324. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/full/tag_map.json +0 -0
  325. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/init.py +0 -0
  326. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/line.json +0 -0
  327. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/make_tag_map.py +0 -0
  328. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/run_spike.py +0 -0
  329. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/seed_breadth.py +0 -0
  330. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/megafactory/tag_map.json +0 -0
  331. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/README.md +0 -0
  332. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/floor.json +0 -0
  333. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/line.json +0 -0
  334. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/README.md +0 -0
  335. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/bom.json +0 -0
  336. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/dispatch_rules.json +0 -0
  337. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/downtime_reasons.json +0 -0
  338. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/equipment.json +0 -0
  339. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/gauges.json +0 -0
  340. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/lots.json +0 -0
  341. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/maintenance_plans.json +0 -0
  342. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/materials.json +0 -0
  343. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/nc_severities.json +0 -0
  344. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/personnel.json +0 -0
  345. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/personnel_skills.json +0 -0
  346. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/quality_specs.json +0 -0
  347. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/roster.json +0 -0
  348. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/routings.json +0 -0
  349. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/shifts.json +0 -0
  350. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/skills.json +0 -0
  351. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/masterdata/work_orders.json +0 -0
  352. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/plant.toml +0 -0
  353. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/bottling/tag_map.json +0 -0
  354. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/README.md +0 -0
  355. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/floor.json +0 -0
  356. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/mappings/inbound_mapping.json +0 -0
  357. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/downtime_reasons.json +0 -0
  358. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/equipment.json +0 -0
  359. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/lots.json +0 -0
  360. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/materials.json +0 -0
  361. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/nc_severities.json +0 -0
  362. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/quality_specs.json +0 -0
  363. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/routings.json +0 -0
  364. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/masterdata/work_orders.json +0 -0
  365. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/plant.toml +0 -0
  366. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/finewire/tag_map.json +0 -0
  367. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/fleet.toml +0 -0
  368. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/floor.json +0 -0
  369. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/line.json +0 -0
  370. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/README.md +0 -0
  371. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/downtime_reasons.json +0 -0
  372. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/equipment.json +0 -0
  373. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/lots.json +0 -0
  374. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/materials.json +0 -0
  375. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/nc_severities.json +0 -0
  376. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/quality_specs.json +0 -0
  377. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/routings.json +0 -0
  378. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/masterdata/work_orders.json +0 -0
  379. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/plant.toml +0 -0
  380. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/labs/multiplant/machining/tag_map.json +0 -0
  381. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/pyproject.toml +0 -0
  382. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/0-how-to-help.md +0 -0
  383. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/1-install.md +0 -0
  384. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/2-your-plant.md +0 -0
  385. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/3-shadow-mode.md +0 -0
  386. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/4-migration.md +0 -0
  387. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/README.md +0 -0
  388. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/assistant/SKILL.md +0 -0
  389. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/FORMAT.md +0 -0
  390. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/SKILL.md +0 -0
  391. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/example/plant-shape-grouped.toml +0 -0
  392. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/example/plant-shape.toml +0 -0
  393. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/01_inventory.sql +0 -0
  394. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/01b_row_count.sql +0 -0
  395. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/02_columns.sql +0 -0
  396. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/03_window.sql +0 -0
  397. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/04_column_profile.sql +0 -0
  398. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/04b_column_sample.sql +0 -0
  399. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/05_assets.sql +0 -0
  400. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/05b_tag_samples.sql +0 -0
  401. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/05c_tag_samples_nostate.sql +0 -0
  402. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/05d_routings.sql +0 -0
  403. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06_states.sql +0 -0
  404. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06b_production.sql +0 -0
  405. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06c_quality.sql +0 -0
  406. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06d_orders.sql +0 -0
  407. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06e_shifts.sql +0 -0
  408. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/06f_documents.sql +0 -0
  409. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/mssql/07_erp.sql +0 -0
  410. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/01_inventory.sql +0 -0
  411. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/01b_row_count.sql +0 -0
  412. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/02_columns.sql +0 -0
  413. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/03_window.sql +0 -0
  414. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/04_column_profile.sql +0 -0
  415. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/04b_column_sample.sql +0 -0
  416. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/05_assets.sql +0 -0
  417. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/05b_tag_samples.sql +0 -0
  418. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/05c_tag_samples_nostate.sql +0 -0
  419. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/05d_routings.sql +0 -0
  420. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06_states.sql +0 -0
  421. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06b_production.sql +0 -0
  422. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06c_quality.sql +0 -0
  423. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06d_orders.sql +0 -0
  424. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06e_shifts.sql +0 -0
  425. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/06f_documents.sql +0 -0
  426. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/queries/sqlite/07_erp.sql +0 -0
  427. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/scripts/explain.py +0 -0
  428. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/scripts/leakcheck.py +0 -0
  429. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/skills/plant-from-your-mes/scripts/profile.py +0 -0
  430. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/__main__.py +0 -0
  431. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/__init__.py +0 -0
  432. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/deps.py +0 -0
  433. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/idempotency.py +0 -0
  434. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/paging.py +0 -0
  435. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/__init__.py +0 -0
  436. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/adjustments.py +0 -0
  437. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/admin.py +0 -0
  438. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/analysis.py +0 -0
  439. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/assist.py +0 -0
  440. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/auth.py +0 -0
  441. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/coa.py +0 -0
  442. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/dashboard.py +0 -0
  443. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/design.py +0 -0
  444. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/documents.py +0 -0
  445. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/equipment.py +0 -0
  446. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/erp.py +0 -0
  447. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/execution.py +0 -0
  448. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/kpis.py +0 -0
  449. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/line.py +0 -0
  450. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/maintenance.py +0 -0
  451. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/masterdata.py +0 -0
  452. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/ops.py +0 -0
  453. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/quality.py +0 -0
  454. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/reasons.py +0 -0
  455. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/scheduling.py +0 -0
  456. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/serialization.py +0 -0
  457. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/severities.py +0 -0
  458. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/triggers.py +0 -0
  459. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/api/routers/workorders.py +0 -0
  460. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/assist_coverage.py +0 -0
  461. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/backup.py +0 -0
  462. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/core/__init__.py +0 -0
  463. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/core/oplock.py +0 -0
  464. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/db.py +0 -0
  465. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/demo_feed.py +0 -0
  466. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/doctor/__init__.py +0 -0
  467. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/doctor/gather.py +0 -0
  468. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/doctor/leak.py +0 -0
  469. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/doctor/render.py +0 -0
  470. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/doctor/scrub.py +0 -0
  471. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/adjustments.py +0 -0
  472. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/ai_turns.py +0 -0
  473. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/audit.py +0 -0
  474. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/calendar.py +0 -0
  475. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/common.py +0 -0
  476. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/crew.py +0 -0
  477. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/documents.py +0 -0
  478. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/equipment.py +0 -0
  479. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/execution.py +0 -0
  480. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/gauges.py +0 -0
  481. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/idempotency.py +0 -0
  482. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/inbound.py +0 -0
  483. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/integration.py +0 -0
  484. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/maintenance.py +0 -0
  485. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/masterdata.py +0 -0
  486. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/plant_settings.py +0 -0
  487. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/quality.py +0 -0
  488. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/reasons.py +0 -0
  489. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/scheduling.py +0 -0
  490. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/serialization.py +0 -0
  491. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/severities.py +0 -0
  492. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/timeseries.py +0 -0
  493. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/triggers.py +0 -0
  494. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/uns.py +0 -0
  495. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/domain/workorders.py +0 -0
  496. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/firstrun.py +0 -0
  497. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/__init__.py +0 -0
  498. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/logsink.py +0 -0
  499. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/fleet/observe.py +0 -0
  500. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/__init__.py +0 -0
  501. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/__init__.py +0 -0
  502. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/b2mml.py +0 -0
  503. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/base.py +0 -0
  504. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/conformance.py +0 -0
  505. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/contract.py +0 -0
  506. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/erpnext_adapter.py +0 -0
  507. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/erpnext_setup.py +0 -0
  508. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/examples.py +0 -0
  509. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/file_adapter.py +0 -0
  510. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/incumbent.py +0 -0
  511. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/mock_erp.py +0 -0
  512. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/rest_adapter.py +0 -0
  513. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/schema.py +0 -0
  514. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/scorecard.py +0 -0
  515. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/scorecard_html.py +0 -0
  516. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/sync.py +0 -0
  517. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/erp/validate.py +0 -0
  518. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/events.py +0 -0
  519. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/inbound/__init__.py +0 -0
  520. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/inbound/contract.py +0 -0
  521. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/inbound/folder.py +0 -0
  522. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/inbound/mqtt.py +0 -0
  523. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/inbound/sql.py +0 -0
  524. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/jev/__init__.py +0 -0
  525. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/jev/client.py +0 -0
  526. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/jev/transport.py +0 -0
  527. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/__init__.py +0 -0
  528. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/csv_replay.py +0 -0
  529. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/inspect.py +0 -0
  530. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/security.py +0 -0
  531. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/simulator.py +0 -0
  532. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/tag_map.py +0 -0
  533. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/opc/worksheet.py +0 -0
  534. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/uns/__init__.py +0 -0
  535. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/uns/envelope.py +0 -0
  536. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/uns/publisher.py +0 -0
  537. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/uns/topics.py +0 -0
  538. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/integrations/uns/transport.py +0 -0
  539. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/kernel/__init__.py +0 -0
  540. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/kernel/common.py +0 -0
  541. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/kernel/tags.py +0 -0
  542. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/__init__.py +0 -0
  543. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/assist_eval.py +0 -0
  544. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/assist_fixtures.py +0 -0
  545. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/assist_seed.py +0 -0
  546. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/build.py +0 -0
  547. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/console.py +0 -0
  548. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/feedback.py +0 -0
  549. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/measure.py +0 -0
  550. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/observe.py +0 -0
  551. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/plan.py +0 -0
  552. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/report.py +0 -0
  553. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/review.py +0 -0
  554. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/run.py +0 -0
  555. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/lab/truth.py +0 -0
  556. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/logging.py +0 -0
  557. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/__init__.py +0 -0
  558. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/adjustments.py +0 -0
  559. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/analysis.py +0 -0
  560. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/coa.py +0 -0
  561. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/equipment.py +0 -0
  562. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/erp.py +0 -0
  563. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/maintenance.py +0 -0
  564. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/masterdata.py +0 -0
  565. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/quality.py +0 -0
  566. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/reasons.py +0 -0
  567. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/scheduling.py +0 -0
  568. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/serialization.py +0 -0
  569. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/settings.py +0 -0
  570. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/severities.py +0 -0
  571. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp/triggers.py +0 -0
  572. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/mcp_server.py +0 -0
  573. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migration.py +0 -0
  574. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/env.py +0 -0
  575. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/script.py.mako +0 -0
  576. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/153379d6cf19_merge_cutlery_and_walkthrough_chains.py +0 -0
  577. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/18af853fc5c4_initial_schema.py +0 -0
  578. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/7c1e5a9d2b4f_serial_sequences.py +0 -0
  579. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/9c4d2c836d05_add_user_passwords.py +0 -0
  580. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a1b2c3d4e5f6_agent_identity.py +0 -0
  581. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a1c47f8b2d93_what_a_maintenance_job_needs_of_the_line.py +0 -0
  582. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a1c5e70b2d94_plant_settings.py +0 -0
  583. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a1c5e83b7602_calendar_and_scheduling.py +0 -0
  584. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a3f6c81d09e2_unassigned_production.py +0 -0
  585. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a4d9c2e70f18_uns_publications.py +0 -0
  586. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a7c1e93b5f20_roles_as_data.py +0 -0
  587. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a7c2e5d1b9f0_document_kind_steps_needs_walkthroughs.py +0 -0
  588. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/a9c4e17b3d60_spc_signals_act.py +0 -0
  589. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b1f4c73a9e08_nonconformance_lifecycle.py +0 -0
  590. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b1f4c7a2e903_production_logs_equipment_ts_index.py +0 -0
  591. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b2c3d4e5f6a7_outbox_hardening.py +0 -0
  592. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b3f8d2a41c67_controlled_documents.py +0 -0
  593. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b3f9c07e51ad_ai_turns.py +0 -0
  594. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b5c1d09e73af_inbound_events_and_their_source.py +0 -0
  595. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b7d2e9f4a1c3_unit_inspections.py +0 -0
  596. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b8f4d27e1a53_serialisation.py +0 -0
  597. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/b9f31c7a4e50_a_characteristic_inspected_n_at_a_time.py +0 -0
  598. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c1e7a04b93d5_downtime_reasons.py +0 -0
  599. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c2e9b74a3f81_gauges_and_calibration.py +0 -0
  600. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c3d4e5f6a7b8_triggers.py +0 -0
  601. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c3d7e91a4b28_equipment_connections.py +0 -0
  602. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c4e8f1a2d5b6_serial_units_one_index.py +0 -0
  603. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c6a4b81f39d7_shift_attribution.py +0 -0
  604. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c7a2e94b16d3_five_facts_the_plant_was_dropping.py +0 -0
  605. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c8b1e40d7a92_erp_messages_direction_index.py +0 -0
  606. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/c9e2a4b71d38_material_at_a_station.py +0 -0
  607. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d2b7e51c9a04_nc_severities.py +0 -0
  608. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d4a1c7e5b902_equipment_cost_center.py +0 -0
  609. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d4a7f10c8b52_component_may_enter_twice.py +0 -0
  610. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d4e5f6a7b8c9_recommended_adjustments.py +0 -0
  611. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d4e8a1c93b70_a_characteristic_the_plant_counts.py +0 -0
  612. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d7b4e92a1c58_the_maintenance_crew_and_its_rules.py +0 -0
  613. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/d9a3f61c48e0_inbound_sql_watermarks.py +0 -0
  614. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/e3c8a17d5b46_gauge_warning_and_pieces.py +0 -0
  615. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/e5f6a7b8c9d0_tag_values_latest_index.py +0 -0
  616. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/e6b3c92d4f17_drop_the_old_bom_constraint.py +0 -0
  617. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/e7b3c9d18a45_workorder_work_center.py +0 -0
  618. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/f0a1b2c3d4e5_equipment_states_ended_index.py +0 -0
  619. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/f2a8d31c6b74_routing_durations.py +0 -0
  620. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/migrations/versions/f7d1a58e2c94_preventive_maintenance.py +0 -0
  621. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/__init__.py +0 -0
  622. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/apply.py +0 -0
  623. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/masterdata.py +0 -0
  624. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/migrate.py +0 -0
  625. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/plan.py +0 -0
  626. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/pack/repoint.py +0 -0
  627. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/py.typed +0 -0
  628. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/seed.py +0 -0
  629. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/seed_kepsim.py +0 -0
  630. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/seed_line.py +0 -0
  631. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/__init__.py +0 -0
  632. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/adjustments.py +0 -0
  633. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/agent.py +0 -0
  634. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/ai_status.py +0 -0
  635. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/ai_trace.py +0 -0
  636. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/analysis.py +0 -0
  637. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/assist_eval.py +0 -0
  638. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/assistant.py +0 -0
  639. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/audit.py +0 -0
  640. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/auth.py +0 -0
  641. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/calendar.py +0 -0
  642. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/capabilities.py +0 -0
  643. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/coa.py +0 -0
  644. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/connection.py +0 -0
  645. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/coverage.py +0 -0
  646. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/design.py +0 -0
  647. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/design_triage.py +0 -0
  648. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/dispatch.py +0 -0
  649. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/documents.py +0 -0
  650. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/drafting.py +0 -0
  651. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/equipment.py +0 -0
  652. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/erp.py +0 -0
  653. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/execution.py +0 -0
  654. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/gauges.py +0 -0
  655. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/inbound.py +0 -0
  656. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/line.py +0 -0
  657. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/line_clock.py +0 -0
  658. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/maintenance.py +0 -0
  659. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/masterdata.py +0 -0
  660. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/moment.py +0 -0
  661. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/oee.py +0 -0
  662. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/outbox.py +0 -0
  663. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/plant_settings.py +0 -0
  664. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/quality.py +0 -0
  665. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/reasons.py +0 -0
  666. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/retention.py +0 -0
  667. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/review.py +0 -0
  668. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/scheduling.py +0 -0
  669. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/serialization.py +0 -0
  670. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/severities.py +0 -0
  671. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/spc.py +0 -0
  672. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/spc_point.py +0 -0
  673. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/staging.py +0 -0
  674. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/state_block.py +0 -0
  675. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/tags.py +0 -0
  676. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/trace_analysis.py +0 -0
  677. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/trend.py +0 -0
  678. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/triggers.py +0 -0
  679. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/uns.py +0 -0
  680. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/vocabulary.py +0 -0
  681. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/walkthroughs.py +0 -0
  682. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/services/workorders.py +0 -0
  683. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/shadow.py +0 -0
  684. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/shape/__init__.py +0 -0
  685. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/shape/model.py +0 -0
  686. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/shape/pack.py +0 -0
  687. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/shape/read.py +0 -0
  688. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/__init__.py +0 -0
  689. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/agent_eval.py +0 -0
  690. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/autoloop.py +0 -0
  691. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/calibration.py +0 -0
  692. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/config_audit.py +0 -0
  693. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/config_audit_curated.py +0 -0
  694. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/generate.py +0 -0
  695. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/labelled.py +0 -0
  696. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/mcp_server.py +0 -0
  697. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/measurement.py +0 -0
  698. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/rollup.py +0 -0
  699. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/runner.py +0 -0
  700. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/score.py +0 -0
  701. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/store.py +0 -0
  702. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/sweep.py +0 -0
  703. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/triage.py +0 -0
  704. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/truth.py +0 -0
  705. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/sim/ui_check.py +0 -0
  706. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/skills.py +0 -0
  707. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/standalone.py +0 -0
  708. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/storage.py +0 -0
  709. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/adjustments.html +0 -0
  710. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/adjustments.js +0 -0
  711. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/admin.css +0 -0
  712. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/admin.html +0 -0
  713. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/admin.js +0 -0
  714. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ai.css +0 -0
  715. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ai.html +0 -0
  716. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ai.js +0 -0
  717. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/analysis.css +0 -0
  718. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/analysis.html +0 -0
  719. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/analysis.js +0 -0
  720. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/app.js +0 -0
  721. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/assist-record.js +0 -0
  722. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/assist.css +0 -0
  723. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/assist.js +0 -0
  724. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/coa.css +0 -0
  725. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/coa.html +0 -0
  726. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/coa.js +0 -0
  727. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/config.html +0 -0
  728. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/config.js +0 -0
  729. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/demo/kepsim-hour.json +0 -0
  730. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/design.css +0 -0
  731. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/design.js +0 -0
  732. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/fleet.html +0 -0
  733. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/gauges.html +0 -0
  734. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/gauges.js +0 -0
  735. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/index.html +0 -0
  736. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/instructions.css +0 -0
  737. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/instructions.html +0 -0
  738. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/instructions.js +0 -0
  739. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/kit.js +0 -0
  740. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/app.js +0 -0
  741. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/feed.js +0 -0
  742. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/flow.js +0 -0
  743. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/parts.js +0 -0
  744. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/robot.js +0 -0
  745. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line/scene.js +0 -0
  746. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line-page.js +0 -0
  747. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line.css +0 -0
  748. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line.html +0 -0
  749. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/line3d.html +0 -0
  750. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/machine.css +0 -0
  751. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/machine.html +0 -0
  752. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/machine.js +0 -0
  753. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/machines.html +0 -0
  754. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/machines.js +0 -0
  755. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/maintenance.css +0 -0
  756. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/maintenance.html +0 -0
  757. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/maintenance.js +0 -0
  758. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/masterdata.html +0 -0
  759. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/masterdata.js +0 -0
  760. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ops.css +0 -0
  761. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ops.html +0 -0
  762. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/ops.js +0 -0
  763. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/orders.css +0 -0
  764. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/orders.html +0 -0
  765. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/orders.js +0 -0
  766. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/quality.css +0 -0
  767. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/quality.html +0 -0
  768. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/quality.js +0 -0
  769. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/reasons.html +0 -0
  770. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/reasons.js +0 -0
  771. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/schedule.html +0 -0
  772. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/schedule.js +0 -0
  773. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/severities.html +0 -0
  774. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/severities.js +0 -0
  775. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/spc.css +0 -0
  776. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/spc.html +0 -0
  777. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/spc.js +0 -0
  778. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/station.css +0 -0
  779. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/station.html +0 -0
  780. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/station.js +0 -0
  781. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/styles.css +0 -0
  782. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/tags.html +0 -0
  783. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/tags.js +0 -0
  784. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/themes.css +0 -0
  785. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/themes.js +0 -0
  786. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/trace.html +0 -0
  787. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/trace.js +0 -0
  788. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/triggers.html +0 -0
  789. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/triggers.js +0 -0
  790. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/vendor/OrbitControls.js +0 -0
  791. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/vendor/README.md +0 -0
  792. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/vendor/three.core.min.js +0 -0
  793. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/src/fsmes/web/vendor/three.module.min.js +0 -0
  794. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/README.md +0 -0
  795. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/admin.toml +0 -0
  796. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/agent.toml +0 -0
  797. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/analyst.toml +0 -0
  798. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/operator.toml +0 -0
  799. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/assist_suite/supervisor.toml +0 -0
  800. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/conftest.py +0 -0
  801. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/line/bench.json +0 -0
  802. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/packs/bench/tag_map.json +0 -0
  803. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/recorded/bench-scorecard.json +0 -0
  804. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/Line.csv +0 -0
  805. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/Pack.csv +0 -0
  806. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/Press.csv +0 -0
  807. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/Trim.csv +0 -0
  808. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/Weld.csv +0 -0
  809. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/replay/bench/schema.ini +0 -0
  810. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-run/scores.json +0 -0
  811. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/fixtures/labelled-set.json +0 -0
  812. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/live_replies.py +0 -0
  813. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/page_anchors.py +0 -0
  814. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_block_on_the_state_timeline_carries_the_records_behind_it.py +0 -0
  815. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_characteristic_inspected_five_at_a_time.py +0 -0
  816. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_characteristic_the_plant_counts.py +0 -0
  817. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_chart_draws_only_what_the_api_measured.py +0 -0
  818. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_books_while_its_dashboard_is_read.py +0 -0
  819. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_from_the_package_writes_only_to_a_users_own_directory.py +0 -0
  820. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_logs_at_a_rate_a_year_can_stand.py +0 -0
  821. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_records_what_each_of_its_processes_is.py +0 -0
  822. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_shape_built_blind_from_an_unknown_sql_mes_is_the_bottling_line.py +0 -0
  823. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_plant_starts_and_stops_the_same_way_on_windows.py +0 -0
  824. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_point_on_the_control_chart_carries_the_records_behind_it.py +0 -0
  825. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_refusal_names_the_capability_and_who_holds_it.py +0 -0
  826. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_sample_on_the_control_chart_carries_the_five_bottles_behind_it.py +0 -0
  827. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_shift_of_stops_comes_out_in_the_plants_own_proportions.py +0 -0
  828. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_signature_they_hold_is_a_walk_and_not_a_refusal.py +0 -0
  829. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_a_walk_waits_for_a_control_the_page_is_still_drawing.py +0 -0
  830. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_adjustments.py +0 -0
  831. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_agent.py +0 -0
  832. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_agent_eval.py +0 -0
  833. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_ai_status.py +0 -0
  834. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_an_analysis_counts_people_before_it_names_one.py +0 -0
  835. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_an_exploration_draws_what_the_plant_measured.py +0 -0
  836. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_analysis.py +0 -0
  837. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_api.py +0 -0
  838. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_approval_review.py +0 -0
  839. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_assist_suite_scripted.py +0 -0
  840. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_assistant.py +0 -0
  841. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_auth.py +0 -0
  842. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_autoloop.py +0 -0
  843. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_backup.py +0 -0
  844. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_bottling_pack.py +0 -0
  845. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_capabilities.py +0 -0
  846. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_cli.py +0 -0
  847. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_clicking_a_block_on_the_state_timeline_opens_the_records_behind_it.py +0 -0
  848. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_clicking_a_lot_on_the_spc_chart_opens_which_defects.py +0 -0
  849. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_clicking_a_point_on_the_spc_chart_opens_the_records_behind_it.py +0 -0
  850. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_clicking_a_point_on_the_trend_graph_opens_the_records_behind_it.py +0 -0
  851. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_clicking_a_sample_on_the_spc_chart_opens_the_five_bottles.py +0 -0
  852. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_coa.py +0 -0
  853. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_config_audit.py +0 -0
  854. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_configuration_sections.py +0 -0
  855. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_core_oplock.py +0 -0
  856. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_core_purity.py +0 -0
  857. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_coverage_ledger.py +0 -0
  858. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_cutlery.py +0 -0
  859. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_demo_verdict.py +0 -0
  860. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_design.py +0 -0
  861. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_design_triage.py +0 -0
  862. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_doctor_writes_one_file_with_nothing_of_yours_in_it.py +0 -0
  863. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_documents.py +0 -0
  864. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_downtime_reasons.py +0 -0
  865. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_environments.py +0 -0
  866. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_equipment_oee.py +0 -0
  867. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erp_confirmation_files.py +0 -0
  868. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erp_conformance.py +0 -0
  869. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erp_contract.py +0 -0
  870. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erp_roundtrip.py +0 -0
  871. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erpnext.py +0 -0
  872. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_erpnext_live.py +0 -0
  873. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_browser_test_is_in_the_browser_tier.py +0 -0
  874. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_command_the_assistant_folder_tells_you_to_run_exists.py +0 -0
  875. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_settings_list_fits_in_one_tool_result.py +0 -0
  876. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_show_me_lands_on_the_real_control.py +0 -0
  877. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_write_route_has_a_tool_or_a_reason.py +0 -0
  878. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_every_write_tool_names_the_capability_its_route_demands.py +0 -0
  879. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_everything_the_model_said_in_one_turn_reaches_the_reply.py +0 -0
  880. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_execution.py +0 -0
  881. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_file_erp.py +0 -0
  882. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_fleet_console.py +0 -0
  883. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_fleet_plan.py +0 -0
  884. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_fsmes_runs_as_a_module_when_it_is_not_on_the_path.py +0 -0
  885. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_hierarchy.py +0 -0
  886. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_hold.py +0 -0
  887. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_inbound.py +0 -0
  888. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_inbound_folder.py +0 -0
  889. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_inbound_mqtt.py +0 -0
  890. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_inbound_sql.py +0 -0
  891. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_agent_eval_scoring.py +0 -0
  892. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_calibration.py +0 -0
  893. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_fail_safe.py +0 -0
  894. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_labelled_set.py +0 -0
  895. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_run_log_triage.py +0 -0
  896. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_jev_sdk_surface.py +0 -0
  897. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_kepsim.py +0 -0
  898. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_kernel_common.py +0 -0
  899. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_kpi_budget.py +0 -0
  900. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_connection.py +0 -0
  901. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_console.py +0 -0
  902. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_experiments.py +0 -0
  903. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_feedback.py +0 -0
  904. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_latency.py +0 -0
  905. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_order_book.py +0 -0
  906. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_orders.py +0 -0
  907. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_lab_scenarios.py +0 -0
  908. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_line_api.py +0 -0
  909. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_line_scoping.py +0 -0
  910. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_live_admin_settings.py +0 -0
  911. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_live_engineering_settings.py +0 -0
  912. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_live_plant_settings.py +0 -0
  913. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_maintenance.py +0 -0
  914. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_maintenance_work_goes_to_the_right_trade.py +0 -0
  915. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_mcp_product.py +0 -0
  916. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_megafactory.py +0 -0
  917. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_migrations_have_one_head.py +0 -0
  918. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_module_wall.py +0 -0
  919. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_nc_severities.py +0 -0
  920. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_no_tenant_literals.py +0 -0
  921. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_onboarding.py +0 -0
  922. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_opc_disconnection.py +0 -0
  923. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_outbox_events.py +0 -0
  924. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_overproduction.py +0 -0
  925. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_pack_format.py +0 -0
  926. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_pack_third.py +0 -0
  927. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_packaged_config.py +0 -0
  928. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_paging.py +0 -0
  929. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_performance_at_replay_speed.py +0 -0
  930. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_plant_identity.py +0 -0
  931. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_plant_migrate.py +0 -0
  932. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_plant_scale_lists.py +0 -0
  933. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_plant_scale_ui.py +0 -0
  934. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_plant_serve_only.py +0 -0
  935. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_promote_script.py +0 -0
  936. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_quality.py +0 -0
  937. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_quality_numbers.py +0 -0
  938. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_read_never_waits.py +0 -0
  939. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_rollup.py +0 -0
  940. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_route_coverage.py +0 -0
  941. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_routing_depth.py +0 -0
  942. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_run_ports.py +0 -0
  943. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_scale.py +0 -0
  944. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_scheduling_trace.py +0 -0
  945. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_schema_upgrade.py +0 -0
  946. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_serial_scale.py +0 -0
  947. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_shadow_mode.py +0 -0
  948. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_shadow_scorecard.py +0 -0
  949. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_shift_attribution.py +0 -0
  950. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_sim.py +0 -0
  951. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_spc_gauges.py +0 -0
  952. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_spc_moving_range.py +0 -0
  953. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_spc_signals.py +0 -0
  954. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_sqlite_write_locks.py +0 -0
  955. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_status_names_its_database.py +0 -0
  956. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_store.py +0 -0
  957. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_supply_chain_settings.py +0 -0
  958. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_sweep_replay.py +0 -0
  959. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_tag_fabric.py +0 -0
  960. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_tag_fabric_review.py +0 -0
  961. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_tags.py +0 -0
  962. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_tags_grouped_the_way_a_real_opc_server_groups_them.py +0 -0
  963. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_ai_screen_shows_a_conversation_and_gates_itself.py +0 -0
  964. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_ai_tab_explores_and_draws_what_it_read.py +0 -0
  965. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_ai_tab_says_what_the_assistant_costs_without_local_ai.py +0 -0
  966. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_analyses_answer_an_agent_the_way_they_answer_a_screen.py +0 -0
  967. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_analysis_agent_is_a_kind_of_its_own.py +0 -0
  968. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_analysis_agent_is_asked_for_the_next_questions.py +0 -0
  969. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_assistant_proposes_rather_than_asking.py +0 -0
  970. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_assistant_reads_before_it_says_no.py +0 -0
  971. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_bottling_shift_leaves_a_chain_a_person_can_walk_back.py +0 -0
  972. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_calendar_tool_names_every_kind_its_api_accepts.py +0 -0
  973. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_chart_comes_into_the_chat_and_stays_clickable.py +0 -0
  974. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_chat_can_open_the_dossier_behind_a_charted_point.py +0 -0
  975. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_control_chart_the_chat_reads_leaves_the_bottles_out.py +0 -0
  976. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_conversation_is_cached_and_not_only_the_catalogue.py +0 -0
  977. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_demo_path_says_what_is_wrong_and_what_to_type.py +0 -0
  978. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_dispatcher_at_three_hundred_people.py +0 -0
  979. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_docker_image_carries_the_packs.py +0 -0
  980. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_gauges_screen_shows_the_two_scales_and_when_each_was_calibrated.py +0 -0
  981. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_panel_can_ask_the_other_agent.py +0 -0
  982. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_panel_keeps_one_brain_through_a_failed_turn.py +0 -0
  983. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_plant_keeps_a_trace_of_what_its_ai_did.py +0 -0
  984. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_plant_stops_dropping_five_facts_it_already_had.py +0 -0
  985. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_screens_that_show_a_characteristic_inspected_five_at_a_time.py +0 -0
  986. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_simulated_crew_does_the_work_it_was_given.py +0 -0
  987. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_simulated_floor_plants_causes_an_engineer_can_find.py +0 -0
  988. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_skills_zip_holds_exactly_what_it_says_and_nothing_else.py +0 -0
  989. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_spc_chart_wears_the_accepted_chart_look.py +0 -0
  990. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_sql_server_query_set_is_not_sqlite_in_disguise.py +0 -0
  991. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_station_redraws_only_what_changed.py +0 -0
  992. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_station_says_when_no_order_is_open_on_the_plant.py +0 -0
  993. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_suite_knows_its_database.py +0 -0
  994. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_supervisor_writes_a_rule_as_a_sentence.py +0 -0
  995. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_supervisors_screen_reads_the_shift_and_writes_a_rule.py +0 -0
  996. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_trend_graph_walks_link_three_of_the_chain.py +0 -0
  997. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_wheel_ships_the_assistant_folder.py +0 -0
  998. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_the_wheel_ships_the_lab_packs.py +0 -0
  999. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_themes.py +0 -0
  1000. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_triage.py +0 -0
  1001. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_triggers.py +0 -0
  1002. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_two_plants_from_two_shapes_keep_each_plants_own_shape.py +0 -0
  1003. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_two_tags_on_one_axis_and_the_records_behind_a_point.py +0 -0
  1004. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_ui_check.py +0 -0
  1005. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_ui_lists_filter_at_scale.py +0 -0
  1006. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_ui_nav.py +0 -0
  1007. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_ui_oee_above_rated.py +0 -0
  1008. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_uns.py +0 -0
  1009. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_walkthroughs.py +0 -0
  1010. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_washer_story.py +0 -0
  1011. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_web.py +0 -0
  1012. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_what_a_maintenance_job_needs_of_the_line.py +0 -0
  1013. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_wip.py +0 -0
  1014. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/test_workorders.py +0 -0
  1015. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/ui/baselines/control-room.json +0 -0
  1016. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/ui/baselines/daylight.json +0 -0
  1017. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/ui/baselines/high-contrast.json +0 -0
  1018. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/ui/baselines/night-shift.json +0 -0
  1019. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/tests/unknown_mes.py +0 -0
  1020. {factorysemantics_mes-0.3.1 → factorysemantics_mes-0.4.0}/uv.lock +0 -0
@@ -0,0 +1,369 @@
1
+ #!/usr/bin/env python
2
+ """Two nodes of one plant on one box, started and stopped by the fleet.
3
+
4
+ Scott, 2026-10-15, about the release this is part of: *"must run on
5
+ windows."* Nobody on this project has a Windows machine, so this script is
6
+ how the two-node machinery is read on one: a pack that names its nodes, one
7
+ PostgreSQL, one machine layer, and the three fleet verbs a person types.
8
+
9
+ What it proves, in the order it does it:
10
+
11
+ 1. `fsmes pack check` accepts a pack that names two nodes.
12
+ 2. `fsmes fleet create` builds the plant once - two nodes are one plant and
13
+ one database - and records that this installation owns it.
14
+ 3. `fsmes fleet start` starts **both** nodes, each with its own node name,
15
+ its own port, its own pid file and its own log directory.
16
+ 4. Both nodes answer `/health`, each saying its own name.
17
+ 5. Every role - the reader, the floor, the housekeeping - is held by exactly
18
+ one of them, and `/health` on either node says the same thing about who
19
+ holds what, because the holders come from the database both nodes share.
20
+ 6. `fsmes fleet status` says two nodes answered and names what each holds.
21
+ 7. `fsmes fleet stop` stops both, and neither port answers afterwards.
22
+
23
+ What it does **not** prove is the kill: the takeover, the lease units and the
24
+ counters that must not be booked twice are proven by
25
+ `tests/test_a_plant_on_two_nodes_survives_one_of_them_dying.py` and by
26
+ `scripts/kill-a-node.sh`, both on Linux. `Popen.terminate()` on Windows does
27
+ not go through the supervisor's own shutdown, so a killed node there is a
28
+ different mechanism from a killed node here and deserves its own proof
29
+ rather than a claim made by this script.
30
+
31
+ It runs on either platform - it is proven on Linux before it is pushed, and
32
+ it is the Windows runner it exists for.
33
+
34
+ python .github/scripts/two_nodes_on_one_box.py \
35
+ --database-url postgresql+psycopg://user:pw@127.0.0.1:5432/two_nodes
36
+
37
+ Every path goes through `pathlib`, every child's output is read as UTF-8, and
38
+ nothing here uses a shell, a signal or a process group: the three things that
39
+ are not the same on both platforms.
40
+ """
41
+
42
+ from __future__ import annotations
43
+
44
+ import argparse
45
+ import json
46
+ import os
47
+ import re
48
+ import shutil
49
+ import subprocess
50
+ import sys
51
+ import tempfile
52
+ import time
53
+ import urllib.error
54
+ import urllib.request
55
+ from pathlib import Path
56
+
57
+ ROOT = Path(__file__).resolve().parents[2]
58
+ #: The variable the pack names for the thing that signs sessions. Both nodes
59
+ #: read the same one: a person signed in on one node is signed in on the
60
+ #: plant, and two of them would sign that person out every time the proxy
61
+ #: sent them to the other node.
62
+ #:
63
+ #: Its name says `signer` and not `secret` on purpose. The pack names the
64
+ #: variable and never the value, so this constant is a variable name and
65
+ #: nothing private - but code scanning reads a name with `secret` in it as a
66
+ #: credential, and a scanner that cries wolf on a CI script is a scanner
67
+ #: nobody reads on the day it is right (`py/clear-text-storage-sensitive-data`,
68
+ #: PR #178).
69
+ SIGNING_VARIABLE = "FSMES_TWO_NODE_SIGNER"
70
+ #: Short enough that a role is claimed while this script is watching, long
71
+ #: enough that a busy runner does not drop a renewal. Every wait below is a
72
+ #: multiple of it, never a number of seconds chosen for its own sake.
73
+ LEASE_SECONDS = 6.0
74
+ ROLES = ("reader", "floor", "housekeeping")
75
+ #: This interpreter's own `fsmes`. Not the console script: on Windows that
76
+ #: lives in a `Scripts` directory that is on PATH only if the installer put
77
+ #: it there, and `python -m fsmes` is the same program either way.
78
+ MES = [sys.executable, "-m", "fsmes"]
79
+
80
+
81
+ def say(line: str = "") -> None:
82
+ print(line, flush=True)
83
+
84
+
85
+ def fail(why: str) -> None:
86
+ say("")
87
+ say(f"NOT PROVEN: {why}")
88
+ raise SystemExit(1)
89
+
90
+
91
+ # ------------------------------------------------------------------ the pack
92
+
93
+ def pack_with_two_nodes(where: Path, *, database_url: str, port_a: int, port_b: int,
94
+ opc_endpoint: str) -> Path:
95
+ """The lab's bottling pack with its nodes named, and nothing else changed.
96
+
97
+ Patched in the four places that make it this script's: where the machine
98
+ layer is, where the database is, that it runs on two nodes, and the name
99
+ of the variable its signing key lives in. The replay data is the
100
+ reference hour beside it, which generates in a moment.
101
+ """
102
+ pack = where / "bottling"
103
+ shutil.copytree(ROOT / "labs" / "multiplant" / "bottling", pack)
104
+ shutil.copy(ROOT / "labs" / "kepsim" / "line.json", pack / "line.json")
105
+
106
+ toml = (pack / "plant.toml").read_text(encoding="utf-8")
107
+ toml = toml.replace('opc_endpoint = "opc.tcp://127.0.0.1:4841/fsmes/bottling"',
108
+ f'opc_endpoint = "{opc_endpoint}"')
109
+ toml = toml.replace("api_port = 8010", f"api_port = {port_a}")
110
+ toml = toml.replace("simulate = true",
111
+ f'simulate = true\nsecret_key_env = "{SIGNING_VARIABLE}"\n\n'
112
+ f'[[serve.nodes]]\nid = "a"\napi_port = {port_a}\n\n'
113
+ f'[[serve.nodes]]\nid = "b"\napi_port = {port_b}\n')
114
+ # A pack a person writes names `database_password_file` and keeps the
115
+ # password out of the file that says what the plant is. This one splices
116
+ # the whole URL because that is what it was given, into a directory that
117
+ # is deleted at the end.
118
+ toml += (f'\n[storage]\ndatabase_url = "{database_url}"\n'
119
+ f'\n[redundancy]\nenabled = true\nlease_seconds = {LEASE_SECONDS}\n')
120
+ (pack / "plant.toml").write_text(toml, encoding="utf-8")
121
+ return pack
122
+
123
+
124
+ # --------------------------------------------------------------- the asking
125
+
126
+ def get(url: str, timeout: float = 4.0) -> tuple[int, str]:
127
+ try:
128
+ with urllib.request.urlopen(url, timeout=timeout) as answer:
129
+ return answer.status, answer.read().decode("utf-8", "replace")
130
+ except urllib.error.HTTPError as refused:
131
+ return refused.code, ""
132
+ except Exception:
133
+ return 0, ""
134
+
135
+
136
+ def health(port: int) -> dict:
137
+ status, body = get(f"http://127.0.0.1:{port}/health")
138
+ if status != 200 or not body:
139
+ return {}
140
+ try:
141
+ return json.loads(body)
142
+ except ValueError:
143
+ return {}
144
+
145
+
146
+ def answers(port: int, timeout: float) -> dict:
147
+ """Wait for one node's dashboard to answer, and say what it said."""
148
+ until = time.monotonic() + timeout
149
+ while time.monotonic() < until:
150
+ body = health(port)
151
+ if body:
152
+ return body
153
+ time.sleep(0.5)
154
+ return {}
155
+
156
+
157
+ def holders(body: dict) -> dict:
158
+ """role -> the node holding it, as `/health` reports it."""
159
+ node = body.get("node") or {}
160
+ return {role: (node.get("holders") or {}).get(role) for role in ROLES}
161
+
162
+
163
+ def wait_for_every_role(port: int, timeout: float) -> dict:
164
+ """Wait until every role has a holder, and say who holds what.
165
+
166
+ Each role is a race of its own - the reader, the floor and the
167
+ housekeeping are claimed by three different processes - so this waits for
168
+ all three to be claimed rather than for one node to claim all three.
169
+ """
170
+ until = time.monotonic() + timeout
171
+ held: dict = {}
172
+ while time.monotonic() < until:
173
+ held = holders(health(port))
174
+ if all(held.get(role) for role in ROLES):
175
+ return held
176
+ time.sleep(0.5)
177
+ return held
178
+
179
+
180
+ # ------------------------------------------------------------- the commands
181
+
182
+ def fsmes(*args: str, env: dict, where: Path | None = None, timeout: float = 600.0):
183
+ """One `fsmes` command, its output read as UTF-8 and printed."""
184
+ done = subprocess.run([*MES, *args], cwd=where or ROOT, env=env, capture_output=True,
185
+ text=True, encoding="utf-8", errors="replace", timeout=timeout)
186
+ for line in (done.stdout or "").splitlines():
187
+ say(f" | {line}")
188
+ if done.returncode != 0:
189
+ for line in (done.stderr or "").splitlines():
190
+ say(f" ! {line}")
191
+ return done
192
+
193
+
194
+ def main() -> int:
195
+ parser = argparse.ArgumentParser(description=__doc__)
196
+ parser.add_argument("--database-url", required=True,
197
+ help="a PostgreSQL both nodes share; the database must exist")
198
+ parser.add_argument("--port-a", type=int, default=8010)
199
+ parser.add_argument("--port-b", type=int, default=8011)
200
+ parser.add_argument("--opc-port", type=int, default=4841)
201
+ parser.add_argument("--speed", type=float, default=60.0,
202
+ help="line seconds per wall second for the replay")
203
+ parser.add_argument("--workdir", default="",
204
+ help="where the pack, the data and the logs go (default: a temp dir)")
205
+ parser.add_argument("--keep-running", action="store_true",
206
+ help="leave both nodes up at the end, for a person to look at")
207
+ args = parser.parse_args()
208
+
209
+ if "postgresql" not in args.database_url:
210
+ fail("two nodes share one database, which a file database cannot be: "
211
+ "--database-url must be a PostgreSQL URL")
212
+
213
+ where = Path(args.workdir).resolve() if args.workdir else Path(tempfile.mkdtemp(
214
+ prefix="fsmes-two-nodes-"))
215
+ where.mkdir(parents=True, exist_ok=True)
216
+ root = where / "run"
217
+ root.mkdir(parents=True, exist_ok=True)
218
+ logs = where / "logs"
219
+ logs.mkdir(parents=True, exist_ok=True)
220
+ endpoint = f"opc.tcp://127.0.0.1:{args.opc_port}/fsmes/bottling-two-nodes"
221
+
222
+ env = dict(os.environ)
223
+ env[SIGNING_VARIABLE] = "the-same-signer-on-both-nodes"
224
+ env["PYTHONIOENCODING"] = "utf-8"
225
+
226
+ say(f"Two nodes of one plant on {sys.platform}, in {where}")
227
+ pack = pack_with_two_nodes(where, database_url=args.database_url, port_a=args.port_a,
228
+ port_b=args.port_b, opc_endpoint=endpoint)
229
+ say(" the line data the replay plays")
230
+ if fsmes("sim-generate", str(pack / "line.json"), "--out", str(pack / "out"),
231
+ env=env).returncode != 0:
232
+ fail("the line data would not generate")
233
+
234
+ say(" fsmes pack check, on a pack that names two nodes")
235
+ if fsmes("pack", "check", str(pack), env=env).returncode != 0:
236
+ fail("the checker refused a pack naming two nodes")
237
+
238
+ replay = None
239
+ started_nodes = False
240
+ replay_log = logs / "replay.log"
241
+ try:
242
+ say(" the machine layer: one OPC replay for the whole plant")
243
+ sim_env = dict(env)
244
+ sim_env.update(MES_PLANT_NAME="bottling", MES_OPC_ENDPOINT=endpoint,
245
+ MES_REPLAY_DIR=str(pack / "out"),
246
+ MES_TAG_MAP_FILE=str(pack / "tag_map.json"),
247
+ MES_SIM_SPEED=str(args.speed), MES_LOG_DIR=str(logs))
248
+ with replay_log.open("ab") as sink:
249
+ replay = subprocess.Popen([*MES, "run-opc-sim", "--replay"], cwd=ROOT, env=sim_env,
250
+ stdout=sink, stderr=subprocess.STDOUT)
251
+ until = time.monotonic() + 90
252
+ while time.monotonic() < until:
253
+ if "replay online" in replay_log.read_text(encoding="utf-8", errors="replace"):
254
+ break
255
+ if replay.poll() is not None:
256
+ fail(f"the machine layer exited ({replay.returncode}); see {replay_log}")
257
+ time.sleep(0.25)
258
+ else:
259
+ fail(f"the machine layer never came online; see {replay_log}")
260
+ say(" | replay online")
261
+
262
+ say(" fsmes fleet create, once, for one plant on two nodes")
263
+ if fsmes("fleet", "create", str(pack), "--root", str(root), env=env).returncode != 0:
264
+ fail("the plant would not build from a pack naming two nodes")
265
+
266
+ say(" fsmes fleet start, which starts every node the pack names")
267
+ started = fsmes("fleet", "start", "bottling", "--root", str(root),
268
+ "--speed", str(args.speed), env=env)
269
+ started_nodes = True
270
+ if started.returncode != 0:
271
+ fail("fleet start refused a plant with two nodes")
272
+ for node in ("a", "b"):
273
+ if f"node {node}" not in started.stdout:
274
+ fail(f"fleet start said nothing about node {node}:\n{started.stdout}")
275
+
276
+ say(" both nodes answer /health, each with its own name")
277
+ seen = {}
278
+ for node, port in (("a", args.port_a), ("b", args.port_b)):
279
+ body = answers(port, timeout=180)
280
+ if not body:
281
+ fail(f"node {node} never answered on port {port}")
282
+ said = (body.get("node") or {}).get("name")
283
+ if said != node:
284
+ fail(f"the node on port {port} calls itself {said!r}, not {node!r}")
285
+ seen[node] = body
286
+ say(f" | node {node} answered on {port}, redundancy "
287
+ f"{(body.get('node') or {}).get('redundancy')}")
288
+
289
+ say(" every role is held by exactly one node, and both nodes agree")
290
+ held = wait_for_every_role(args.port_a, timeout=LEASE_SECONDS * 20)
291
+ missing = [role for role in ROLES if not held.get(role)]
292
+ if missing:
293
+ fail(f"nobody held {', '.join(missing)} within 20 leases; "
294
+ f"what was held: {held}")
295
+ for role, holder in held.items():
296
+ if holder not in ("a", "b"):
297
+ fail(f"{role} is held by {holder!r}, which is neither node")
298
+ say(f" | {role} is held by node {holder}")
299
+ from_b = holders(health(args.port_b))
300
+ if from_b != held:
301
+ fail(f"the nodes disagree about who holds what: a says {held}, b says {from_b}")
302
+ say(" | node b says the same, because the holders are in the database")
303
+
304
+ say(" fsmes fleet status names both nodes and what they hold")
305
+ status = fsmes("fleet", "status", "bottling", "--root", str(root), env=env)
306
+ if status.returncode != 0:
307
+ fail("fleet status refused a plant with two nodes")
308
+ if not re.search(r"nodes\s+2, 2 answered", status.stdout):
309
+ fail(f"fleet status did not say two nodes answered:\n{status.stdout}")
310
+ for node in ("a", "b"):
311
+ if not re.search(rf"^\s+{node}\s+\S+.*holding ", status.stdout, re.MULTILINE):
312
+ fail(f"fleet status said nothing about node {node}:\n{status.stdout}")
313
+
314
+ say(" fsmes fleet stop stops both")
315
+ if args.keep_running:
316
+ say(f" | --keep-running: both nodes are up on {args.port_a} and "
317
+ f"{args.port_b}, the machine layer is still playing on "
318
+ f"{endpoint} (pid {replay.pid}), and {root} is theirs. Stop "
319
+ f"them with `fsmes fleet stop bottling --root {root}`, and "
320
+ f"the machine layer by its pid.")
321
+ return 0
322
+ stopped = fsmes("fleet", "stop", "bottling", "--root", str(root), env=env)
323
+ if stopped.returncode != 0:
324
+ fail("fleet stop refused a plant with two nodes")
325
+ started_nodes = False
326
+ for node, port in (("a", args.port_a), ("b", args.port_b)):
327
+ if f"node {node}" not in stopped.stdout:
328
+ fail(f"fleet stop said nothing about node {node}:\n{stopped.stdout}")
329
+ until = time.monotonic() + 60
330
+ while time.monotonic() < until and health(port):
331
+ time.sleep(0.5)
332
+ if health(port):
333
+ fail(f"node {node} was still answering on {port} after fleet stop")
334
+ say(f" | node {node} is gone from {port}")
335
+
336
+ say("")
337
+ say("PROVEN on this box: a pack that names two nodes is checked, built once, "
338
+ "started as two nodes that each answer for themselves, has every role held "
339
+ "by exactly one of them, and is stopped by one command. The kill is proven "
340
+ "on Linux and is not claimed here.")
341
+ return 0
342
+ finally:
343
+ # A failure before the stop step leaves two nodes answering, which on
344
+ # a runner is a job that never ends and on a person's box is two
345
+ # plants they did not ask for. `--keep-running` is the one case where
346
+ # they are meant to stay up.
347
+ if started_nodes and not args.keep_running:
348
+ fsmes("fleet", "stop", "bottling", "--root", str(root), env=env, timeout=120)
349
+ if replay is not None and replay.poll() is None and not args.keep_running:
350
+ # `--keep-running` keeps the machine layer too: two nodes with
351
+ # nothing to read are a plant whose machines all say
352
+ # *disconnected*, which is not what the person asked to look at.
353
+ replay.terminate()
354
+ try:
355
+ replay.wait(timeout=30)
356
+ except subprocess.TimeoutExpired:
357
+ replay.kill()
358
+ for log in sorted(logs.rglob("*.log")) + sorted((root / "logs").rglob("*.jsonl")):
359
+ say("")
360
+ say(f"--- the last 40 lines of {log}")
361
+ try:
362
+ for line in log.read_text(encoding="utf-8", errors="replace").splitlines()[-40:]:
363
+ say(f" {line}")
364
+ except OSError as unreadable:
365
+ say(f" (unreadable: {unreadable})")
366
+
367
+
368
+ if __name__ == "__main__":
369
+ raise SystemExit(main())
@@ -493,6 +493,128 @@ jobs:
493
493
  esac
494
494
  done
495
495
 
496
+ two-nodes-in-compose:
497
+ # The two-box demo, killed on purpose, on every pull request.
498
+ #
499
+ # `docker/docker-compose.redundant.yml` is one PostgreSQL, one machine
500
+ # layer, two nodes of the bottling plant and nginx in front of them, and
501
+ # `scripts/kill-a-node.sh` kills one node and checks the other carried
502
+ # on: the reader lease moved within three leases, the counters kept
503
+ # moving, every machine booked exactly what it counted, no reading was
504
+ # stored twice, and the one address kept answering. It is the same claim
505
+ # `postgres`'s two-node test makes, made through containers and a proxy
506
+ # instead of two processes - which is what anybody who tries this product
507
+ # will actually run.
508
+ #
509
+ # Linux only. `docker compose` on the Windows runner has no Linux daemon
510
+ # to run these images on, and a plant engineer's Windows box is covered by
511
+ # `half-dead-plant` and `two-nodes-on-windows` instead.
512
+ #
513
+ # Behind `image`: there is nothing to learn from a compose demo of an
514
+ # image that does not build, and the layer cache that job wrote makes the
515
+ # build here a cache hit rather than a second four-minute pip install.
516
+ # The timing this job asserts is in lease units measured against the
517
+ # database's own clock, never in seconds on a shared runner.
518
+ needs: image
519
+ runs-on: ubuntu-latest
520
+ timeout-minutes: 25
521
+ steps:
522
+ - uses: actions/checkout@v7
523
+ - uses: docker/setup-buildx-action@v4
524
+ - name: Build the image the compose file names
525
+ uses: docker/build-push-action@v7
526
+ with:
527
+ context: .
528
+ file: docker/Dockerfile
529
+ platforms: linux/amd64
530
+ push: false
531
+ load: true
532
+ tags: factorysemantics-mes:two-nodes
533
+ # Read-only: `image` owns this scope, and two jobs writing one
534
+ # scope evict each other's layers.
535
+ cache-from: type=gha,scope=ci-image
536
+
537
+ - name: Kill one of two nodes and check the plant carried on
538
+ run: bash scripts/kill-a-node.sh
539
+
540
+ - name: What the containers said
541
+ # Always, pass or fail: a failover nobody can read the logs of is a
542
+ # green check or a red one and nothing else.
543
+ if: always()
544
+ run: |
545
+ docker compose -f docker/docker-compose.redundant.yml ps -a || true
546
+ docker compose -f docker/docker-compose.redundant.yml logs --no-color --tail 200 || true
547
+
548
+ - name: Put it away
549
+ if: always()
550
+ run: docker compose -f docker/docker-compose.redundant.yml down -v || true
551
+
552
+ two-nodes-on-windows:
553
+ # Scott, about this release: "must run on windows." Nobody on this
554
+ # project has a Windows machine, so this job is where the two-node
555
+ # machinery is read on one.
556
+ #
557
+ # It names its nodes in the pack, builds the plant once, starts it with
558
+ # `fsmes fleet start`, and checks that both nodes answer `/health` under
559
+ # their own names, that each of the three roles is held by exactly one of
560
+ # them, that `fleet status` names both, and that `fleet stop` stops both.
561
+ # The PostgreSQL is the one the runner image ships - installed and
562
+ # stopped, so the job starts it.
563
+ #
564
+ # What this job does NOT do is kill a node. `Popen.terminate()` on
565
+ # Windows does not go through the plant's own shutdown handler, so a
566
+ # killed node there is a different mechanism from a killed node on Linux
567
+ # and deserves a proof of its own rather than a claim made here. The
568
+ # lease, the takeover in lease units and the counters that must not be
569
+ # booked twice are proven by the `postgres` job and by
570
+ # `two-nodes-in-compose`, both Linux.
571
+ #
572
+ # Windows only: the Linux half of the same claim is the `postgres` job,
573
+ # which runs the whole two-node failover test, and running this script
574
+ # there as well would buy the weaker half of a stronger proof.
575
+ runs-on: windows-latest
576
+ timeout-minutes: 40
577
+ steps:
578
+ - uses: actions/checkout@v7
579
+ - uses: actions/setup-python@v7
580
+ with:
581
+ python-version: "3.12"
582
+
583
+ - name: Start the PostgreSQL this runner ships
584
+ shell: pwsh
585
+ run: |
586
+ $service = Get-Service -Name "postgresql*" | Select-Object -First 1
587
+ if (-not $service) { throw "this runner image has no PostgreSQL service" }
588
+ Write-Host "service $($service.Name) is $($service.Status)"
589
+ Set-Service -Name $service.Name -StartupType Manual
590
+ Start-Service -Name $service.Name
591
+ $env:PGPASSWORD = "root"
592
+ $ready = $false
593
+ foreach ($try in 1..30) {
594
+ & "$env:PGBIN\pg_isready.exe" -h 127.0.0.1 -p 5432 -U postgres
595
+ if ($LASTEXITCODE -eq 0) { $ready = $true; break }
596
+ Start-Sleep -Seconds 2
597
+ }
598
+ if (-not $ready) { throw "PostgreSQL never accepted a connection" }
599
+ & "$env:PGBIN\createdb.exe" -h 127.0.0.1 -p 5432 -U postgres two_nodes
600
+ if ($LASTEXITCODE -ne 0) { throw "could not create the database" }
601
+
602
+ - name: Install
603
+ run: python -m pip install --upgrade pip && python -m pip install -e ".[postgres]"
604
+
605
+ - name: Two nodes of one plant, started and stopped by the fleet
606
+ shell: bash
607
+ env:
608
+ # The runner image's own password for its own PostgreSQL. It is in
609
+ # the image's documentation, it is reachable from this job and from
610
+ # nothing else, and the database it opens is deleted with the
611
+ # runner.
612
+ PGPASSWORD: root
613
+ run: |
614
+ python .github/scripts/two_nodes_on_one_box.py \
615
+ --database-url "postgresql+psycopg://postgres:root@127.0.0.1:5432/two_nodes" \
616
+ --speed 60
617
+
496
618
  lab:
497
619
  # The lab's starter experiments, on a runner.
498
620
  #
@@ -12,6 +12,163 @@ goes under Honesty with a migration line, so plant people can find it.
12
12
 
13
13
  Nothing yet.
14
14
 
15
+ ## [0.4.0] — 2026-10-16
16
+
17
+ ### Added
18
+
19
+ - **A plant can run on two boxes and keep counting when one of them dies.**
20
+ Two or more **nodes** of one plant against one PostgreSQL, with the pack
21
+ saying so:
22
+
23
+ ```toml
24
+ [redundancy]
25
+ enabled = true
26
+ lease_seconds = 10
27
+ ```
28
+
29
+ Three jobs that must run once — reading the machines, the simulated floor,
30
+ and pruning the history — are held one at a time by a row in a new
31
+ `plant_leases` table, claimed and renewed against the **database's** clock
32
+ and never the box's. A holder that cannot renew stops at once and comes
33
+ back as a standby; the other node has the job within a lease or two. The
34
+ dashboard on the surviving node keeps answering, a person signed in on one
35
+ node is signed in on the other (the pack names the variable holding the
36
+ signing key, `secret_key_env`, and a plant with `[redundancy]` on refuses
37
+ to start without it), and production is booked **exactly once** — the
38
+ counters are absolute, and a new `counter_baselines` table carries each
39
+ one's baseline in the same transaction as the booking it belongs to, so a
40
+ node taking over continues the count rather than starting it again.
41
+ `fsmes plant <name> run --node <id> --api-port <port>` names a node and
42
+ moves it off the plant's own port; `/health` grows a `node` block saying
43
+ which node answered, how long its lease is, what it holds and who holds
44
+ the rest; `fsmes plant <name> status` says the same as a line. PostgreSQL
45
+ only: `[redundancy]` with a SQLite URL refuses in one sentence, and the
46
+ single-box SQLite demo is untouched. Measured in lease units on one
47
+ machine, not in seconds. What it does **not** do is in
48
+ [one plant on two boxes](docs/operate/redundancy.md) and decision 0042:
49
+ the front door is yours (two nodes are two addresses), the database's own
50
+ standby is PostgreSQL's job, the PLC write path stays single, ERP sync and
51
+ the UNS publisher are still one copy each, and a conversation on the AI tab
52
+ starts over after a failover. (#177)
53
+
54
+ - **The two-box demo, and the kill test anyone can run.**
55
+ `docker compose -f docker/docker-compose.redundant.yml up` brings up one
56
+ PostgreSQL, the simulated machines, two nodes of one plant and nginx in
57
+ front of both on one address; `bash scripts/kill-a-node.sh` brings it up,
58
+ waits for the counts to move, kills a node outright, watches the one
59
+ address until the other node holds the reader, and prints the takeover in
60
+ lease units with a check that nothing was booked twice and nothing was
61
+ lost. A CI job (`two-nodes-in-compose`) runs that same script on every
62
+ pull request. On this product's own box on 2026-10-16 the reader was on the
63
+ second node after 1.13 leases of 6 s, 0 of the requests asked during the
64
+ failover were refused, all 6 machines booked exactly what their counters
65
+ moved, and 0 readings were booked twice. (#178)
66
+
67
+ - **The screens say which box holds what.** The line beside the plant's name
68
+ on the dashboard — *served by b · machines read by a* — used to be written
69
+ once when the page loaded, which left it naming a dead node until somebody
70
+ reloaded; it now follows a takeover on the page's own poll, within five
71
+ seconds and with no reload, and only on a plant that says it runs on more
72
+ than one node (a single-node plant starts no timer and makes no request it
73
+ did not make before). The [fleet console](docs/operate/fleet.md) shows such
74
+ a plant once with its nodes under it — how many there are and how many
75
+ answered, then one line each saying where that node is and what it holds in
76
+ words — and `fsmes fleet status`, `fsmes fleet list` and `/fleet.json`
77
+ carry the same. A node that did not answer is **unknown** there, never a
78
+ node holding nothing. (#178)
79
+
80
+ - **A pack may name the nodes that run on one box**, which is the cheap way
81
+ to see all of this before you own the second box:
82
+
83
+ ```toml
84
+ [[serve.nodes]]
85
+ id = "a"
86
+ api_port = 8010
87
+ ```
88
+
89
+ `fsmes fleet start`, `stop`, `status`, `list` and `apply` then act on every
90
+ node the pack names, each with its own pid file and its own log directory,
91
+ and `fsmes pack check` refuses the four ways a node list half-starts a
92
+ plant (two nodes sharing a port or a name, nodes named with `[redundancy]`
93
+ off, no signing key between them). A pack that names no nodes is the
94
+ ordinary plant on one address and behaves exactly as it did. (#178)
95
+
96
+ - **`fsmes fleet start` starts the machines a two-node simulated plant
97
+ shares, and `fleet stop` stops them.** A simulated plant on one node starts
98
+ its own OPC replay; a pack that named nodes deliberately did not, because a
99
+ replay started inside a node dies with that node and the surviving reader
100
+ then sees the line start over — which reads as a PLC reset and books
101
+ nothing. Nobody started it instead: after the four commands in
102
+ [one plant on two boxes](docs/operate/redundancy.md) the console said
103
+ *6 of 6 disconnected* and nothing was booked. The plant now starts it once,
104
+ before either node, with a log directory of its own; it is left playing
105
+ when it is already playing, both when this installation's own pid file
106
+ names it and when anything else already answers on the endpoint the pack
107
+ names, so a replay you started by hand — or the one `docker compose` owns —
108
+ is never stopped by `fsmes fleet stop`. A plant whose pack says
109
+ `simulate = false` starts nothing here: its machine layer is a PLC somebody
110
+ else runs.
111
+
112
+ - **`fsmes fleet stop <plant> --node <id>`** stops one node of a plant and
113
+ leaves the others and the shared machines running, for taking one box down
114
+ on purpose. It is a graceful stop — the node is asked, then told, and it
115
+ lets go of its leases on the way out — so it is not the proof that a plant
116
+ survives a box dying: that proof is a `kill`, and the docs say which is
117
+ which. A node the pack does not name is refused by name, with the nodes it
118
+ does have.
119
+
120
+ ### Fixed
121
+
122
+ - **A plant whose first node died could not be stopped.** `fsmes fleet stop`
123
+ asked one address — the one in the ownership record — and counted a pid
124
+ file a plant with nodes never writes, so a plant running happily on its
125
+ second node refused to stop at all: *nothing in its pid file is alive, so
126
+ there may be nothing left to stop*, with three live processes. `stop`,
127
+ `apply` and `start` now ask every node the pack names, and a refusal counts
128
+ every node's pid file and says how many it read. (#178)
129
+
130
+ - **The console's row for a plant running on its second node was `unknown`
131
+ in every column** — no label, no schema, no machines, no orders — because
132
+ the row was filled from the address in the pack, which was the node that
133
+ had died. A plant with nodes is now read at whichever node answers, and the
134
+ silent node is still named as silent on its own line underneath. The node
135
+ that answered is asked the same ownership question as the first address, so
136
+ a port answering as something else is refused rather than believed. (#178)
137
+
138
+ - **`fsmes fleet apply` to a book with nothing in it leaves accounts in it.**
139
+ Pointing an existing pack at a new PostgreSQL ran the migrations and seeded
140
+ the plant's master data and stopped there: every sign-in answered *invalid
141
+ credentials*, and on a simulated plant both floor processes died saying
142
+ *could not sign in* with nothing saying why. `apply` now makes the accounts
143
+ `fsmes fleet create` makes, in the one case where it cannot be taking
144
+ anybody's decision away — a book with no account in it at all — and says on
145
+ a line of its own that it did. A plant that has accounts is left alone:
146
+ `apply` is not the command that brings back one you deleted. And the
147
+ floor's own line now names the likeliest cause, which is either a plant
148
+ that answered and refused the credentials or a plant that never answered
149
+ at all.
150
+
151
+ ### Honesty
152
+
153
+ - **A restart no longer re-books what was already booked, on one box or
154
+ two.** Production is counted from absolute machine counters, and until now
155
+ the baseline each counter was measured from lived in the reader's memory:
156
+ a reader that restarted treated the counter's whole value as new
157
+ production. One migration, `b6f0c2a71d58`, adds `plant_leases` and
158
+ `counter_baselines`; nothing to do on a single-box plant, where the two
159
+ tables sit unused until `[redundancy]` is turned on.
160
+
161
+ - **Windows: what is and is not proven.** A CI job
162
+ (`two-nodes-on-windows`) builds a two-node pack, checks it, creates it,
163
+ starts it and stops it, and holds that both nodes answer under their own
164
+ names and that each of the three roles is held by exactly one of them. The
165
+ **kill is not proven on Windows**: `Popen.terminate()` there does not go
166
+ through the plant's own shutdown handler, so a node killed that way stops
167
+ by a different mechanism than a node whose power is cut, and the takeover
168
+ that follows is a different thing to measure. The lease, the takeover in
169
+ lease units and the counts that must not be booked twice are proven on
170
+ Linux only.
171
+
15
172
  ## [0.3.1] — 2026-10-15
16
173
 
17
174
  ### Added
@@ -4907,7 +5064,8 @@ number in it comes from a simulated plant.
4907
5064
  MES was not watching. Unlabelled downtime is reported as unlabelled. These
4908
5065
  are the house rules and they are tested.
4909
5066
 
4910
- [Unreleased]: https://github.com/factorysemantics/factorysemantics-mes/compare/v0.3.1...HEAD
5067
+ [Unreleased]: https://github.com/factorysemantics/factorysemantics-mes/compare/v0.4.0...HEAD
5068
+ [0.4.0]: https://github.com/factorysemantics/factorysemantics-mes/releases/tag/v0.4.0
4911
5069
  [0.3.1]: https://github.com/factorysemantics/factorysemantics-mes/releases/tag/v0.3.1
4912
5070
  [0.3.0]: https://github.com/factorysemantics/factorysemantics-mes/releases/tag/v0.3.0
4913
5071
  [0.2.0]: https://github.com/factorysemantics/factorysemantics-mes/releases/tag/v0.2.0