sollertia-forgery 1.0.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 (144) hide show
  1. sollertia_forgery-1.0.0/.gitignore +218 -0
  2. sollertia_forgery-1.0.0/.netlify-site +1 -0
  3. sollertia_forgery-1.0.0/CLAUDE.md +267 -0
  4. sollertia_forgery-1.0.0/LICENSE +191 -0
  5. sollertia_forgery-1.0.0/PKG-INFO +881 -0
  6. sollertia_forgery-1.0.0/README.md +837 -0
  7. sollertia_forgery-1.0.0/docs/Makefile +19 -0
  8. sollertia_forgery-1.0.0/docs/make.bat +35 -0
  9. sollertia_forgery-1.0.0/docs/source/api.rst +174 -0
  10. sollertia_forgery-1.0.0/docs/source/conf.py +45 -0
  11. sollertia_forgery-1.0.0/docs/source/index.rst +19 -0
  12. sollertia_forgery-1.0.0/docs/source/welcome.rst +21 -0
  13. sollertia_forgery-1.0.0/envs/slf_dev_lin.yml +229 -0
  14. sollertia_forgery-1.0.0/envs/slf_dev_osx.yml +202 -0
  15. sollertia_forgery-1.0.0/envs/slf_dev_win.yml +223 -0
  16. sollertia_forgery-1.0.0/pyproject.toml +343 -0
  17. sollertia_forgery-1.0.0/src/sollertia_forgery/__init__.py +46 -0
  18. sollertia_forgery-1.0.0/src/sollertia_forgery/forging/__init__.py +37 -0
  19. sollertia_forgery-1.0.0/src/sollertia_forgery/forging/admission.py +91 -0
  20. sollertia_forgery-1.0.0/src/sollertia_forgery/forging/dataset.py +492 -0
  21. sollertia_forgery-1.0.0/src/sollertia_forgery/forging/pipeline.py +1122 -0
  22. sollertia_forgery-1.0.0/src/sollertia_forgery/forging/state.py +188 -0
  23. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/__init__.py +5 -0
  24. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/entry_points.py +144 -0
  25. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/forge.py +125 -0
  26. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/forging_tools.py +494 -0
  27. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/host_resolution.py +105 -0
  28. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/manage.py +313 -0
  29. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/management_tools.py +402 -0
  30. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/mcp_instance.py +8 -0
  31. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/mcp_server.py +38 -0
  32. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/orchestration_tools.py +376 -0
  33. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/plan.py +109 -0
  34. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/planning_tools.py +386 -0
  35. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/process.py +269 -0
  36. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/processing_tools.py +1355 -0
  37. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/remote_tools.py +1121 -0
  38. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/responses.py +263 -0
  39. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/server.py +772 -0
  40. sollertia_forgery-1.0.0/src/sollertia_forgery/interfaces/server_tools.py +787 -0
  41. sollertia_forgery-1.0.0/src/sollertia_forgery/managing/__init__.py +31 -0
  42. sollertia_forgery-1.0.0/src/sollertia_forgery/managing/checksum.py +206 -0
  43. sollertia_forgery-1.0.0/src/sollertia_forgery/managing/jobs.py +79 -0
  44. sollertia_forgery-1.0.0/src/sollertia_forgery/managing/manifest.py +715 -0
  45. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/__init__.py +52 -0
  46. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/assembly_sources.py +144 -0
  47. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/behavior_dataset.py +322 -0
  48. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/experiment_dataset.py +147 -0
  49. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/forging.py +96 -0
  50. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/metadata.py +403 -0
  51. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/microcontrollers.py +844 -0
  52. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/runtime.py +631 -0
  53. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/runtime_dataset.py +275 -0
  54. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/training_dataset.py +150 -0
  55. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/two_photon.py +387 -0
  56. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/two_photon_dataset.py +629 -0
  57. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/video_dataset.py +361 -0
  58. sollertia_forgery-1.0.0/src/sollertia_forgery/mesoscope_vr/video_tracking.py +533 -0
  59. sollertia_forgery-1.0.0/src/sollertia_forgery/microcontrollers/__init__.py +18 -0
  60. sollertia_forgery-1.0.0/src/sollertia_forgery/microcontrollers/pipeline.py +888 -0
  61. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/__init__.py +174 -0
  62. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/batches.py +283 -0
  63. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/closure.py +348 -0
  64. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/dispatch.py +820 -0
  65. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/footprints.py +1996 -0
  66. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/graph.py +511 -0
  67. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/hosts.py +857 -0
  68. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/ledger.py +240 -0
  69. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/local.py +557 -0
  70. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/maintenance.py +142 -0
  71. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/planning.py +739 -0
  72. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/preparation.py +142 -0
  73. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/reconcile.py +276 -0
  74. sollertia_forgery-1.0.0/src/sollertia_forgery/orchestration/remote.py +1001 -0
  75. sollertia_forgery-1.0.0/src/sollertia_forgery/py.typed +0 -0
  76. sollertia_forgery-1.0.0/src/sollertia_forgery/registries.py +662 -0
  77. sollertia_forgery-1.0.0/src/sollertia_forgery/runtime/__init__.py +15 -0
  78. sollertia_forgery-1.0.0/src/sollertia_forgery/runtime/pipeline.py +295 -0
  79. sollertia_forgery-1.0.0/src/sollertia_forgery/server/__init__.py +37 -0
  80. sollertia_forgery-1.0.0/src/sollertia_forgery/server/discovery.py +149 -0
  81. sollertia_forgery-1.0.0/src/sollertia_forgery/server/job.py +234 -0
  82. sollertia_forgery-1.0.0/src/sollertia_forgery/server/server.py +866 -0
  83. sollertia_forgery-1.0.0/src/sollertia_forgery/server/server_configuration.py +148 -0
  84. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/__init__.py +37 -0
  85. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/assembly.py +32 -0
  86. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/microcontroller.py +37 -0
  87. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/openmp.py +374 -0
  88. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/pipelines.py +92 -0
  89. sollertia_forgery-1.0.0/src/sollertia_forgery/shared_assets/utilities.py +107 -0
  90. sollertia_forgery-1.0.0/src/sollertia_forgery/two_photon/__init__.py +18 -0
  91. sollertia_forgery-1.0.0/src/sollertia_forgery/two_photon/pipeline.py +475 -0
  92. sollertia_forgery-1.0.0/src/sollertia_forgery/video/__init__.py +25 -0
  93. sollertia_forgery-1.0.0/src/sollertia_forgery/video/motion_energy.py +427 -0
  94. sollertia_forgery-1.0.0/src/sollertia_forgery/video/pipeline.py +696 -0
  95. sollertia_forgery-1.0.0/tests/conftest.py +1127 -0
  96. sollertia_forgery-1.0.0/tests/fixtures/cindra/CA1_GCaMP6f_MD.yaml +50 -0
  97. sollertia_forgery-1.0.0/tests/fixtures/cindra/CA1_GCaMP6f_SD.yaml +72 -0
  98. sollertia_forgery-1.0.0/tests/fixtures/cindra/CA1_GCaMP8s_MD.yaml +50 -0
  99. sollertia_forgery-1.0.0/tests/fixtures/cindra/CA1_GCaMP8s_SD.yaml +72 -0
  100. sollertia_forgery-1.0.0/tests/forging/dataset_resolution_test.py +1042 -0
  101. sollertia_forgery-1.0.0/tests/forging/dataset_state_test.py +300 -0
  102. sollertia_forgery-1.0.0/tests/forging/forging_pipeline_test.py +1050 -0
  103. sollertia_forgery-1.0.0/tests/interfaces/batch_registry_test.py +129 -0
  104. sollertia_forgery-1.0.0/tests/interfaces/planning_tools_test.py +208 -0
  105. sollertia_forgery-1.0.0/tests/interfaces/processing_dispatch_test.py +319 -0
  106. sollertia_forgery-1.0.0/tests/interfaces/read_contract_test.py +382 -0
  107. sollertia_forgery-1.0.0/tests/interfaces/remote_batch_test.py +974 -0
  108. sollertia_forgery-1.0.0/tests/interfaces/scheduler_records_test.py +130 -0
  109. sollertia_forgery-1.0.0/tests/managing/checksum_test.py +251 -0
  110. sollertia_forgery-1.0.0/tests/managing/manifest_test.py +659 -0
  111. sollertia_forgery-1.0.0/tests/managing/project_jobs_test.py +179 -0
  112. sollertia_forgery-1.0.0/tests/mesoscope_vr/behavior_dataset_test.py +532 -0
  113. sollertia_forgery-1.0.0/tests/mesoscope_vr/dataset_assembly_test.py +315 -0
  114. sollertia_forgery-1.0.0/tests/mesoscope_vr/experiment_dataset_test.py +543 -0
  115. sollertia_forgery-1.0.0/tests/mesoscope_vr/mesoscope_runtime_test.py +1090 -0
  116. sollertia_forgery-1.0.0/tests/mesoscope_vr/microcontroller_extraction_test.py +727 -0
  117. sollertia_forgery-1.0.0/tests/mesoscope_vr/training_dataset_test.py +381 -0
  118. sollertia_forgery-1.0.0/tests/mesoscope_vr/two_photon_dataset_test.py +581 -0
  119. sollertia_forgery-1.0.0/tests/mesoscope_vr/two_photon_test.py +255 -0
  120. sollertia_forgery-1.0.0/tests/mesoscope_vr/video_dataset_test.py +388 -0
  121. sollertia_forgery-1.0.0/tests/mesoscope_vr/video_tracking_test.py +431 -0
  122. sollertia_forgery-1.0.0/tests/microcontrollers/microcontrollers_test.py +1216 -0
  123. sollertia_forgery-1.0.0/tests/orchestration/allocation_resolution_test.py +658 -0
  124. sollertia_forgery-1.0.0/tests/orchestration/closure_test.py +758 -0
  125. sollertia_forgery-1.0.0/tests/orchestration/footprints_test.py +2895 -0
  126. sollertia_forgery-1.0.0/tests/orchestration/host_operations_test.py +962 -0
  127. sollertia_forgery-1.0.0/tests/orchestration/job_planning_test.py +1197 -0
  128. sollertia_forgery-1.0.0/tests/orchestration/local_dispatch_test.py +1127 -0
  129. sollertia_forgery-1.0.0/tests/orchestration/maintenance_test.py +362 -0
  130. sollertia_forgery-1.0.0/tests/orchestration/orchestration_concurrency_test.py +917 -0
  131. sollertia_forgery-1.0.0/tests/orchestration/reconciliation_test.py +526 -0
  132. sollertia_forgery-1.0.0/tests/orchestration/remote_orchestration_test.py +1392 -0
  133. sollertia_forgery-1.0.0/tests/registry_coverage_test.py +206 -0
  134. sollertia_forgery-1.0.0/tests/runtime/worker_pipelines_test.py +256 -0
  135. sollertia_forgery-1.0.0/tests/server/server_configuration_test.py +193 -0
  136. sollertia_forgery-1.0.0/tests/server/server_discovery_test.py +266 -0
  137. sollertia_forgery-1.0.0/tests/server/server_test.py +913 -0
  138. sollertia_forgery-1.0.0/tests/shared_assets/openmp_test.py +371 -0
  139. sollertia_forgery-1.0.0/tests/shared_assets/session_pipelines_test.py +159 -0
  140. sollertia_forgery-1.0.0/tests/shared_assets/shared_assets_test.py +122 -0
  141. sollertia_forgery-1.0.0/tests/two_photon/two_photon_priming_test.py +656 -0
  142. sollertia_forgery-1.0.0/tests/video/video_motion_energy_test.py +593 -0
  143. sollertia_forgery-1.0.0/tests/video/video_pipeline_test.py +694 -0
  144. sollertia_forgery-1.0.0/tox.ini +194 -0
@@ -0,0 +1,218 @@
1
+
2
+ # This version of gitignore is designed to work for python projects using C++ computational core. It has been
3
+ # configured, it to exclude certain jetbrains files, but additional configuration may be needed for contributors
4
+ # seeking to use VSCode or other IDE / code editor.
5
+
6
+ # Prerequisites
7
+ *.d
8
+
9
+ # Compiled Object files
10
+ *.slo
11
+ *.lo
12
+ *.o
13
+ *.obj
14
+
15
+ # Precompiled Headers
16
+ *.gch
17
+ *.pch
18
+
19
+ # Compiled Dynamic libraries
20
+ *.so
21
+ *.dylib
22
+ *.dll
23
+
24
+ # Fortran module files
25
+ *.mod
26
+ *.smod
27
+
28
+ # Compiled Static libraries
29
+ *.lai
30
+ *.la
31
+ *.a
32
+ *.lib
33
+
34
+ # Executables
35
+ *.exe
36
+ *.out
37
+ *.app
38
+
39
+ # Platformio files
40
+ *.pio
41
+
42
+ # Byte-compiled / optimized / DLL files
43
+ __pycache__/
44
+ *.py[cod]
45
+ *$py.class
46
+
47
+ # Distribution / packaging
48
+ .Python
49
+ build/
50
+ develop-eggs/
51
+ dist/
52
+ downloads/
53
+ eggs/
54
+ .eggs/
55
+ lib/
56
+ lib64/
57
+ parts/
58
+ sdist/
59
+ var/
60
+ wheels/
61
+ share/python-wheels/
62
+ *.egg-info/
63
+ .installed.cfg
64
+ *.egg
65
+ MANIFEST
66
+
67
+ # PyInstaller
68
+ # Usually these files are written by a python script from a template
69
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
70
+ *.manifest
71
+ *.spec
72
+
73
+ # Installer logs
74
+ pip-log.txt
75
+ pip-delete-this-directory.txt
76
+
77
+ # Unit test / coverage reports
78
+ htmlcov/
79
+ .tox/
80
+ .nox/
81
+ .coverage
82
+ .coverage.*
83
+ .cache
84
+ nosetests.xml
85
+ coverage.xml
86
+ *.cover
87
+ *.py,cover
88
+ .hypothesis/
89
+ .pytest_cache/
90
+ cover/
91
+
92
+ # Translations
93
+ *.mo
94
+ *.pot
95
+
96
+ # Django stuff:
97
+ *.log
98
+ local_settings.py
99
+ db.sqlite3
100
+ db.sqlite3-journal
101
+
102
+ # Flask stuff:
103
+ instance/
104
+ .webassets-cache
105
+
106
+ # Scrapy stuff:
107
+ .scrapy
108
+
109
+ # Sphinx documentation
110
+ docs/_build/
111
+
112
+ # PyBuilder
113
+ .pybuilder/
114
+ target/
115
+
116
+ # Jupyter Notebook
117
+ .ipynb_checkpoints
118
+
119
+ # IPython
120
+ profile_default/
121
+ ipython_config.py
122
+
123
+ # pyenv
124
+ # For a library or package, you might want to ignore these files since the code is
125
+ # intended to run in multiple environments; otherwise, check them in:
126
+ # python-version
127
+
128
+ # pipenv
129
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
130
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
131
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
132
+ # install all needed dependencies.
133
+ #Pipfile.lock
134
+
135
+ # poetry
136
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
137
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
138
+ # commonly ignored for libraries.
139
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
140
+ #poetry.lock
141
+
142
+ # pdm
143
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
144
+ #pdm.lock
145
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
146
+ # in version control.
147
+ # https://pdm.fming.dev/#use-with-ide
148
+ .pdm.toml
149
+
150
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
151
+ __pypackages__/
152
+
153
+ # Celery stuff
154
+ celerybeat-schedule
155
+ celerybeat.pid
156
+
157
+ # SageMath parsed files
158
+ *.sage.py
159
+
160
+ # Environments
161
+ .env
162
+ .venv
163
+ env/
164
+ venv/
165
+ ENV/
166
+ env.bak/
167
+ venv.bak/
168
+
169
+ # Spyder project settings
170
+ .spyderproject
171
+ .spyproject
172
+
173
+ # Rope project settings
174
+ .ropeproject
175
+
176
+ # mkdocs documentation
177
+ /site
178
+
179
+ # mypy
180
+ .mypy_cache/
181
+ .dmypy.json
182
+ dmypy.json
183
+
184
+ # Pyre type checker
185
+ .pyre/
186
+
187
+ # pytype static type analyzer
188
+ .pytype/
189
+
190
+ # Cython debug symbols
191
+ cython_debug/
192
+
193
+ # PyCharm
194
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
195
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
196
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
197
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
198
+ .idea/
199
+
200
+ # OSx
201
+ .DS_Store
202
+
203
+ # Project files that are part of the general Sollertia C-Python project architecture that should not be uploaded to and
204
+ # from Github
205
+ /cmake-build-debug/
206
+ /reports/
207
+ /docs/source/doxygen/
208
+ /docs/build/
209
+ /stubs/
210
+ /.pypirc
211
+
212
+
213
+ # Project: Add any project-specific exclusions here
214
+ Temp/
215
+ /temp
216
+ trash/
217
+ data
218
+ .vscode
@@ -0,0 +1 @@
1
+ sollertia-forgery-api-docs.netlify.app
@@ -0,0 +1,267 @@
1
+ # Claude Code Instructions
2
+
3
+ ## Session start behavior
4
+
5
+ At the beginning of each coding session, before making any code changes, you MUST build a comprehensive understanding of
6
+ the codebase by invoking the `automation:explore-codebase` skill.
7
+
8
+ ## Style guide compliance
9
+
10
+ You MUST invoke the appropriate style skill before performing ANY of the following tasks:
11
+
12
+ | Task | Skill to invoke |
13
+ |-----------------------------------------------|------------------------------|
14
+ | Writing or modifying Python code | `automation:python-style` |
15
+ | Writing or modifying README files | `automation:readme-style` |
16
+ | Writing or modifying skill files or this file | `automation:skill-design` |
17
+ | Writing or modifying pyproject.toml | `automation:pyproject-style` |
18
+ | Writing or modifying tox.ini | `automation:tox-config` |
19
+ | Writing or modifying Sphinx docs files | `automation:api-docs` |
20
+ | Creating or verifying project structure | `automation:project-layout` |
21
+ | Committing local changes | `automation:commit` |
22
+
23
+ Each skill contains a verification checklist that you MUST complete before submitting any work.
24
+
25
+ ## Cross-referenced library verification
26
+
27
+ The `sollertia-forgery` package depends on several `ataraxis-*` libraries, on `sollertia-shared-assets`, and on
28
+ `cindra`. These libraries may be stored locally in the same parent directory as this project, reachable as `../`
29
+ from the repository root.
30
+
31
+ **Before writing code that interacts with a cross-referenced library, you MUST:**
32
+
33
+ 1. **Check for local version**: Look for the library in the parent directory (e.g., `../ataraxis-video-system/`,
34
+ `../ataraxis-communication-interface/`, `../sollertia-shared-assets/`, `../cindra/`).
35
+
36
+ 2. **Compare versions**: If a local copy exists, compare its version against the latest release or main branch on
37
+ GitHub:
38
+ - Read the local `pyproject.toml` to get the current version
39
+ - Use `gh api repos/Sun-Lab-NBB/{repo-name}/releases/latest` to check the latest release
40
+ - Alternatively, check the main branch version on GitHub
41
+
42
+ 3. **Handle version mismatches**: If the local version differs from the latest release or main branch, notify the user
43
+ with the following options:
44
+ - **Use online version**: Fetch documentation and API details from the GitHub repository
45
+ - **Update local copy**: The user will pull the latest changes locally before proceeding
46
+
47
+ 4. **Proceed with correct source**: Use whichever version the user selects, and treat that version as the
48
+ authoritative reference for API usage, patterns, and documentation.
49
+
50
+ ## Available skills
51
+
52
+ **Forging plugin skills** (`sollertia` marketplace, `forging` plugin):
53
+
54
+ | Skill | Description |
55
+ |-----------------------------------------|---------------------------------------------------------------------------|
56
+ | `forging:batch-processing` | Orchestrates batch processing across all six batch pipelines |
57
+ | `forging:cli-reference` | Documents every `slf` command, option, and its MCP counterpart |
58
+ | `forging:data-processing-design` | Documents the agnostic-worker and per-system-donation design pattern |
59
+ | `forging:dataset-definition` | Composes forged dataset hierarchies and reports their forging job state |
60
+ | `forging:dataset-forging` | Documents how the forging pipeline differs from the per-session pipelines |
61
+ | `forging:forging-mcp-environment-setup` | Diagnoses MCP connectivity and owns the shared response envelope |
62
+ | `forging:job-planning` | Sizes every runnable job and records the planned cores and memory |
63
+ | `forging:library-extension` | Owns the extension path for systems, stages, pipelines, and MCP tools |
64
+ | `forging:pipeline` | Orders the end-to-end processing lifecycle and its local-remote split |
65
+ | `forging:processing-input-format` | Documents the on-disk inputs each batch pipeline requires |
66
+ | `forging:processing-results` | Documents what each pipeline writes and how to verify it |
67
+ | `forging:project-state` | Documents the session manifest and the job table published beside it |
68
+ | `forging:remote-execution` | Runs work on the configured SLURM compute server through `slf mcp` |
69
+ | `forging:server-configuration` | Authors the `ServerConfiguration` YAML authorizing SSH and SLURM access |
70
+
71
+ **Mesoscope plugin skills** (`sollertia` marketplace, `mesoscope` plugin) document the Mesoscope-VR donations under
72
+ `src/sollertia_forgery/mesoscope_vr/`, through `mesoscope:mesoscope-vr-module-parsing`,
73
+ `mesoscope:mesoscope-vr-trial-decomposition`, `mesoscope:mesoscope-vr-fluorescence-alignment`,
74
+ `mesoscope:mesoscope-vr-imaging-configuration`, `mesoscope:mesoscope-vr-video-tracking`,
75
+ `mesoscope:mesoscope-vr-dataset-assembly`, and `mesoscope:mesoscope-vr-processing-schema`, which owns the
76
+ `BehaviorDataFiles`, `VideoDataFiles`, and `DatasetColumn` rosters in `mesoscope_vr/metadata.py`.
77
+
78
+ **Automation plugin skills** (`ataraxis` marketplace, `automation` plugin) provide the style guides listed above,
79
+ `automation:explore-codebase`, `automation:explore-dependencies`, the `automation:audit-*` family, `automation:pr`, and
80
+ `automation:release`.
81
+
82
+ ## MCP server
83
+
84
+ The library exposes an MCP server through the `slf mcp` command. `interfaces/entry_points.py` selects the transport with
85
+ `-t/--transport`, defaulting to `stdio` and also accepting `sse` and `streamable-http` for a network client. It
86
+ disables the console on the `stdio` path, because the pipelines echo progress to the same stream that carries the
87
+ JSON-RPC messages. `interfaces/mcp_server.py` runs the server, and its import discovers every `*_tools.py` module under
88
+ `src/sollertia_forgery/interfaces/`, each of which registers the tools it declares purely as an import side effect.
89
+
90
+ **When adding an MCP tool**, place it in the `*_tools.py` module that owns its domain and decorate it with `@mcp.tool()`
91
+ from `.mcp_instance`. Return through the `ok_response` and `error_response` helpers in `.responses`, and give the tool a
92
+ `Returns` section that names the response keys in prose. Resolve every path the tool opens inside that envelope, so a
93
+ directory the host does not supply answers with an error response rather than raising out of the session. A tool that
94
+ reads a remote project opens that project's local mirror and reports the caller's own `project_path` back through
95
+ `resolve_reported_project_path`, while the artifact path keys beside it name the mirror the read actually opened. Add a
96
+ new tool module to the `[tool.coverage.run] omit` list in `pyproject.toml`, because tool modules reach infrastructure
97
+ that only a live MCP session supplies. The batch tools that read, cancel, and remediate what the scheduler ran keep
98
+ their implementations in `interfaces/remote_tools.py`, which registers no tool of its own. An `slf server` command and
99
+ the tool beside it therefore answer a caller from one function. `get_processing_status_tool` and
100
+ `retire_remote_batches_tool` resolve every allocation through the one state table in `orchestration/remote.py` rather
101
+ than each deciding for itself.
102
+
103
+ ## Downstream library integration
104
+
105
+ This library reads the records defined by `sollertia-shared-assets` and drives the pipelines published by
106
+ `ataraxis-video-system`, `ataraxis-communication-interface`, and `cindra`. It never references the downstream analysis
107
+ repository, which owns its own artifact names.
108
+
109
+ ## Companion library synchronization
110
+
111
+ `sollertia-shared-assets` owns the vocabulary this library uses for dispatch, and `sollertia-experiment` records the
112
+ data this library processes, so an out-of-domain extension usually lands as one change in each of the three
113
+ repositories.
114
+
115
+ - `AcquisitionSystems`, `SessionTypes`, `SYSTEM_SESSION_TYPES`, `ProcessingTrackers`, `ProcessedData`, `SessionData`,
116
+ and `DatasetData` all live in `sollertia-shared-assets`. A new acquisition system or session type gains its
117
+ enumeration member there first through `assets:library-extension`, and this library never mints one locally.
118
+ - Adding an `AcquisitionSystems` member upstream breaks every import path that reaches `registries.py`, and that break
119
+ holds until this library wires the new system. Those paths cover every processing pipeline. Read the RuntimeError
120
+ raised by `_assert_registry_coverage` as the remaining extension checklist.
121
+ - `_FORGING_ADMISSION_REGISTRY` and `_MULTI_RECORDING_SESSION_TYPE_REGISTRY` validate their session types against
122
+ `SYSTEM_SESSION_TYPES`, so each type this library assigns to a system must appear under that same system in the
123
+ upstream registry.
124
+ - A new per-session pipeline needs an upstream tracker filename in `ProcessingTrackers` and an upstream output directory
125
+ in `ProcessedData`, before `shared_assets/pipelines.py` is able to resolve the tracker location.
126
+ - `sollertia-experiment` has to acquire the data before anything here can process it, so confirm that the acquisition
127
+ side creates sessions of a new session type and writes the artifacts a new pipeline reads. `experiment:pipeline` owns
128
+ that acquisition lifecycle, `experiment:data-management` owns the preprocessing that materializes `raw_data`, and
129
+ `mesoscope:mesoscope-vr-runtime` owns the Mesoscope-VR runtime that records the session.
130
+
131
+ ## Distribution model
132
+
133
+ The package ships to PyPI as `sollertia-forgery` and installs the `slf` CLI. Its Claude Code skills ship separately,
134
+ through the [sollertia](https://github.com/Sun-Lab-NBB/sollertia) marketplace, in its `forging` and `mesoscope` plugins,
135
+ and the `forging` plugin alone carries the MCP server registration. An agent asked to add or change a skill edits that
136
+ repository rather than this one.
137
+
138
+ ## Project context
139
+
140
+ This is **sollertia-forgery**, the data processing counterpart to `sollertia-experiment`. It turns the raw acquisition
141
+ logs of a recorded session into per-session data tables, verifies the integrity of the acquired data, and forges the
142
+ processed sessions into the multi-session datasets consumed by a downstream analysis repository.
143
+
144
+ ### Key areas
145
+
146
+ | Path | Contents |
147
+ |----------------------------------------|--------------------------------------------------------------------------|
148
+ | `src/sollertia_forgery/registries.py` | The acquisition-system dispatch registries and their coverage check |
149
+ | `src/sollertia_forgery/mesoscope_vr/` | The Mesoscope-VR system's donated parsers, resolvers, and workers |
150
+ | `src/sollertia_forgery/orchestration/` | Planning, preparation, dispatch, execution, closure, and maintenance |
151
+ | `src/sollertia_forgery/managing/` | The checksum pipeline, the project manifest, and the job artifact |
152
+ | `src/sollertia_forgery/server/` | SLURM jobs, remote discovery, the SSH and SFTP transport, and its config |
153
+ | `src/sollertia_forgery/interfaces/` | The `slf` Click CLI and the MCP tool modules |
154
+ | `src/sollertia_forgery/shared_assets/` | The agnostic substrate on which every category package draws |
155
+
156
+ The `video/`, `microcontrollers/`, `runtime/`, `two_photon/`, and `forging/` category packages sit beside them, one
157
+ per pipeline.
158
+
159
+ ### Architecture
160
+
161
+ The processing packages are **system-agnostic**. A category package such as `video/`, `microcontrollers/`, `runtime/`,
162
+ `two_photon/`, or `forging/` owns a pipeline that runs the same way for every acquisition system. Everything a specific
163
+ acquisition system contributes lives in a per-system package such as `mesoscope_vr/`, and reaches the agnostic
164
+ pipelines through `registries.py`.
165
+
166
+ `registries.py` maps each `AcquisitionSystems` member to the workers, parsers, resolvers, and locators donated by that
167
+ member, and runs an import-time coverage check that refuses a partially wired system. The dependency runs one way,
168
+ because a per-system package never imports an agnostic category package. A category pipeline imports `registries.py` and
169
+ `registries.py` imports every per-system package, so the reverse import is a genuine cycle rather than a style
170
+ preference.
171
+
172
+ Work reaches a host as a **job**, and every pipeline models its jobs the same way. `slf plan session` and
173
+ `slf plan dataset` read a unit's acquisition data, register on its processing tracker every job that unit is able to
174
+ run, and record each job's cores, its two memory figures, and its upstream jobs. `memory_mb` is the anonymous memory the
175
+ job allocates, which is the term this machine's process pool budgets against, and `resident_mb` adds to it the pages the
176
+ job maps and the file-backed library image every job holds, which is the term one SLURM allocation requests. Preparation
177
+ joins the tracker state to those records into one descriptor per job under a batch identifier, and dispatch runs the
178
+ batch either on this machine's process pool or as one SLURM allocation per job. Each job holds a `ProcessingStatus` on
179
+ the tracker, one of `SCHEDULED`, `RUNNING`, `SUCCEEDED`, or `FAILED`. A rerun therefore resolves only the work still
180
+ outstanding. The run reports a job as blocked rather than dispatched when it can neither queue that job's upstream stage
181
+ nor confirm that the stage already succeeded.
182
+
183
+ A remote allocation outlives this process, so `orchestration/remote.py` resolves each recorded one against scheduler
184
+ accounting, the scheduler queue, and the job's own tracker. That resolution yields a `scheduler_state`, a `verdict`,
185
+ and the `remediation` that verdict prescribes, with `_VERDICT_REMEDIATIONS` as the single state table both the status
186
+ read and the remediation apply. Only the `stranded` verdict writes a tracker, because a tracker still claiming a purged
187
+ allocation is the one record no rerun can clear.
188
+
189
+ The public surface of the distribution is the `slf` CLI and the MCP server that CLI starts, so the top-level
190
+ `__init__.py` re-exports no library symbol and its `__all__` is empty. Adding a name to a public listing is a deliberate
191
+ API change rather than a convenience.
192
+
193
+ ### Extension contracts
194
+
195
+ Every registry is private to `registries.py` and is reached through that module's `resolve_*` accessors, so a consuming
196
+ pipeline never indexes a registry directly. All thirteen registries are the designed extension point, and a new
197
+ acquisition system supplies an entry in each.
198
+
199
+ | Registry | Donation |
200
+ |------------------------------------------|------------------------------------------------------------------|
201
+ | `_MICROCONTROLLER_PARSER_REGISTRY` | One `MicrocontrollerParser` per parsed hardware module |
202
+ | `_MICROCONTROLLER_EVENT_CODE_REGISTRY` | The event codes every parsed module reads |
203
+ | `_MICROCONTROLLER_ELIGIBILITY_REGISTRY` | The modules a given session configured for use |
204
+ | `_RUNTIME_PARSER_REGISTRY` | The source id of the runtime log, paired with its parser |
205
+ | `_POSE_PREDICTION_REGISTRY` | The locator for the externally-produced pose-prediction file |
206
+ | `_VIDEO_TRACKING_REGISTRY` | The system's whole video-tracking pass |
207
+ | `_TWO_PHOTON_DATA_REGISTRY` | The locator for the raw two-photon imaging directory |
208
+ | `_CINDRA_CONFIGURATION_REGISTRY` | The single- and multi-recording cindra config resolvers |
209
+ | `_FORGING_ASSEMBLY_REGISTRY` | The per-session assembler and its column descriptions |
210
+ | `_ASSEMBLY_GEOMETRY_REGISTRY` | The heights at which its assembler holds a frame and its sources |
211
+ | `_ASSEMBLY_SOURCE_REGISTRY` | The height at which its assembler holds each source it reads |
212
+ | `_FORGING_ADMISSION_REGISTRY` | The pipelines a session of each type completes to join a dataset |
213
+ | `_MULTI_RECORDING_SESSION_TYPE_REGISTRY` | The session types the system tracks across recordings |
214
+
215
+ Every registry is keyed by `AcquisitionSystems`, except `_MICROCONTROLLER_PARSER_REGISTRY`, whose `(AcquisitionSystems,
216
+ module_type, module_id)` key lets a system register one parser per hardware module.
217
+
218
+ `_assert_registry_coverage()` runs when `registries.py` is imported and raises a `RuntimeError` that names the offending
219
+ members. It fires when a system is missing from any registry, when a parseable microcontroller module declares no event
220
+ codes, and when a declared session type is absent from the upstream `SYSTEM_SESSION_TYPES` pairing for that system.
221
+
222
+ **When adding an acquisition system**, add its package, register every donation in `registries.py`, and let the coverage
223
+ check tell you what is still unwired. Nothing under `orchestration/` or `interfaces/` changes, because every command
224
+ resolves the system from the session or dataset it opens.
225
+
226
+ **When adding a processing stage**, define or reuse its job name, emit it from the pipeline's job discovery, order it in
227
+ the prerequisite mapping, and give it both a `_JOB_CORE_ALLOCATIONS` entry and a sizing model in `footprints.py`. A job
228
+ type missing either one is a hard error rather than a job admitted at a default size. A sizing model states the
229
+ anonymous memory its stage allocates, and a stage that holds its input memory-mapped states those bytes beside it as
230
+ the footprint's `mapped_mb`, because the resident figure a SLURM allocation requests is derived from the two together.
231
+
232
+ **When adding a processing pipeline**, add its `ProcessingPipelines` member and tracker entry in
233
+ `shared_assets/pipelines.py`, its category package, and both its `BATCH_PIPELINES` membership and its `PipelineDispatch`
234
+ entry, which `_assert_dispatch_coverage` holds in step. Give a per-session pipeline its manifest status column in
235
+ `_PIPELINE_STATUS_COLUMNS`, and name that column in the five rosters beside it in `managing/manifest.py`:
236
+ `_PROJECT_MANIFEST_SCHEMA`, `_MANIFEST_ROW_COLUMNS`, `_MANIFEST_SUMMARY_COLUMNS`, and the public `MANIFEST_AXES` and
237
+ `MANIFEST_SEMI_FIELDS` that `interfaces/management_tools.py` imports. `_assert_status_column_coverage` checks all of it
238
+ at import, raising when the declared columns and `SESSION_PIPELINES` differ either way, when a roster omits a status
239
+ column, and when a roster names a column the schema does not declare. Then add its CLI and MCP surfaces.
240
+
241
+ ### Code standards
242
+
243
+ - Every category package `__init__.py` exports its pipeline entry point, every stage job name, and the job discovery and
244
+ prerequisite callables the orchestration layer binds. A name reaches that list only when a package outside the
245
+ defining one imports it, and a symbol that no other module reaches at all carries the underscore.
246
+ - A stage backed by a library `execute_job` binding reuses the job-name constant that library exports rather than a
247
+ local string, so the tracker identifiers stay aligned with the library's own. The forging pipeline is the one
248
+ exception. Its tracker interleaves cindra's cross-recording stages with the assembly stage this library owns and
249
+ records all of them under local names, which `_MULTIDAY_JOB_NAMES` mints. A new cindra stage also needs its core
250
+ allocation in `orchestration/dispatch.py` and its sizing branch in `orchestration/footprints.py`.
251
+ - The test suite covers 100% of the measured statements. Interface modules are excluded per module through the
252
+ `[tool.coverage.run] omit` list rather than through a directory glob.
253
+ - A test that spawns a process pool or mutates process-wide state carries `@pytest.mark.xdist_group`, because the suite
254
+ runs under `pytest-xdist` with `--dist loadgroup`.
255
+
256
+ ### Development commands
257
+
258
+ | Command | Effect |
259
+ |---------------------|------------------------------------------------------------|
260
+ | `tox -e lint` | Runs ruff formatting, ruff linting, and mypy type checking |
261
+ | `tox -e py314-test` | Runs the test suite and writes its coverage data |
262
+ | `tox -e coverage` | Merges the coverage data and applies the 100% gate |
263
+ | `tox -e docs` | Builds the API documentation |
264
+ | `tox -e create` | Creates the `slf_dev` mamba environment |
265
+ | `tox -e install` | Installs the project into that environment |
266
+
267
+ Run `tox` with no argument to execute the full pipeline, and `tox --parallel` to overlap the tasks that allow it.