catabolic 0.1.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 (411) hide show
  1. catabolic-0.1.0/LICENSE +22 -0
  2. catabolic-0.1.0/MANIFEST.in +6 -0
  3. catabolic-0.1.0/PKG-INFO +470 -0
  4. catabolic-0.1.0/README.md +440 -0
  5. catabolic-0.1.0/docs/ARTIFACTS.md +324 -0
  6. catabolic-0.1.0/docs/AUDIT.md +155 -0
  7. catabolic-0.1.0/docs/AUTOMATION.md +186 -0
  8. catabolic-0.1.0/docs/CATALOG_REFRESH.md +119 -0
  9. catabolic-0.1.0/docs/COMPATIBILITY.md +250 -0
  10. catabolic-0.1.0/docs/COMPONENTS.md +264 -0
  11. catabolic-0.1.0/docs/CONSUMERS.md +421 -0
  12. catabolic-0.1.0/docs/CONSUMER_DESIGN.md +142 -0
  13. catabolic-0.1.0/docs/CONSUMER_VALIDATION.md +177 -0
  14. catabolic-0.1.0/docs/COPYRIGHT_AUDIT.md +179 -0
  15. catabolic-0.1.0/docs/DESIGN.md +340 -0
  16. catabolic-0.1.0/docs/DEVELOPMENT.md +180 -0
  17. catabolic-0.1.0/docs/ENRICHMENT.md +413 -0
  18. catabolic-0.1.0/docs/EXPERIENCE_ACCEPTANCE.md +229 -0
  19. catabolic-0.1.0/docs/FALLBACK.md +189 -0
  20. catabolic-0.1.0/docs/FAQ.md +150 -0
  21. catabolic-0.1.0/docs/GETTING_STARTED.md +156 -0
  22. catabolic-0.1.0/docs/GRAPHQL.md +175 -0
  23. catabolic-0.1.0/docs/HARDLINKS.md +160 -0
  24. catabolic-0.1.0/docs/HTTP.md +458 -0
  25. catabolic-0.1.0/docs/HTTP_BACKEND_M0.md +255 -0
  26. catabolic-0.1.0/docs/INBOX.md +210 -0
  27. catabolic-0.1.0/docs/INSTALLATION.md +147 -0
  28. catabolic-0.1.0/docs/MAINTENANCE.md +212 -0
  29. catabolic-0.1.0/docs/MANIFESTS.md +153 -0
  30. catabolic-0.1.0/docs/MEDIA_MODEL.md +196 -0
  31. catabolic-0.1.0/docs/MIGRATIONS.md +349 -0
  32. catabolic-0.1.0/docs/NATIVE_LAYOUT.md +114 -0
  33. catabolic-0.1.0/docs/OBSERVATIONS.md +314 -0
  34. catabolic-0.1.0/docs/OPEN_CATALOG.md +214 -0
  35. catabolic-0.1.0/docs/OPERATIONS.md +280 -0
  36. catabolic-0.1.0/docs/OUTPUT_LAYOUTS.md +221 -0
  37. catabolic-0.1.0/docs/PROCESSING_REVIEW.md +352 -0
  38. catabolic-0.1.0/docs/PROCESSORS.md +159 -0
  39. catabolic-0.1.0/docs/PROGRAMMABLE_CATALOG.md +346 -0
  40. catabolic-0.1.0/docs/PROGRAMMABLE_CATALOG_REVIEW.md +118 -0
  41. catabolic-0.1.0/docs/PROGRAMMABLE_CATALOG_VALIDATION.md +212 -0
  42. catabolic-0.1.0/docs/QUERYING.md +256 -0
  43. catabolic-0.1.0/docs/QUERY_FOLDERS.md +175 -0
  44. catabolic-0.1.0/docs/RELEASE_TESTING.md +217 -0
  45. catabolic-0.1.0/docs/RENDITION_WORKFLOWS.md +257 -0
  46. catabolic-0.1.0/docs/ROADMAP.md +324 -0
  47. catabolic-0.1.0/docs/RULES.md +204 -0
  48. catabolic-0.1.0/docs/SCALE_BENCHMARKS.md +170 -0
  49. catabolic-0.1.0/docs/SCHEMAS.md +135 -0
  50. catabolic-0.1.0/docs/TAGGING.md +220 -0
  51. catabolic-0.1.0/docs/TROUBLESHOOTING.md +167 -0
  52. catabolic-0.1.0/docs/TRUST_POLICIES.md +102 -0
  53. catabolic-0.1.0/docs/WATCHERS.md +165 -0
  54. catabolic-0.1.0/docs/WORKFLOW.md +141 -0
  55. catabolic-0.1.0/docs/WORKLOG.md +171 -0
  56. catabolic-0.1.0/docs/plans/UNIFIED_FALLBACK.md +226 -0
  57. catabolic-0.1.0/docs/plans/WATCHERS.md +176 -0
  58. catabolic-0.1.0/pyproject.toml +49 -0
  59. catabolic-0.1.0/setup.cfg +4 -0
  60. catabolic-0.1.0/src/catabolic/__init__.py +6 -0
  61. catabolic-0.1.0/src/catabolic/__main__.py +6 -0
  62. catabolic-0.1.0/src/catabolic/access/__init__.py +298 -0
  63. catabolic-0.1.0/src/catabolic/access/catalog.py +238 -0
  64. catabolic-0.1.0/src/catabolic/access/graphql.py +158 -0
  65. catabolic-0.1.0/src/catabolic/api_cli.py +245 -0
  66. catabolic-0.1.0/src/catabolic/api_events.py +79 -0
  67. catabolic-0.1.0/src/catabolic/app.py +533 -0
  68. catabolic-0.1.0/src/catabolic/artifact_cli.py +70 -0
  69. catabolic-0.1.0/src/catabolic/artifacts.py +792 -0
  70. catabolic-0.1.0/src/catabolic/catalog_refresh.py +203 -0
  71. catabolic-0.1.0/src/catabolic/catalog_refresh_cli.py +76 -0
  72. catabolic-0.1.0/src/catabolic/catalog_state.py +86 -0
  73. catabolic-0.1.0/src/catabolic/cli.py +1484 -0
  74. catabolic-0.1.0/src/catabolic/component_claims.py +121 -0
  75. catabolic-0.1.0/src/catabolic/component_cli.py +54 -0
  76. catabolic-0.1.0/src/catabolic/component_packages.py +497 -0
  77. catabolic-0.1.0/src/catabolic/component_packaging.py +596 -0
  78. catabolic-0.1.0/src/catabolic/component_sql.py +228 -0
  79. catabolic-0.1.0/src/catabolic/components.py +229 -0
  80. catabolic-0.1.0/src/catabolic/consumer_adapters.py +413 -0
  81. catabolic-0.1.0/src/catabolic/consumer_cli.py +358 -0
  82. catabolic-0.1.0/src/catabolic/consumer_setup.py +394 -0
  83. catabolic-0.1.0/src/catabolic/consumers.py +515 -0
  84. catabolic-0.1.0/src/catabolic/content_access.py +142 -0
  85. catabolic-0.1.0/src/catabolic/copy_selection.py +237 -0
  86. catabolic-0.1.0/src/catabolic/curation.py +549 -0
  87. catabolic-0.1.0/src/catabolic/database_io.py +84 -0
  88. catabolic-0.1.0/src/catabolic/document_text.py +130 -0
  89. catabolic-0.1.0/src/catabolic/documentation.py +372 -0
  90. catabolic-0.1.0/src/catabolic/domain.py +73 -0
  91. catabolic-0.1.0/src/catabolic/enrichment_cli.py +342 -0
  92. catabolic-0.1.0/src/catabolic/estimate_calibration.py +84 -0
  93. catabolic-0.1.0/src/catabolic/evaluation.py +105 -0
  94. catabolic-0.1.0/src/catabolic/execution_claims.py +132 -0
  95. catabolic-0.1.0/src/catabolic/exports.py +311 -0
  96. catabolic-0.1.0/src/catabolic/fallback_cli.py +119 -0
  97. catabolic-0.1.0/src/catabolic/fallback_models.py +97 -0
  98. catabolic-0.1.0/src/catabolic/fallback_policies.py +113 -0
  99. catabolic-0.1.0/src/catabolic/fallback_probe.py +135 -0
  100. catabolic-0.1.0/src/catabolic/fallback_projection.py +525 -0
  101. catabolic-0.1.0/src/catabolic/fallback_records.py +36 -0
  102. catabolic-0.1.0/src/catabolic/fallback_resolution.py +596 -0
  103. catabolic-0.1.0/src/catabolic/fallback_worker.py +110 -0
  104. catabolic-0.1.0/src/catabolic/filesystem.py +261 -0
  105. catabolic-0.1.0/src/catabolic/graphql_query.py +834 -0
  106. catabolic-0.1.0/src/catabolic/guides/ARTIFACTS.md +324 -0
  107. catabolic-0.1.0/src/catabolic/guides/AUTOMATION.md +186 -0
  108. catabolic-0.1.0/src/catabolic/guides/CATALOG_REFRESH.md +119 -0
  109. catabolic-0.1.0/src/catabolic/guides/COMPATIBILITY.md +250 -0
  110. catabolic-0.1.0/src/catabolic/guides/COMPONENTS.md +264 -0
  111. catabolic-0.1.0/src/catabolic/guides/CONSUMERS.md +421 -0
  112. catabolic-0.1.0/src/catabolic/guides/CONSUMER_DESIGN.md +142 -0
  113. catabolic-0.1.0/src/catabolic/guides/CONSUMER_VALIDATION.md +177 -0
  114. catabolic-0.1.0/src/catabolic/guides/DESIGN.md +340 -0
  115. catabolic-0.1.0/src/catabolic/guides/DEVELOPMENT.md +180 -0
  116. catabolic-0.1.0/src/catabolic/guides/ENRICHMENT.md +413 -0
  117. catabolic-0.1.0/src/catabolic/guides/EXPERIENCE_ACCEPTANCE.md +229 -0
  118. catabolic-0.1.0/src/catabolic/guides/FALLBACK.md +189 -0
  119. catabolic-0.1.0/src/catabolic/guides/FAQ.md +150 -0
  120. catabolic-0.1.0/src/catabolic/guides/GETTING_STARTED.md +156 -0
  121. catabolic-0.1.0/src/catabolic/guides/GRAPHQL.md +175 -0
  122. catabolic-0.1.0/src/catabolic/guides/HARDLINKS.md +160 -0
  123. catabolic-0.1.0/src/catabolic/guides/HTTP.md +458 -0
  124. catabolic-0.1.0/src/catabolic/guides/INBOX.md +210 -0
  125. catabolic-0.1.0/src/catabolic/guides/INSTALLATION.md +147 -0
  126. catabolic-0.1.0/src/catabolic/guides/MAINTENANCE.md +212 -0
  127. catabolic-0.1.0/src/catabolic/guides/MANIFESTS.md +153 -0
  128. catabolic-0.1.0/src/catabolic/guides/MEDIA_MODEL.md +196 -0
  129. catabolic-0.1.0/src/catabolic/guides/MIGRATIONS.md +349 -0
  130. catabolic-0.1.0/src/catabolic/guides/NATIVE_LAYOUT.md +114 -0
  131. catabolic-0.1.0/src/catabolic/guides/OBSERVATIONS.md +314 -0
  132. catabolic-0.1.0/src/catabolic/guides/OPEN_CATALOG.md +214 -0
  133. catabolic-0.1.0/src/catabolic/guides/OPERATIONS.md +280 -0
  134. catabolic-0.1.0/src/catabolic/guides/OUTPUT_LAYOUTS.md +221 -0
  135. catabolic-0.1.0/src/catabolic/guides/PROCESSING_REVIEW.md +352 -0
  136. catabolic-0.1.0/src/catabolic/guides/PROCESSORS.md +159 -0
  137. catabolic-0.1.0/src/catabolic/guides/PROGRAMMABLE_CATALOG.md +346 -0
  138. catabolic-0.1.0/src/catabolic/guides/PROGRAMMABLE_CATALOG_REVIEW.md +118 -0
  139. catabolic-0.1.0/src/catabolic/guides/PROGRAMMABLE_CATALOG_VALIDATION.md +212 -0
  140. catabolic-0.1.0/src/catabolic/guides/QUERYING.md +256 -0
  141. catabolic-0.1.0/src/catabolic/guides/QUERY_FOLDERS.md +175 -0
  142. catabolic-0.1.0/src/catabolic/guides/README.md +440 -0
  143. catabolic-0.1.0/src/catabolic/guides/RELEASE_TESTING.md +217 -0
  144. catabolic-0.1.0/src/catabolic/guides/RENDITION_WORKFLOWS.md +257 -0
  145. catabolic-0.1.0/src/catabolic/guides/RULES.md +204 -0
  146. catabolic-0.1.0/src/catabolic/guides/SCALE_BENCHMARKS.md +170 -0
  147. catabolic-0.1.0/src/catabolic/guides/SCHEMAS.md +135 -0
  148. catabolic-0.1.0/src/catabolic/guides/TAGGING.md +220 -0
  149. catabolic-0.1.0/src/catabolic/guides/TROUBLESHOOTING.md +167 -0
  150. catabolic-0.1.0/src/catabolic/guides/TRUST_POLICIES.md +102 -0
  151. catabolic-0.1.0/src/catabolic/guides/WATCHERS.md +165 -0
  152. catabolic-0.1.0/src/catabolic/guides/WORKFLOW.md +141 -0
  153. catabolic-0.1.0/src/catabolic/guides/WORKLOG.md +171 -0
  154. catabolic-0.1.0/src/catabolic/hardlinks.py +580 -0
  155. catabolic-0.1.0/src/catabolic/http/__init__.py +4 -0
  156. catabolic-0.1.0/src/catabolic/http/app.py +1022 -0
  157. catabolic-0.1.0/src/catabolic/http/contract.py +200 -0
  158. catabolic-0.1.0/src/catabolic/http/fallback.py +227 -0
  159. catabolic-0.1.0/src/catabolic/http/models.py +347 -0
  160. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/manifest.json +37 -0
  161. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/manifest.json.license +2 -0
  162. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/openapi.json +12407 -0
  163. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/openapi.json.license +2 -0
  164. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/schema.graphql +261 -0
  165. catabolic-0.1.0/src/catabolic/http/releases/1.0.0/schema.graphql.license +2 -0
  166. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/manifest.json +40 -0
  167. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/manifest.json.license +2 -0
  168. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/openapi.json +13564 -0
  169. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/openapi.json.license +2 -0
  170. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/schema.graphql +287 -0
  171. catabolic-0.1.0/src/catabolic/http/releases/1.1.0/schema.graphql.license +2 -0
  172. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/manifest.json +46 -0
  173. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/manifest.json.license +2 -0
  174. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/openapi.json +15408 -0
  175. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/openapi.json.license +2 -0
  176. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/schema.graphql +287 -0
  177. catabolic-0.1.0/src/catabolic/http/releases/1.2.0/schema.graphql.license +2 -0
  178. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/manifest.json +46 -0
  179. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/manifest.json.license +2 -0
  180. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/openapi.json +15408 -0
  181. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/openapi.json.license +2 -0
  182. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/schema.graphql +335 -0
  183. catabolic-0.1.0/src/catabolic/http/releases/1.3.0/schema.graphql.license +2 -0
  184. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/manifest.json +46 -0
  185. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/manifest.json.license +2 -0
  186. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/openapi.json +15452 -0
  187. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/openapi.json.license +2 -0
  188. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/schema.graphql +335 -0
  189. catabolic-0.1.0/src/catabolic/http/releases/1.4.0/schema.graphql.license +2 -0
  190. catabolic-0.1.0/src/catabolic/http/transport.py +98 -0
  191. catabolic-0.1.0/src/catabolic/http/watchers.py +161 -0
  192. catabolic-0.1.0/src/catabolic/http_worker.py +72 -0
  193. catabolic-0.1.0/src/catabolic/http_worker_local.py +109 -0
  194. catabolic-0.1.0/src/catabolic/importers.py +205 -0
  195. catabolic-0.1.0/src/catabolic/inbox_cli.py +106 -0
  196. catabolic-0.1.0/src/catabolic/interchange/__init__.py +4 -0
  197. catabolic-0.1.0/src/catabolic/interchange/releases/index.json +8 -0
  198. catabolic-0.1.0/src/catabolic/interchange/releases/index.json.license +2 -0
  199. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v1.md +179 -0
  200. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v1.md.license +2 -0
  201. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v1.schema.json +921 -0
  202. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v1.schema.json.license +2 -0
  203. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v2.md +232 -0
  204. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v2.md.license +2 -0
  205. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v2.schema.json +1190 -0
  206. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v2.schema.json.license +2 -0
  207. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v3.md +266 -0
  208. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v3.md.license +2 -0
  209. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v3.schema.json +1379 -0
  210. catabolic-0.1.0/src/catabolic/interchange/releases/manifest-v3.schema.json.license +2 -0
  211. catabolic-0.1.0/src/catabolic/interchange/specification.py +132 -0
  212. catabolic-0.1.0/src/catabolic/interchange/v1.py +257 -0
  213. catabolic-0.1.0/src/catabolic/interchange/v2.py +104 -0
  214. catabolic-0.1.0/src/catabolic/interchange/v3.py +85 -0
  215. catabolic-0.1.0/src/catabolic/interchange/validation.py +278 -0
  216. catabolic-0.1.0/src/catabolic/item_workflow.py +381 -0
  217. catabolic-0.1.0/src/catabolic/layouts.py +797 -0
  218. catabolic-0.1.0/src/catabolic/legacy_refresh_delivery.py +79 -0
  219. catabolic-0.1.0/src/catabolic/maintenance.py +634 -0
  220. catabolic-0.1.0/src/catabolic/manifest.py +567 -0
  221. catabolic-0.1.0/src/catabolic/media.py +124 -0
  222. catabolic-0.1.0/src/catabolic/media_catalog.py +218 -0
  223. catabolic-0.1.0/src/catabolic/migration.py +625 -0
  224. catabolic-0.1.0/src/catabolic/migrations/001_initial.sql +36 -0
  225. catabolic-0.1.0/src/catabolic/migrations/001_initial.sql.license +2 -0
  226. catabolic-0.1.0/src/catabolic/migrations/002_migration_history.sql +7 -0
  227. catabolic-0.1.0/src/catabolic/migrations/002_migration_history.sql.license +2 -0
  228. catabolic-0.1.0/src/catabolic/migrations/003_media_model.sql +35 -0
  229. catabolic-0.1.0/src/catabolic/migrations/003_media_model.sql.license +2 -0
  230. catabolic-0.1.0/src/catabolic/migrations/004_tags.sql +40 -0
  231. catabolic-0.1.0/src/catabolic/migrations/004_tags.sql.license +2 -0
  232. catabolic-0.1.0/src/catabolic/migrations/005_hardlinks.sql +20 -0
  233. catabolic-0.1.0/src/catabolic/migrations/005_hardlinks.sql.license +2 -0
  234. catabolic-0.1.0/src/catabolic/migrations/006_enrichment.sql +66 -0
  235. catabolic-0.1.0/src/catabolic/migrations/006_enrichment.sql.license +2 -0
  236. catabolic-0.1.0/src/catabolic/migrations/007_processing_attempts.sql +14 -0
  237. catabolic-0.1.0/src/catabolic/migrations/007_processing_attempts.sql.license +2 -0
  238. catabolic-0.1.0/src/catabolic/migrations/008_processing_artifacts.sql +32 -0
  239. catabolic-0.1.0/src/catabolic/migrations/008_processing_artifacts.sql.license +2 -0
  240. catabolic-0.1.0/src/catabolic/migrations/009_output_definitions.sql +30 -0
  241. catabolic-0.1.0/src/catabolic/migrations/009_output_definitions.sql.license +2 -0
  242. catabolic-0.1.0/src/catabolic/migrations/010_item_workflow.sql +38 -0
  243. catabolic-0.1.0/src/catabolic/migrations/010_item_workflow.sql.license +2 -0
  244. catabolic-0.1.0/src/catabolic/migrations/011_processing_rules.sql +24 -0
  245. catabolic-0.1.0/src/catabolic/migrations/011_processing_rules.sql.license +2 -0
  246. catabolic-0.1.0/src/catabolic/migrations/012_rendition_publication.sql +47 -0
  247. catabolic-0.1.0/src/catabolic/migrations/012_rendition_publication.sql.license +2 -0
  248. catabolic-0.1.0/src/catabolic/migrations/013_processor_workers.sql +31 -0
  249. catabolic-0.1.0/src/catabolic/migrations/013_processor_workers.sql.license +2 -0
  250. catabolic-0.1.0/src/catabolic/migrations/014_catalog_refresh.sql +16 -0
  251. catabolic-0.1.0/src/catabolic/migrations/014_catalog_refresh.sql.license +2 -0
  252. catabolic-0.1.0/src/catabolic/migrations/015_queries_projections.sql +37 -0
  253. catabolic-0.1.0/src/catabolic/migrations/015_queries_projections.sql.license +2 -0
  254. catabolic-0.1.0/src/catabolic/migrations/016_operation_rules.sql +43 -0
  255. catabolic-0.1.0/src/catabolic/migrations/016_operation_rules.sql.license +2 -0
  256. catabolic-0.1.0/src/catabolic/migrations/017_consumers.sql +87 -0
  257. catabolic-0.1.0/src/catabolic/migrations/017_consumers.sql.license +2 -0
  258. catabolic-0.1.0/src/catabolic/migrations/018_volume_identity.sql +21 -0
  259. catabolic-0.1.0/src/catabolic/migrations/018_volume_identity.sql.license +2 -0
  260. catabolic-0.1.0/src/catabolic/migrations/019_source_trust.sql +4 -0
  261. catabolic-0.1.0/src/catabolic/migrations/019_source_trust.sql.license +2 -0
  262. catabolic-0.1.0/src/catabolic/migrations/020_trust_evidence.sql +10 -0
  263. catabolic-0.1.0/src/catabolic/migrations/020_trust_evidence.sql.license +2 -0
  264. catabolic-0.1.0/src/catabolic/migrations/021_execution_claims.sql +16 -0
  265. catabolic-0.1.0/src/catabolic/migrations/021_execution_claims.sql.license +2 -0
  266. catabolic-0.1.0/src/catabolic/migrations/022_http_access.sql +34 -0
  267. catabolic-0.1.0/src/catabolic/migrations/022_http_access.sql.license +2 -0
  268. catabolic-0.1.0/src/catabolic/migrations/023_fallback_resolution.sql +324 -0
  269. catabolic-0.1.0/src/catabolic/migrations/023_fallback_resolution.sql.license +2 -0
  270. catabolic-0.1.0/src/catabolic/migrations/024_watchers.sql +38 -0
  271. catabolic-0.1.0/src/catabolic/migrations/024_watchers.sql.license +2 -0
  272. catabolic-0.1.0/src/catabolic/migrations/025_media_components.sql +45 -0
  273. catabolic-0.1.0/src/catabolic/migrations/025_media_components.sql.license +2 -0
  274. catabolic-0.1.0/src/catabolic/migrations/026_observation_requests.sql +10 -0
  275. catabolic-0.1.0/src/catabolic/migrations/026_observation_requests.sql.license +2 -0
  276. catabolic-0.1.0/src/catabolic/migrations/027_guarded_observations.sql +27 -0
  277. catabolic-0.1.0/src/catabolic/migrations/027_guarded_observations.sql.license +2 -0
  278. catabolic-0.1.0/src/catabolic/native_monitor.py +76 -0
  279. catabolic-0.1.0/src/catabolic/network_adapters.py +299 -0
  280. catabolic-0.1.0/src/catabolic/notification_worker.py +75 -0
  281. catabolic-0.1.0/src/catabolic/notifications.py +259 -0
  282. catabolic-0.1.0/src/catabolic/observations.py +893 -0
  283. catabolic-0.1.0/src/catabolic/operations.py +178 -0
  284. catabolic-0.1.0/src/catabolic/output_cli.py +109 -0
  285. catabolic-0.1.0/src/catabolic/outputs.py +315 -0
  286. catabolic-0.1.0/src/catabolic/plans.py +355 -0
  287. catabolic-0.1.0/src/catabolic/plex_import.py +407 -0
  288. catabolic-0.1.0/src/catabolic/plex_login.py +225 -0
  289. catabolic-0.1.0/src/catabolic/process_runner.py +113 -0
  290. catabolic-0.1.0/src/catabolic/processing.py +1070 -0
  291. catabolic-0.1.0/src/catabolic/processor_cli.py +115 -0
  292. catabolic-0.1.0/src/catabolic/processors.py +462 -0
  293. catabolic-0.1.0/src/catabolic/program_bundle.py +466 -0
  294. catabolic-0.1.0/src/catabolic/program_cli.py +221 -0
  295. catabolic-0.1.0/src/catabolic/program_contracts.py +108 -0
  296. catabolic-0.1.0/src/catabolic/projection_stats.py +251 -0
  297. catabolic-0.1.0/src/catabolic/projections.py +152 -0
  298. catabolic-0.1.0/src/catabolic/publication_lock.py +30 -0
  299. catabolic-0.1.0/src/catabolic/query.py +744 -0
  300. catabolic-0.1.0/src/catabolic/receipts.py +249 -0
  301. catabolic-0.1.0/src/catabolic/reconcile.py +856 -0
  302. catabolic-0.1.0/src/catabolic/remount.py +419 -0
  303. catabolic-0.1.0/src/catabolic/rendering.py +633 -0
  304. catabolic-0.1.0/src/catabolic/rendition_publication.py +348 -0
  305. catabolic-0.1.0/src/catabolic/rendition_requests.py +276 -0
  306. catabolic-0.1.0/src/catabolic/revision_evidence.py +19 -0
  307. catabolic-0.1.0/src/catabolic/rule_analysis.py +130 -0
  308. catabolic-0.1.0/src/catabolic/rule_cli.py +198 -0
  309. catabolic-0.1.0/src/catabolic/rule_estimates.py +185 -0
  310. catabolic-0.1.0/src/catabolic/rule_external.py +226 -0
  311. catabolic-0.1.0/src/catabolic/rules.py +893 -0
  312. catabolic-0.1.0/src/catabolic/saved_queries.py +351 -0
  313. catabolic-0.1.0/src/catabolic/scan_execution.py +541 -0
  314. catabolic-0.1.0/src/catabolic/scan_policy.py +111 -0
  315. catabolic-0.1.0/src/catabolic/scan_staging.py +55 -0
  316. catabolic-0.1.0/src/catabolic/scan_traversal.py +282 -0
  317. catabolic-0.1.0/src/catabolic/selection.py +427 -0
  318. catabolic-0.1.0/src/catabolic/source_access.py +77 -0
  319. catabolic-0.1.0/src/catabolic/source_events.py +31 -0
  320. catabolic-0.1.0/src/catabolic/source_trust.py +104 -0
  321. catabolic-0.1.0/src/catabolic/sql_query.py +721 -0
  322. catabolic-0.1.0/src/catabolic/store.py +158 -0
  323. catabolic-0.1.0/src/catabolic/supervisor.py +263 -0
  324. catabolic-0.1.0/src/catabolic/tagging.py +280 -0
  325. catabolic-0.1.0/src/catabolic/targets.py +353 -0
  326. catabolic-0.1.0/src/catabolic/volume_identity.py +60 -0
  327. catabolic-0.1.0/src/catabolic/watcher_cli.py +71 -0
  328. catabolic-0.1.0/src/catabolic/watcher_models.py +65 -0
  329. catabolic-0.1.0/src/catabolic/watcher_processing.py +91 -0
  330. catabolic-0.1.0/src/catabolic/watcher_schedule.py +68 -0
  331. catabolic-0.1.0/src/catabolic/watchers.py +439 -0
  332. catabolic-0.1.0/src/catabolic/watching.py +136 -0
  333. catabolic-0.1.0/src/catabolic/work_inbox.py +444 -0
  334. catabolic-0.1.0/src/catabolic/workflow_cli.py +116 -0
  335. catabolic-0.1.0/src/catabolic.egg-info/PKG-INFO +470 -0
  336. catabolic-0.1.0/src/catabolic.egg-info/SOURCES.txt +409 -0
  337. catabolic-0.1.0/src/catabolic.egg-info/dependency_links.txt +1 -0
  338. catabolic-0.1.0/src/catabolic.egg-info/entry_points.txt +2 -0
  339. catabolic-0.1.0/src/catabolic.egg-info/requires.txt +16 -0
  340. catabolic-0.1.0/src/catabolic.egg-info/top_level.txt +1 -0
  341. catabolic-0.1.0/tests/fixtures/experience/cases.json.license +2 -0
  342. catabolic-0.1.0/tests/fixtures/interchange/manifest-v1.json.license +2 -0
  343. catabolic-0.1.0/tests/test_application.py +778 -0
  344. catabolic-0.1.0/tests/test_artifacts.py +552 -0
  345. catabolic-0.1.0/tests/test_audit_fixes.py +364 -0
  346. catabolic-0.1.0/tests/test_catalog_refresh.py +290 -0
  347. catabolic-0.1.0/tests/test_component_lifecycle.py +264 -0
  348. catabolic-0.1.0/tests/test_component_media.py +496 -0
  349. catabolic-0.1.0/tests/test_component_migration.py +213 -0
  350. catabolic-0.1.0/tests/test_component_packages.py +315 -0
  351. catabolic-0.1.0/tests/test_components.py +263 -0
  352. catabolic-0.1.0/tests/test_consumer_publication.py +141 -0
  353. catabolic-0.1.0/tests/test_consumers.py +1021 -0
  354. catabolic-0.1.0/tests/test_distribution.py +97 -0
  355. catabolic-0.1.0/tests/test_document_text.py +266 -0
  356. catabolic-0.1.0/tests/test_documentation.py +86 -0
  357. catabolic-0.1.0/tests/test_enrichment.py +845 -0
  358. catabolic-0.1.0/tests/test_execution_claims.py +84 -0
  359. catabolic-0.1.0/tests/test_experience_acceptance.py +163 -0
  360. catabolic-0.1.0/tests/test_fallback_baseline.py +121 -0
  361. catabolic-0.1.0/tests/test_fallback_evidence.py +118 -0
  362. catabolic-0.1.0/tests/test_fallback_http.py +120 -0
  363. catabolic-0.1.0/tests/test_fallback_identity.py +187 -0
  364. catabolic-0.1.0/tests/test_fallback_lifecycle.py +158 -0
  365. catabolic-0.1.0/tests/test_fallback_processing.py +101 -0
  366. catabolic-0.1.0/tests/test_fallback_resolution.py +143 -0
  367. catabolic-0.1.0/tests/test_fallback_review.py +173 -0
  368. catabolic-0.1.0/tests/test_graphql_query.py +177 -0
  369. catabolic-0.1.0/tests/test_guarded_scans.py +598 -0
  370. catabolic-0.1.0/tests/test_hardlinks.py +513 -0
  371. catabolic-0.1.0/tests/test_http_backend.py +760 -0
  372. catabolic-0.1.0/tests/test_http_contract.py +262 -0
  373. catabolic-0.1.0/tests/test_http_renditions.py +327 -0
  374. catabolic-0.1.0/tests/test_http_review.py +293 -0
  375. catabolic-0.1.0/tests/test_interchange.py +268 -0
  376. catabolic-0.1.0/tests/test_item_workflow.py +296 -0
  377. catabolic-0.1.0/tests/test_layouts.py +451 -0
  378. catabolic-0.1.0/tests/test_maintenance.py +391 -0
  379. catabolic-0.1.0/tests/test_manifest.py +279 -0
  380. catabolic-0.1.0/tests/test_media_model.py +581 -0
  381. catabolic-0.1.0/tests/test_migrations.py +669 -0
  382. catabolic-0.1.0/tests/test_native_layout.py +175 -0
  383. catabolic-0.1.0/tests/test_native_processing.py +259 -0
  384. catabolic-0.1.0/tests/test_notifications.py +122 -0
  385. catabolic-0.1.0/tests/test_observation_service.py +562 -0
  386. catabolic-0.1.0/tests/test_outputs.py +317 -0
  387. catabolic-0.1.0/tests/test_plex_import.py +413 -0
  388. catabolic-0.1.0/tests/test_plex_login.py +264 -0
  389. catabolic-0.1.0/tests/test_processor_workers.py +223 -0
  390. catabolic-0.1.0/tests/test_program_bundle.py +307 -0
  391. catabolic-0.1.0/tests/test_programmable_catalog.py +561 -0
  392. catabolic-0.1.0/tests/test_programmable_migration.py +112 -0
  393. catabolic-0.1.0/tests/test_projection_stats.py +224 -0
  394. catabolic-0.1.0/tests/test_queries.py +434 -0
  395. catabolic-0.1.0/tests/test_query_layouts.py +399 -0
  396. catabolic-0.1.0/tests/test_release_safety.py +300 -0
  397. catabolic-0.1.0/tests/test_release_tooling.py +88 -0
  398. catabolic-0.1.0/tests/test_remount.py +375 -0
  399. catabolic-0.1.0/tests/test_rendition_workflows.py +407 -0
  400. catabolic-0.1.0/tests/test_rule_scale_calibration.py +162 -0
  401. catabolic-0.1.0/tests/test_rules.py +417 -0
  402. catabolic-0.1.0/tests/test_source_trust.py +261 -0
  403. catabolic-0.1.0/tests/test_sql_query.py +472 -0
  404. catabolic-0.1.0/tests/test_storage_acceptance.py +92 -0
  405. catabolic-0.1.0/tests/test_synthetic_library.py +54 -0
  406. catabolic-0.1.0/tests/test_tagging.py +416 -0
  407. catabolic-0.1.0/tests/test_targets.py +409 -0
  408. catabolic-0.1.0/tests/test_watcher_http.py +126 -0
  409. catabolic-0.1.0/tests/test_watcher_recovery.py +360 -0
  410. catabolic-0.1.0/tests/test_watchers.py +440 -0
  411. catabolic-0.1.0/tests/test_work_inbox.py +778 -0
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jaga Tranvo
4
+ Copyright (c) 2026 The Catabolic Contributors
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # SPDX-FileCopyrightText: 2026 The Catabolic Contributors
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ include LICENSE
5
+ recursive-include docs *.md
6
+ recursive-include tests *.license
@@ -0,0 +1,470 @@
1
+ Metadata-Version: 2.4
2
+ Name: catabolic
3
+ Version: 0.1.0
4
+ Summary: Programmable media catalog with query-driven rules and safe output projections
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/Jagalite/catabolic
7
+ Project-URL: Documentation, https://github.com/Jagalite/catabolic/wiki
8
+ Project-URL: Repository, https://github.com/Jagalite/catabolic
9
+ Project-URL: Issues, https://github.com/Jagalite/catabolic/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Operating System :: MacOS
12
+ Classifier: Operating System :: POSIX :: Linux
13
+ Classifier: Programming Language :: Python :: 3
14
+ Requires-Python: >=3.11
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: graphql-core==3.2.12
18
+ Requires-Dist: pydantic==2.13.5
19
+ Provides-Extra: watch
20
+ Requires-Dist: watchdog==6.0.0; extra == "watch"
21
+ Provides-Extra: http
22
+ Requires-Dist: fastapi==0.141.1; extra == "http"
23
+ Requires-Dist: uvicorn==0.52.4; extra == "http"
24
+ Provides-Extra: notifications
25
+ Requires-Dist: apprise==1.13.1; extra == "notifications"
26
+ Provides-Extra: dev
27
+ Requires-Dist: ruff==0.16.6; extra == "dev"
28
+ Requires-Dist: jsonschema==4.26.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # Catabolic
32
+
33
+ <!--
34
+ SPDX-FileCopyrightText: 2026 The Catabolic Contributors
35
+ SPDX-License-Identifier: MIT
36
+ -->
37
+
38
+ **A programmable media catalog.**
39
+
40
+ People and agents decide what belongs. Queries select catalog state. Rules
41
+ perform explicit processing and record results. Projections publish selected media
42
+ into maintained output structures. Consumer integrations connect those outputs
43
+ to applications; optional notifications tell people what happened.
44
+
45
+ Inventory media across drives and mounted storage, identify logical items, and
46
+ inspect their metadata, relationships, technical facts and processing evidence
47
+ with SQL or GraphQL. Save a reusable query, attach an operation rule or an output
48
+ projection, preview, execute a bounded batch, and verify the resulting state.
49
+
50
+ Completed processing becomes catalog evidence. A query for media missing a
51
+ rendition stops matching once that result is recorded. Different projections can
52
+ select different versions of the same item and maintain independent Plex,
53
+ Jellyfin, music or document layouts without changing original files. Durable jobs,
54
+ receipts and filesystem journals preserve recovery when work is interrupted.
55
+
56
+ Start with the [query → rule → projection guide](docs/PROGRAMMABLE_CATALOG.md),
57
+ including implemented operation types, compatibility and validation limits.
58
+
59
+ [Get started](https://github.com/Jagalite/catabolic/blob/main/docs/GETTING_STARTED.md) · [Documentation](https://github.com/Jagalite/catabolic/wiki) · [FAQ](https://github.com/Jagalite/catabolic/blob/main/docs/FAQ.md)
60
+
61
+ ## What can you do with it?
62
+
63
+ - **Bring your collection together.** Catalog media across several drives and
64
+ mounted storage locations, and search the recorded catalog while they're offline.
65
+ - **Organize it your way.** Add titles, identities, tags, and relationships to
66
+ movies, TV, music, books, audiobooks, comics, photos, documents, and more.
67
+ - **Track your cataloging work.** Use the [work inbox](docs/INBOX.md) to find
68
+ unidentified files, pending reviews, and processing or projection failures.
69
+ Keep an entry worklog, defer unresolved items, and check required work before
70
+ marking an entry complete.
71
+ - **Make collections from searches.** Save a selection, such as favorite films or
72
+ books by an author, and refresh it into a symlink folder when you choose.
73
+ - **Build symlink libraries for your apps.** Generate popular folder formats or
74
+ custom layouts from the same catalog, with links back to your source files.
75
+ - **Keep useful metadata alongside your media.** Export catalog details,
76
+ playlists, and metadata files for other tools.
77
+ - **Keep track of custom versions.** Catalog your own remuxes and edits, or use
78
+ optional FFmpeg recipes to generate separate files with recorded source relationships.
79
+ - **Generate previews and smaller versions with rules.** Apply a recipe to a
80
+ saved selection, backfill existing media, and include new matches during
81
+ maintenance. Preview the estimated additional storage before queuing work.
82
+ - **Give each library the versions it needs.** Publish a separate transcode
83
+ library, keep originals in another, and register results from external processors.
84
+ [Automatic catalog updates](docs/CATALOG_REFRESH.md) can add links when new
85
+ versions become ready, with durable retries for offline destinations.
86
+ - **Keep projections useful during storage outages.** [Fallback policies](docs/FALLBACK.md)
87
+ try saved candidate queries in order: originals, backup occurrences, then existing
88
+ renditions. Logical membership survives outages, and an explicitly enabled worker
89
+ performs recoverable symlink switches with stable failback.
90
+ - **Select audio and subtitles consistently.** [Media components](docs/COMPONENTS.md)
91
+ make embedded streams and external files queryable together, with explicit
92
+ compatibility and separate extraction/mux operations.
93
+ - **Coordinate network processing.** Submit work through a versioned HTTP receipt
94
+ adapter, with durable jobs and worker leases. Estimates learn from successful
95
+ local renders, and paged rules can select up to 100,000 IDs. See
96
+ [processor workflows](docs/PROCESSORS.md).
97
+
98
+ For example, the same film can appear in your Plex library and a favorites folder
99
+ without storing another copy of the movie. Each symlink points to the existing
100
+ file while giving it a name and location suited to that library. You can preview
101
+ the changes before applying them.
102
+
103
+ ## Build an application on the catalog
104
+
105
+ The optional [HTTP backend](docs/HTTP.md) exposes authorized GraphQL, operator SQL,
106
+ saved queries, metadata, revision-pinned content and durable rendition requests.
107
+ Scoped tokens can permit browser derivatives while denying originals. A separate
108
+ foreground worker prepares approved recipes; reusable short-lived tickets support
109
+ browser range requests. CLI and HTTP share jobs, artifacts and recovery.
110
+
111
+ Install the optional HTTP dependencies and configure grants/source exposure before
112
+ starting `catabolic --db catalog.db api serve`. The server defaults to loopback
113
+ and existing-content mode. Processing requires explicit enablement and a worker.
114
+ The [HTTP guide](docs/HTTP.md) records limits and current release qualification.
115
+ The [public developer contract](docs/HTTP.md#public-developer-contract) includes typed
116
+ responses, stable operation IDs, versioned OpenAPI/GraphQL artifacts and generated
117
+ TypeScript client acceptance tests.
118
+
119
+ ## Works with your media apps
120
+
121
+ Folder presets cover **Plex, Jellyfin, Emby, Kodi, Infuse, Navidrome,
122
+ Audiobookshelf, Komga, Kavita**, and other applications. Custom naming rules let
123
+ you build a different structure. There are also explicit import options for
124
+ calibre, Calibre-Web, and Immich.
125
+
126
+ See [supported applications](https://github.com/Jagalite/catabolic/blob/main/docs/COMPATIBILITY.md) for the full list and each
127
+ integration's requirements. Folder presets and import options behave differently;
128
+ imports copy or upload selected media.
129
+
130
+ ### Start from an existing Plex library
131
+
132
+ [Import Plex metadata](docs/CONSUMERS.md#import-an-existing-plex-library-into-catabolic)
133
+ to bootstrap file identification from your existing library. Connect your Plex
134
+ server, map its media paths to scanned Catabolic sources, then preview and apply
135
+ a bounded page. Imports preserve existing metadata, retain Plex identity and
136
+ provenance, and report ambiguous or unavailable files for review. They do not copy
137
+ media or change Plex. Movies, episode files, music tracks and photos are supported;
138
+ parent relationships, playlists and watched state are outside the import scope.
139
+
140
+ ### Connect published outputs to Plex or Jellyfin
141
+
142
+ [Consumer bindings](docs/CONSUMERS.md) connect a projection or media subtree to an
143
+ exact server and library identity. Configure a binding once: verified publication
144
+ then records durable scan generations and can automatically request library scans.
145
+ Unchanged output creates no new scan. Offline servers leave retryable delivery
146
+ work without rerendering completed media or rewriting unchanged links.
147
+
148
+ Plex supports browser sign-in, server/library discovery, existing-library binding,
149
+ explicit library creation, normal section scans and bounded file-path indexing checks. Jellyfin supports
150
+ existing-library bindings and scans; legacy refresh commands remain available.
151
+ Folder naming presets for other apps do not imply an API integration.
152
+
153
+ Scan acceptance and verified indexing are separate outcomes. Plex must be able
154
+ to read both published symlinks and their resolved targets. Protocol and recovery
155
+ fixtures are tested; live Plex acceptance remains unverified. See the
156
+ [validation record](docs/CONSUMER_VALIDATION.md) for evidence and limitations.
157
+
158
+ ## Install
159
+
160
+ Requires **Python 3.11+** on **macOS or Linux**.
161
+
162
+ ```sh
163
+ python3 -m venv ~/.venvs/catabolic
164
+ . ~/.venvs/catabolic/bin/activate
165
+ python -m pip install catabolic
166
+ catabolic --help
167
+ ```
168
+
169
+ Prefer pipx or want to install a specific version? See the
170
+ [installation guide](https://github.com/Jagalite/catabolic/blob/main/docs/INSTALLATION.md).
171
+
172
+ ## Try it without touching your library
173
+
174
+ The [getting started walkthrough](https://github.com/Jagalite/catabolic/blob/main/docs/GETTING_STARTED.md) creates a small sample
175
+ collection and walks through cataloging, tagging, and generating your first
176
+ folders. No media server, API key, or FFmpeg installation is needed.
177
+
178
+ Then add your own source locations, identify the files you want to organize,
179
+ choose an output format, and preview the result.
180
+
181
+ Catabolic is a command-line application and is currently **alpha**. Keep backups
182
+ and start with a small collection. Generated folders need access to their source
183
+ files; they are not independent backups.
184
+
185
+ ## Agentic Operator guide
186
+
187
+ People and agents use the same five workflows:
188
+
189
+ - **Discover and identify:** bind sources → scan → inspect the inbox → propose
190
+ identities and associations → review and accept proposals.
191
+ - **Curate and complete:** inspect requirements → resolve reviews through their
192
+ owning services → check readiness → mark curation complete. Missing required
193
+ evidence can bring an item back into needs_attention. See [worklogs and
194
+ requirements](docs/WORKLOG.md).
195
+ - **Publish libraries:** save queries and output layouts → preview → publish →
196
+ verify. Curation readiness and projection health are separate. See the
197
+ [query → rule → projection guide](docs/PROGRAMMABLE_CATALOG.md).
198
+ - **Process media:** choose an approved operation → admit jobs → run workers →
199
+ inspect generated artifacts and lineage → recover failures. See
200
+ [processing rules](docs/RULES.md) and [artifacts](docs/ARTIFACTS.md).
201
+ - **Maintain continuously:** configure and enable watchers → run the supervisor →
202
+ inspect reports, history and the inbox → address outstanding work. See
203
+ [watchers](docs/WATCHERS.md).
204
+
205
+ The daily loop is **scan or supervise → inbox summary → inbox list → inbox show
206
+ → existing operation → check again**. Start with the
207
+ [setup walkthrough](https://github.com/Jagalite/catabolic/wiki/Getting-Started)
208
+ to register sources and configure output catalogs and layouts. Then select your
209
+ database and profile for the commands below:
210
+
211
+ ```sh
212
+ export CATABOLIC_DB=/absolute/path/catalog.sqlite3
213
+ export CATABOLIC_PROFILE=default
214
+ catabolic db status
215
+ ```
216
+
217
+ If an upgrade is required, follow the
218
+ [migration guide](https://github.com/Jagalite/catabolic/wiki/Database-Migrations)
219
+ before continuing.
220
+
221
+ ### 1. Refresh evidence: manually or with watchers
222
+
223
+ Choose either entry path using the database/profile selected above.
224
+
225
+ For a manual refresh:
226
+
227
+ ```sh
228
+ catabolic scan
229
+ ```
230
+
231
+ Scans publish discoveries in guarded batches and report unfinished directories.
232
+ Use `scan --continue-request REQUEST_ID --extended` to continue outstanding work;
233
+ see [guarded observation policies and coverage](docs/OBSERVATIONS.md#guarded-discovery-and-continuation-schema-27).
234
+
235
+ For scheduled refreshes, [configure a watcher once](#configure-a-watcher-once),
236
+ then keep its supervisor running:
237
+
238
+ ```sh
239
+ catabolic supervise
240
+ ```
241
+
242
+ `supervise` runs continuously in the foreground; `supervise --once` handles one
243
+ pass. Watchers may refresh source observations when their plans require it.
244
+ Check scan or watcher results for incomplete evidence. Both paths lead to the
245
+ same inbox steps below; with a foreground supervisor, use another terminal with
246
+ the same database/profile.
247
+
248
+ ### 2. Inspect the inbox
249
+
250
+ ```sh
251
+ catabolic --json inbox summary
252
+ catabolic --json inbox list --limit 100
253
+ catabolic --json inbox show WORK_KEY
254
+ ```
255
+
256
+ Replace `WORK_KEY` with a key returned by `list`. Detail explains why the work
257
+ appears, which record owns it, and which existing operation addresses it. Follow
258
+ `next_cursor` with `inbox list --after CURSOR`; `--include-inactive` includes
259
+ waiting, deferred and historical entries. Reads use recorded evidence and do not
260
+ scan or complete work. An empty actionable inbox does not prove curation finished.
261
+ See the [inbox guide](docs/INBOX.md) for query examples and completion reporting.
262
+
263
+ ### 3. Act through the owning service, then check again
264
+
265
+ Use the entry's suggested operation after reloading its owner and checking current
266
+ eligibility and preconditions. Suggestions describe work; they do not authorize it.
267
+ Review identities, associations and tags through the proposal workflow, resolve
268
+ explicit reviews through requirement operations, and record decisions in each
269
+ entry's worklog. The
270
+ [recommended workflow](https://github.com/Jagalite/catabolic/wiki/Recommended-Workflow)
271
+ covers curation, completion checks, and the first preview/apply/sync/verify cycle
272
+ for your symlink folders.
273
+
274
+ After acting, return to **step 2** to check recorded results. Return to **step 1**
275
+ when evidence needs refreshing. Keep checking even without new notifications:
276
+ previously outstanding work remains discoverable until its owner resolves it.
277
+
278
+ ### Configure a watcher once
279
+
280
+ For scanning alone, use an [observation-only watcher](docs/OBSERVATIONS.md):
281
+ `{"plan":{"kind":"observation","sources":["media"]},"schedule":{"kind":"interval","seconds":3600}}`.
282
+ It schedules the same one-shot operation as `scan`, with no query or reaction.
283
+ `supervise --once` processes eligible watcher work; it does not mean “scan all sources once.”
284
+
285
+ For a query report as well as observation, use the configuration below.
286
+
287
+ Save an inbox query using the [inbox query examples](docs/INBOX.md#queries-and-watchers),
288
+ then put its immutable query revision ID in `inbox-watcher.json`:
289
+
290
+ ```json
291
+ {
292
+ "version": 1,
293
+ "authority": "local_owner",
294
+ "plan": {"kind": "query", "query_id": "IMMUTABLE_QUERY_REVISION"},
295
+ "schedule": {"kind": "interval", "seconds": 3600},
296
+ "max_age_seconds": 300,
297
+ "reaction": "report"
298
+ }
299
+ ```
300
+
301
+ Using the database/profile selected above:
302
+
303
+ ```sh
304
+ catabolic watcher put inbox-audit --file inbox-watcher.json
305
+ catabolic watcher preview inbox-audit
306
+ catabolic watcher enable inbox-audit
307
+ catabolic watcher run inbox-audit
308
+ ```
309
+
310
+ Continue with the supervisor entry path in **step 1**, then use the shared inbox
311
+ flow in **steps 2–3**. This report watcher does not perform suggested inbox actions
312
+ or launch an agent. To inspect watcher scheduling and failures:
313
+
314
+ ```sh
315
+ catabolic watcher pending
316
+ catabolic watcher history inbox-audit
317
+ ```
318
+
319
+ The [watcher guide](docs/WATCHERS.md) covers schedules,
320
+ events and recovery. For watcher-owned projections, use `watcher run` for repair
321
+ or inventory-only maintenance; legacy maintenance does not reconcile those outputs.
322
+
323
+ ### Run routine maintenance
324
+
325
+ Once your output layouts are configured:
326
+
327
+ ```sh
328
+ # Scan sources, refresh output links, verify them, and update metadata manifests.
329
+ catabolic maintenance --all-catalogs --manifest
330
+
331
+ # Or scan and report the backlog without updating output folders.
332
+ catabolic --json maintenance --inventory-only
333
+ ```
334
+
335
+ The report includes new files, uncataloged files, entry statuses and unfinished
336
+ jobs. Maintenance defaults to zero output removals; it does not identify media
337
+ or mark entries complete. See the
338
+ [maintenance guide](https://github.com/Jagalite/catabolic/wiki/Maintenance)
339
+ for scan exclusions, budgets, optional analysis and handling incomplete cycles.
340
+
341
+ ### Backfill previews or transcodes
342
+
343
+ Follow the [processing rules guide](https://github.com/Jagalite/catabolic/wiki/Processing-Rules)
344
+ to collect probe metadata and save a recipe, selection and generated destination.
345
+ Replace `RULE_ID` with the saved rule's ID, then review its full storage estimate:
346
+
347
+ ```sh
348
+ catabolic rule preview RULE_ID
349
+ # Queue up to 10 outputs with a 10 GiB estimated planning budget.
350
+ catabolic rule apply RULE_ID --batch 10 --max-new-bytes 10737418240
351
+ catabolic rule run RULE_ID --batch 1
352
+ ```
353
+
354
+ Estimates show additional space, a likely range and any unknown sizes; they are
355
+ not guaranteed output sizes. Rendering requires an external FFmpeg installation
356
+ and creates separate files, preserving originals. After reviewing a rule, opt it
357
+ into future maintenance cycles:
358
+
359
+ ```sh
360
+ catabolic rule enable RULE_ID
361
+ catabolic maintenance --all-catalogs --rules --rule-batch 10 --render-rules 1
362
+ ```
363
+
364
+ `--rules` queues enabled rules; `--render-rules 1` also renders at most one job.
365
+ Ordinary maintenance does neither. For agents and scheduled runs, use global
366
+ `--json` and check exit codes; see [automation](https://github.com/Jagalite/catabolic/wiki/Automation).
367
+
368
+ ### Set up delivery once
369
+
370
+ Start with a configured projection named `cinema` that publishes movie links
371
+ under `Movies`. Use the database/profile selected above. Sign in with Plex, open
372
+ the returned `authorization_url`, then complete the login with its `login_id`:
373
+
374
+ ```sh
375
+ catabolic consumer plex-login
376
+ catabolic consumer plex-login-complete LOGIN_ID
377
+ ```
378
+
379
+ Completion returns a private `credential_file` path without printing the token.
380
+ Replace the example endpoint with your Plex server address and `CREDENTIAL_FILE`
381
+ with that path. Login does not discover the server address automatically.
382
+
383
+ ```sh
384
+ catabolic consumer connection-put home --application plex \
385
+ --endpoint https://plex.example.test:32400 --credential-file CREDENTIAL_FILE --apply
386
+ catabolic consumer discover home --type movie
387
+ ```
388
+
389
+ If discovery reports library `7` rooted at `/media/Movies`, preview and then save
390
+ the binding. The remote root is the path **as Plex sees it**, which may differ
391
+ from the host's output path. Plex also needs access to the symlinks' targets.
392
+
393
+ ```sh
394
+ catabolic consumer bind cinema-plex --connection home --catalog cinema \
395
+ --subtree Movies --remote-root /media/Movies --library-id 7 --type movie \
396
+ --automatic --initial-scan
397
+ catabolic consumer bind cinema-plex --connection home --catalog cinema \
398
+ --subtree Movies --remote-root /media/Movies --library-id 7 --type movie \
399
+ --automatic --initial-scan --apply
400
+ catabolic projection execute cinema
401
+ catabolic consumer run --limit 10
402
+ catabolic consumer bindings
403
+ catabolic consumer verify-indexing cinema-plex --limit 100
404
+ ```
405
+
406
+ `--initial-scan` schedules existing published files; `--automatic` enables delivery
407
+ after future publication. A saved binding alone does not start a worker. Scan
408
+ acceptance means Plex accepted the request; `verify-indexing` separately reports
409
+ whether expected paths were found and may be inconclusive while indexing or in a
410
+ large library. An output catalog without a saved projection can use `sync` and
411
+ `verify` instead; see the [consumer guide](docs/CONSUMERS.md).
412
+
413
+ For SSH, open the sign-in link on another device. Scheduled workers need access
414
+ to the same credential file. An existing token can instead be supplied through
415
+ protected configuration with `--credential-env PLEX_TOKEN`; see
416
+ [sign-in and credential setup](docs/CONSUMERS.md#sign-in-with-plex).
417
+
418
+ Publication performs a bounded delivery drain when automatic delivery is enabled.
419
+ Schedule `catabolic consumer run --limit 10` for delayed retries, or supervise
420
+ `catabolic consumer watch --interval 30`. The CLI does not start a background
421
+ service. Inspect `consumer attempts` and `consumer events` for separate outcomes.
422
+
423
+ The [consumer guide](docs/CONSUMERS.md) covers explicit library creation, path
424
+ mapping, repair and optional Apprise subscriptions. Apprise is installed separately
425
+ with the `notifications` extra; its per-destination retries are independent of
426
+ scan delivery. Preview and apply any required database upgrade before setup;
427
+ the current schema is 20. Upgrading does not enable automatic network actions.
428
+
429
+ ## Publishing a release
430
+
431
+ Keep the version in `pyproject.toml` and `src/catabolic/__init__.py` identical,
432
+ then create and push a matching `vVERSION` tag on the release commit. Pushing a
433
+ version tag runs the release validation workflow; publication requires a separate
434
+ manual request after configuring PyPI Trusted Publishing.
435
+
436
+ For example, to publish version `0.1.0` from its matching tag:
437
+
438
+ ```sh
439
+ gh workflow run release.yml --ref v0.1.0 -f publish=true
440
+ ```
441
+
442
+ The workflow runs all CI checks before uploading the tested wheel and source
443
+ archive to PyPI. It uses the `pypi` GitHub environment and Trusted Publishing;
444
+ no stored API token is required. Configure the PyPI publisher for `Jagalite`,
445
+ repository `catabolic`, workflow `release.yml`, and environment `pypi`.
446
+ Any configured environment approval is still required. Ordinary branch pushes
447
+ never publish. See [release setup and validation](docs/RELEASE_TESTING.md#pypi-trusted-publishing)
448
+ for first-publication setup and recovery after an interrupted upload.
449
+
450
+ ## Learn more
451
+
452
+ - [Wiki](https://github.com/Jagalite/catabolic/wiki) — walkthroughs and detailed guides.
453
+ - [Recommended workflow](https://github.com/Jagalite/catabolic/blob/main/docs/WORKFLOW.md) — the everyday cataloging cycle; also `catabolic docs workflow`.
454
+ - [Processing rules](https://github.com/Jagalite/catabolic/wiki/Processing-Rules) — recipes, retroactive storage estimates and maintenance; also `catabolic docs rules`.
455
+ - [Output consumers](docs/CONSUMERS.md) — Plex/Jellyfin setup, durable scan delivery and optional notifications; also `catabolic docs consumers`.
456
+ - [Rendition workflows](https://github.com/Jagalite/catabolic/wiki/Rendition-Workflows) — transcode libraries, external result receipts and completion requirements.
457
+ - [Using Catabolic with agents](https://github.com/Jagalite/catabolic/blob/main/docs/AUTOMATION.md) — automation and structured output.
458
+ - [SQL queries](https://github.com/Jagalite/catabolic/blob/main/docs/QUERYING.md) and [GraphQL](https://github.com/Jagalite/catabolic/blob/main/docs/GRAPHQL.md) — explore the catalog.
459
+ - [Troubleshooting](https://github.com/Jagalite/catabolic/blob/main/docs/TROUBLESHOOTING.md) — common questions and recovery steps.
460
+ - [Development](https://github.com/Jagalite/catabolic/blob/main/docs/DEVELOPMENT.md) — contribute, run tests, and maintain the docs.
461
+
462
+ Documentation is also available offline: run `catabolic docs` after installation.
463
+
464
+ ## License
465
+
466
+ [MIT](https://github.com/Jagalite/catabolic/blob/main/LICENSE). Copyright 2026 Jaga Tranvo and The Catabolic Contributors.
467
+
468
+ Owner-controlled source identity settings and their evidence are described in [Trust policies](docs/TRUST_POLICIES.md), also available with `catabolic docs trust`.
469
+
470
+ Named query watchers share source observations while maintaining independent schedules and projection ownership. See [the watcher guide](docs/WATCHERS.md).