krons 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 (204) hide show
  1. krons-0.1.0/.github/workflows/release.yml +65 -0
  2. krons-0.1.0/.gitignore +207 -0
  3. krons-0.1.0/.python-version +1 -0
  4. krons-0.1.0/CLAUDE.md +285 -0
  5. krons-0.1.0/LICENSE +201 -0
  6. krons-0.1.0/PKG-INFO +70 -0
  7. krons-0.1.0/README.md +43 -0
  8. krons-0.1.0/pyproject.toml +61 -0
  9. krons-0.1.0/src/kronos/__init__.py +0 -0
  10. krons-0.1.0/src/kronos/core/__init__.py +145 -0
  11. krons-0.1.0/src/kronos/core/broadcaster.py +116 -0
  12. krons-0.1.0/src/kronos/core/element.py +225 -0
  13. krons-0.1.0/src/kronos/core/event.py +316 -0
  14. krons-0.1.0/src/kronos/core/eventbus.py +116 -0
  15. krons-0.1.0/src/kronos/core/flow.py +356 -0
  16. krons-0.1.0/src/kronos/core/graph.py +442 -0
  17. krons-0.1.0/src/kronos/core/node.py +982 -0
  18. krons-0.1.0/src/kronos/core/pile.py +575 -0
  19. krons-0.1.0/src/kronos/core/processor.py +494 -0
  20. krons-0.1.0/src/kronos/core/progression.py +296 -0
  21. krons-0.1.0/src/kronos/enforcement/__init__.py +57 -0
  22. krons-0.1.0/src/kronos/enforcement/common/__init__.py +34 -0
  23. krons-0.1.0/src/kronos/enforcement/common/boolean.py +85 -0
  24. krons-0.1.0/src/kronos/enforcement/common/choice.py +97 -0
  25. krons-0.1.0/src/kronos/enforcement/common/mapping.py +118 -0
  26. krons-0.1.0/src/kronos/enforcement/common/model.py +102 -0
  27. krons-0.1.0/src/kronos/enforcement/common/number.py +98 -0
  28. krons-0.1.0/src/kronos/enforcement/common/string.py +140 -0
  29. krons-0.1.0/src/kronos/enforcement/context.py +129 -0
  30. krons-0.1.0/src/kronos/enforcement/policy.py +80 -0
  31. krons-0.1.0/src/kronos/enforcement/registry.py +153 -0
  32. krons-0.1.0/src/kronos/enforcement/rule.py +312 -0
  33. krons-0.1.0/src/kronos/enforcement/service.py +370 -0
  34. krons-0.1.0/src/kronos/enforcement/validator.py +198 -0
  35. krons-0.1.0/src/kronos/errors.py +146 -0
  36. krons-0.1.0/src/kronos/operations/__init__.py +32 -0
  37. krons-0.1.0/src/kronos/operations/builder.py +228 -0
  38. krons-0.1.0/src/kronos/operations/flow.py +398 -0
  39. krons-0.1.0/src/kronos/operations/node.py +101 -0
  40. krons-0.1.0/src/kronos/operations/registry.py +92 -0
  41. krons-0.1.0/src/kronos/protocols.py +414 -0
  42. krons-0.1.0/src/kronos/py.typed +0 -0
  43. krons-0.1.0/src/kronos/services/__init__.py +81 -0
  44. krons-0.1.0/src/kronos/services/backend.py +286 -0
  45. krons-0.1.0/src/kronos/services/endpoint.py +608 -0
  46. krons-0.1.0/src/kronos/services/hook.py +471 -0
  47. krons-0.1.0/src/kronos/services/imodel.py +465 -0
  48. krons-0.1.0/src/kronos/services/registry.py +115 -0
  49. krons-0.1.0/src/kronos/services/utilities/__init__.py +36 -0
  50. krons-0.1.0/src/kronos/services/utilities/header_factory.py +87 -0
  51. krons-0.1.0/src/kronos/services/utilities/rate_limited_executor.py +271 -0
  52. krons-0.1.0/src/kronos/services/utilities/rate_limiter.py +180 -0
  53. krons-0.1.0/src/kronos/services/utilities/resilience.py +414 -0
  54. krons-0.1.0/src/kronos/session/__init__.py +41 -0
  55. krons-0.1.0/src/kronos/session/exchange.py +258 -0
  56. krons-0.1.0/src/kronos/session/message.py +60 -0
  57. krons-0.1.0/src/kronos/session/session.py +411 -0
  58. krons-0.1.0/src/kronos/specs/__init__.py +25 -0
  59. krons-0.1.0/src/kronos/specs/adapters/__init__.py +0 -0
  60. krons-0.1.0/src/kronos/specs/adapters/_utils.py +45 -0
  61. krons-0.1.0/src/kronos/specs/adapters/dataclass_field.py +246 -0
  62. krons-0.1.0/src/kronos/specs/adapters/factory.py +56 -0
  63. krons-0.1.0/src/kronos/specs/adapters/pydantic_adapter.py +309 -0
  64. krons-0.1.0/src/kronos/specs/adapters/sql_ddl.py +946 -0
  65. krons-0.1.0/src/kronos/specs/catalog/__init__.py +36 -0
  66. krons-0.1.0/src/kronos/specs/catalog/_audit.py +39 -0
  67. krons-0.1.0/src/kronos/specs/catalog/_common.py +43 -0
  68. krons-0.1.0/src/kronos/specs/catalog/_content.py +59 -0
  69. krons-0.1.0/src/kronos/specs/catalog/_enforcement.py +70 -0
  70. krons-0.1.0/src/kronos/specs/factory.py +120 -0
  71. krons-0.1.0/src/kronos/specs/operable.py +314 -0
  72. krons-0.1.0/src/kronos/specs/phrase.py +405 -0
  73. krons-0.1.0/src/kronos/specs/protocol.py +140 -0
  74. krons-0.1.0/src/kronos/specs/spec.py +506 -0
  75. krons-0.1.0/src/kronos/types/__init__.py +60 -0
  76. krons-0.1.0/src/kronos/types/_sentinel.py +311 -0
  77. krons-0.1.0/src/kronos/types/base.py +369 -0
  78. krons-0.1.0/src/kronos/types/db_types.py +260 -0
  79. krons-0.1.0/src/kronos/types/identity.py +66 -0
  80. krons-0.1.0/src/kronos/utils/__init__.py +40 -0
  81. krons-0.1.0/src/kronos/utils/_hash.py +234 -0
  82. krons-0.1.0/src/kronos/utils/_json_dump.py +392 -0
  83. krons-0.1.0/src/kronos/utils/_lazy_init.py +63 -0
  84. krons-0.1.0/src/kronos/utils/_to_list.py +165 -0
  85. krons-0.1.0/src/kronos/utils/_to_num.py +85 -0
  86. krons-0.1.0/src/kronos/utils/_utils.py +375 -0
  87. krons-0.1.0/src/kronos/utils/concurrency/__init__.py +205 -0
  88. krons-0.1.0/src/kronos/utils/concurrency/_async_call.py +333 -0
  89. krons-0.1.0/src/kronos/utils/concurrency/_cancel.py +122 -0
  90. krons-0.1.0/src/kronos/utils/concurrency/_errors.py +96 -0
  91. krons-0.1.0/src/kronos/utils/concurrency/_patterns.py +363 -0
  92. krons-0.1.0/src/kronos/utils/concurrency/_primitives.py +328 -0
  93. krons-0.1.0/src/kronos/utils/concurrency/_priority_queue.py +135 -0
  94. krons-0.1.0/src/kronos/utils/concurrency/_resource_tracker.py +110 -0
  95. krons-0.1.0/src/kronos/utils/concurrency/_run_async.py +67 -0
  96. krons-0.1.0/src/kronos/utils/concurrency/_task.py +95 -0
  97. krons-0.1.0/src/kronos/utils/concurrency/_utils.py +79 -0
  98. krons-0.1.0/src/kronos/utils/fuzzy/__init__.py +14 -0
  99. krons-0.1.0/src/kronos/utils/fuzzy/_extract_json.py +90 -0
  100. krons-0.1.0/src/kronos/utils/fuzzy/_fuzzy_json.py +288 -0
  101. krons-0.1.0/src/kronos/utils/fuzzy/_fuzzy_match.py +149 -0
  102. krons-0.1.0/src/kronos/utils/fuzzy/_string_similarity.py +187 -0
  103. krons-0.1.0/src/kronos/utils/fuzzy/_to_dict.py +396 -0
  104. krons-0.1.0/src/kronos/utils/sql/__init__.py +13 -0
  105. krons-0.1.0/src/kronos/utils/sql/_sql_validation.py +142 -0
  106. krons-0.1.0/tests/__init__.py +2 -0
  107. krons-0.1.0/tests/conftest.py +390 -0
  108. krons-0.1.0/tests/core/__init__.py +2 -0
  109. krons-0.1.0/tests/core/test_broadcaster.py +449 -0
  110. krons-0.1.0/tests/core/test_element.py +181 -0
  111. krons-0.1.0/tests/core/test_error_paths.py +154 -0
  112. krons-0.1.0/tests/core/test_event.py +185 -0
  113. krons-0.1.0/tests/core/test_event_status_race.py +383 -0
  114. krons-0.1.0/tests/core/test_eventbus.py +810 -0
  115. krons-0.1.0/tests/core/test_flow.py +241 -0
  116. krons-0.1.0/tests/core/test_flow_edge_cases.py +164 -0
  117. krons-0.1.0/tests/core/test_graph.py +315 -0
  118. krons-0.1.0/tests/core/test_graph_event_loop.py +380 -0
  119. krons-0.1.0/tests/core/test_node.py +533 -0
  120. krons-0.1.0/tests/core/test_pile.py +315 -0
  121. krons-0.1.0/tests/core/test_pile_edge_cases.py +187 -0
  122. krons-0.1.0/tests/core/test_processor.py +234 -0
  123. krons-0.1.0/tests/core/test_processor_security.py +811 -0
  124. krons-0.1.0/tests/core/test_progression.py +297 -0
  125. krons-0.1.0/tests/core/test_progression_edge_cases.py +126 -0
  126. krons-0.1.0/tests/core/test_serialization_roundtrip.py +920 -0
  127. krons-0.1.0/tests/core/test_thread_safety_stress.py +221 -0
  128. krons-0.1.0/tests/enforcement/__init__.py +2 -0
  129. krons-0.1.0/tests/enforcement/test_service.py +595 -0
  130. krons-0.1.0/tests/operations/__init__.py +2 -0
  131. krons-0.1.0/tests/operations/test_builder.py +417 -0
  132. krons-0.1.0/tests/operations/test_flow.py +519 -0
  133. krons-0.1.0/tests/operations/test_node.py +190 -0
  134. krons-0.1.0/tests/operations/test_op_flow.py +1042 -0
  135. krons-0.1.0/tests/operations/test_op_node.py +159 -0
  136. krons-0.1.0/tests/operations/test_registry.py +237 -0
  137. krons-0.1.0/tests/rules/__init__.py +2 -0
  138. krons-0.1.0/tests/rules/test_base.py +342 -0
  139. krons-0.1.0/tests/rules/test_builtin.py +429 -0
  140. krons-0.1.0/tests/rules/test_registry.py +299 -0
  141. krons-0.1.0/tests/rules/test_rule_params_edge_cases.py +71 -0
  142. krons-0.1.0/tests/rules/test_rules_comprehensive.py +892 -0
  143. krons-0.1.0/tests/rules/test_validator.py +406 -0
  144. krons-0.1.0/tests/services/__init__.py +2 -0
  145. krons-0.1.0/tests/services/test_backend.py +374 -0
  146. krons-0.1.0/tests/services/test_endpoint.py +864 -0
  147. krons-0.1.0/tests/services/test_hook.py +995 -0
  148. krons-0.1.0/tests/services/test_imodel.py +541 -0
  149. krons-0.1.0/tests/services/test_registry.py +334 -0
  150. krons-0.1.0/tests/services/utilities/__init__.py +2 -0
  151. krons-0.1.0/tests/services/utilities/test_header_factory.py +160 -0
  152. krons-0.1.0/tests/services/utilities/test_rate_limiter.py +387 -0
  153. krons-0.1.0/tests/services/utilities/test_resilience.py +713 -0
  154. krons-0.1.0/tests/services/utilities/test_resilience_retry.py +292 -0
  155. krons-0.1.0/tests/session/__init__.py +2 -0
  156. krons-0.1.0/tests/session/test_exchange.py +428 -0
  157. krons-0.1.0/tests/session/test_message.py +167 -0
  158. krons-0.1.0/tests/session/test_message_edge_cases.py +321 -0
  159. krons-0.1.0/tests/session/test_session.py +407 -0
  160. krons-0.1.0/tests/session/test_session_edge_cases.py +610 -0
  161. krons-0.1.0/tests/specs/__init__.py +0 -0
  162. krons-0.1.0/tests/specs/test_catalog.py +346 -0
  163. krons-0.1.0/tests/specs/test_factory.py +227 -0
  164. krons-0.1.0/tests/specs/test_phrase.py +633 -0
  165. krons-0.1.0/tests/test_protocols.py +402 -0
  166. krons-0.1.0/tests/types/__init__.py +2 -0
  167. krons-0.1.0/tests/types/conftest.py +202 -0
  168. krons-0.1.0/tests/types/spec_adapters/__init__.py +2 -0
  169. krons-0.1.0/tests/types/spec_adapters/test_adapters_py311.py +421 -0
  170. krons-0.1.0/tests/types/spec_adapters/test_protocol.py +192 -0
  171. krons-0.1.0/tests/types/spec_adapters/test_pydantic_field.py +379 -0
  172. krons-0.1.0/tests/types/spec_adapters/test_sql_ddl_specs.py +442 -0
  173. krons-0.1.0/tests/types/test_db_types.py +238 -0
  174. krons-0.1.0/tests/types/test_identity.py +101 -0
  175. krons-0.1.0/tests/types/test_model.py +390 -0
  176. krons-0.1.0/tests/types/test_operable.py +413 -0
  177. krons-0.1.0/tests/types/test_sentinel.py +234 -0
  178. krons-0.1.0/tests/types/test_spec.py +645 -0
  179. krons-0.1.0/tests/types/test_types.py +950 -0
  180. krons-0.1.0/tests/types/test_types_py311.py +374 -0
  181. krons-0.1.0/tests/utils/__init__.py +2 -0
  182. krons-0.1.0/tests/utils/concurrency/__init__.py +2 -0
  183. krons-0.1.0/tests/utils/concurrency/test_async_call.py +133 -0
  184. krons-0.1.0/tests/utils/concurrency/test_cancel.py +233 -0
  185. krons-0.1.0/tests/utils/concurrency/test_errors.py +156 -0
  186. krons-0.1.0/tests/utils/concurrency/test_patterns.py +509 -0
  187. krons-0.1.0/tests/utils/concurrency/test_primitives.py +697 -0
  188. krons-0.1.0/tests/utils/concurrency/test_priority_queue.py +392 -0
  189. krons-0.1.0/tests/utils/concurrency/test_run_async.py +199 -0
  190. krons-0.1.0/tests/utils/concurrency/test_task.py +103 -0
  191. krons-0.1.0/tests/utils/concurrency/test_utils.py +278 -0
  192. krons-0.1.0/tests/utils/test_extract_json.py +215 -0
  193. krons-0.1.0/tests/utils/test_fuzzy_json.py +256 -0
  194. krons-0.1.0/tests/utils/test_fuzzy_match.py +235 -0
  195. krons-0.1.0/tests/utils/test_hash.py +300 -0
  196. krons-0.1.0/tests/utils/test_json_dump.py +715 -0
  197. krons-0.1.0/tests/utils/test_lazy_init.py +148 -0
  198. krons-0.1.0/tests/utils/test_sql_validation.py +128 -0
  199. krons-0.1.0/tests/utils/test_string_similarity.py +189 -0
  200. krons-0.1.0/tests/utils/test_to_dict.py +350 -0
  201. krons-0.1.0/tests/utils/test_to_list.py +355 -0
  202. krons-0.1.0/tests/utils/test_to_num.py +277 -0
  203. krons-0.1.0/tests/utils/test_utils.py +396 -0
  204. krons-0.1.0/uv.lock +641 -0
@@ -0,0 +1,65 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ python-version: ['3.11', '3.12', '3.13', '3.14']
16
+ steps:
17
+ - uses: actions/checkout@v5
18
+ - name: Set up Python ${{ matrix.python-version }}
19
+ uses: actions/setup-python@v6
20
+ with:
21
+ python-version: ${{ matrix.python-version }}
22
+
23
+ - name: Install uv
24
+ run: |
25
+ curl -LsSf https://astral.sh/uv/install.sh | sh
26
+ echo "$HOME/.cargo/bin" >> $GITHUB_PATH
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ uv venv
31
+ uv sync --all-extras
32
+
33
+ - name: Run tests
34
+ run: |
35
+ source .venv/bin/activate
36
+ uv run pytest --asyncio-mode=auto --maxfail=1 --disable-warnings tests/
37
+
38
+ deploy:
39
+ needs: test
40
+ runs-on: ubuntu-latest
41
+ steps:
42
+ - uses: actions/checkout@v5
43
+ - name: Set up Python
44
+ uses: actions/setup-python@v6
45
+ with:
46
+ python-version: "3.12"
47
+
48
+ - name: Install uv
49
+ run: |
50
+ curl -LsSf https://astral.sh/uv/install.sh | sh
51
+ echo "$HOME/.cargo/bin" >> $GITHUB_PATH
52
+
53
+ - name: Install dependencies
54
+ run: |
55
+ uv venv
56
+ uv pip install twine
57
+
58
+ - name: Build package
59
+ run: uv build
60
+
61
+ - name: Publish package to PyPI
62
+ env:
63
+ TWINE_USERNAME: __token__
64
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_KEY }}
65
+ run: uv run twine upload dist/*
krons-0.1.0/.gitignore ADDED
@@ -0,0 +1,207 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py.cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # UV
98
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ #uv.lock
102
+
103
+ # poetry
104
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
106
+ # commonly ignored for libraries.
107
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
+ #poetry.lock
109
+ #poetry.toml
110
+
111
+ # pdm
112
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
+ #pdm.lock
116
+ #pdm.toml
117
+ .pdm-python
118
+ .pdm-build/
119
+
120
+ # pixi
121
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
+ #pixi.lock
123
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
+ # in the .venv directory. It is recommended not to include this directory in version control.
125
+ .pixi
126
+
127
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
+ __pypackages__/
129
+
130
+ # Celery stuff
131
+ celerybeat-schedule
132
+ celerybeat.pid
133
+
134
+ # SageMath parsed files
135
+ *.sage.py
136
+
137
+ # Environments
138
+ .env
139
+ .envrc
140
+ .venv
141
+ env/
142
+ venv/
143
+ ENV/
144
+ env.bak/
145
+ venv.bak/
146
+
147
+ # Spyder project settings
148
+ .spyderproject
149
+ .spyproject
150
+
151
+ # Rope project settings
152
+ .ropeproject
153
+
154
+ # mkdocs documentation
155
+ /site
156
+
157
+ # mypy
158
+ .mypy_cache/
159
+ .dmypy.json
160
+ dmypy.json
161
+
162
+ # Pyre type checker
163
+ .pyre/
164
+
165
+ # pytype static type analyzer
166
+ .pytype/
167
+
168
+ # Cython debug symbols
169
+ cython_debug/
170
+
171
+ # PyCharm
172
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
175
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
+ #.idea/
177
+
178
+ # Abstra
179
+ # Abstra is an AI-powered process automation framework.
180
+ # Ignore directories containing user credentials, local state, and settings.
181
+ # Learn more at https://abstra.io/docs
182
+ .abstra/
183
+
184
+ # Visual Studio Code
185
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
+ # you could uncomment the following to ignore the entire vscode folder
189
+ # .vscode/
190
+
191
+ # Ruff stuff:
192
+ .ruff_cache/
193
+
194
+ # PyPI configuration file
195
+ .pypirc
196
+
197
+ # Cursor
198
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
+ # refer to https://docs.cursor.com/context/ignore-files
201
+ .cursorignore
202
+ .cursorindexingignore
203
+
204
+ # Marimo
205
+ marimo/_static/
206
+ marimo/_lsp/
207
+ __marimo__/
@@ -0,0 +1 @@
1
+ 3.11
krons-0.1.0/CLAUDE.md ADDED
@@ -0,0 +1,285 @@
1
+ # kronos - Spec-Based Composable Framework
2
+
3
+ ## Overview
4
+
5
+ **kronos** is a Python framework for building spec-based, composable systems. It provides:
6
+
7
+ - **Spec/Operable**: Type-safe field definitions with validation, defaults, and DB metadata
8
+ - **Node**: Polymorphic content containers with DB serialization
9
+ - **Services**: Unified service interfaces (iModel, KronService) with hooks and rate limiting
10
+ - **Enforcement**: Policy evaluation and action handlers with typed I/O
11
+
12
+ ## Architecture
13
+
14
+ ```
15
+ kronos/
16
+ ├── core/ # Foundation: Element, Node, Event, Flow, Graph, Pile
17
+ ├── specs/ # Spec definitions, Operable composition, adapters
18
+ │ ├── catalog/ # Pre-built specs (Content, Audit, Common, Enforcement)
19
+ │ └── adapters/ # Pydantic, SQL DDL, Dataclass adapters
20
+ ├── services/ # Service backends, iModel, hooks, rate limiting
21
+ ├── enforcement/ # Policy protocols, KronService, action decorators
22
+ ├── types/ # Base types, sentinels, DB types (FK, Vector)
23
+ ├── operations/ # Operation builders and registry
24
+ ├── protocols.py # Runtime-checkable protocols with @implements
25
+ └── utils/ # Fuzzy matching, SQL utilities, helpers
26
+ ```
27
+
28
+ ## Key Patterns
29
+
30
+ ### 1. Spec & Operable
31
+
32
+ **Spec** defines a single field with type, name, default, validation, and DB metadata:
33
+
34
+ ```python
35
+ from kronos.specs import Spec, Operable
36
+ from kronos.types.db_types import FK, VectorMeta
37
+
38
+ # Basic specs
39
+ name_spec = Spec(str, name="name")
40
+ count_spec = Spec(int, name="count", default=0, ge=0)
41
+
42
+ # With DB metadata
43
+ user_id = Spec(UUID, name="user_id", as_fk=FK[User])
44
+ embedding = Spec(list[float], name="embedding", embedding=VectorMeta(1536))
45
+
46
+ # Nullable
47
+ email = Spec(str, name="email").as_nullable()
48
+ ```
49
+
50
+ **Operable** composes multiple Specs into structures:
51
+
52
+ ```python
53
+ # From specs
54
+ operable = Operable([name_spec, count_spec, email])
55
+
56
+ # From Pydantic BaseModel
57
+ operable = Operable.from_structure(MyModel)
58
+
59
+ # Generate typed structures
60
+ MyDataclass = operable.compose_structure("MyDataclass")
61
+ specs_list = operable.get_specs()
62
+ ```
63
+
64
+ ### 2. Catalog Specs (BaseModel Pattern)
65
+
66
+ Pre-built specs use BaseModel for field definitions:
67
+
68
+ ```python
69
+ from kronos.specs.catalog import ContentSpecs, AuditSpecs, CommonSpecs
70
+
71
+ # Get specs with customization
72
+ content_specs = ContentSpecs.get_specs(dim=1536) # With vector dimension
73
+ audit_specs = AuditSpecs.get_specs(use_uuid=True) # UUID actor IDs
74
+ common_specs = CommonSpecs.get_specs(status_default="pending")
75
+ ```
76
+
77
+ **Pattern for catalog specs:**
78
+
79
+ ```python
80
+ class MySpecs(BaseModel):
81
+ field1: str
82
+ field2: int = 0
83
+ field3: datetime = Field(default_factory=now_utc)
84
+
85
+ @classmethod
86
+ def get_specs(cls, **overrides) -> list[Spec]:
87
+ operable = Operable.from_structure(cls)
88
+ specs = {s.name: s for s in operable.get_specs()}
89
+ # Apply overrides...
90
+ return list(specs.values())
91
+ ```
92
+
93
+ ### 3. Node (Polymorphic Content)
94
+
95
+ **Node** stores polymorphic content with DB serialization:
96
+
97
+ ```python
98
+ from kronos.core import Node
99
+ from kronos.core.node import create_node, NodeConfig
100
+
101
+ # Basic usage
102
+ node = Node(content={"key": "value"})
103
+ data = node.to_dict(mode="json") # For JSON serialization
104
+ db_data = node.to_dict(mode="db") # For database (renames metadata)
105
+
106
+ # Custom node with typed content
107
+ class JobContent(BaseModel):
108
+ title: str
109
+ salary: int
110
+
111
+ JobNode = create_node(
112
+ "JobNode",
113
+ content=JobContent,
114
+ flatten_content=True, # Spreads content fields in DB mode
115
+ embedding_enabled=True,
116
+ embedding_dim=1536,
117
+ soft_delete=True,
118
+ versioning=True,
119
+ )
120
+
121
+ # DB roundtrip
122
+ job = JobNode(content=JobContent(title="Engineer", salary=100000))
123
+ db_data = job.to_dict(mode="db") # {"title": "Engineer", "salary": 100000, ...}
124
+ restored = JobNode.from_dict(db_data, from_row=True) # Reconstructs content
125
+ ```
126
+
127
+ ### 4. Services (iModel, KronService)
128
+
129
+ **iModel** - Unified service interface with rate limiting:
130
+
131
+ ```python
132
+ from kronos.services import Endpoint, EndpointConfig, iModel
133
+
134
+ config = EndpointConfig(
135
+ name="gpt-4",
136
+ provider="openai",
137
+ endpoint="chat/completions",
138
+ base_url="https://api.openai.com/v1",
139
+ api_key="...",
140
+ )
141
+ endpoint = Endpoint(config=config)
142
+ model = iModel(backend=endpoint)
143
+
144
+ response = await model.invoke({"messages": [...]})
145
+ ```
146
+
147
+ **KronService** - Action handlers with policy evaluation:
148
+
149
+ ```python
150
+ from kronos.enforcement import KronService, KronConfig, action, RequestContext
151
+
152
+ class MyService(KronService):
153
+ @property
154
+ def event_type(self):
155
+ return Calling # Required abstract property
156
+
157
+ @action(name="user.create", inputs={"name", "email"}, outputs={"user_id"})
158
+ async def _handle_create(self, options, ctx):
159
+ return {"user_id": uuid4()}
160
+
161
+ service = MyService(config=KronConfig(provider="my", name="service"))
162
+ result = await service.call("user.create", {"name": "John"}, RequestContext(name="user.create"))
163
+ ```
164
+
165
+ ### 5. Protocols with @implements
166
+
167
+ Runtime-checkable protocols with signature validation:
168
+
169
+ ```python
170
+ from kronos.protocols import implements, Serializable, SignatureMismatchError
171
+
172
+ @implements(Serializable, signature_check="error") # "error", "warn", "skip"
173
+ class MyClass:
174
+ def to_dict(self, **kwargs): # Must match protocol signature
175
+ return {"data": ...}
176
+ ```
177
+
178
+ ### 6. DB Types (FK, Vector)
179
+
180
+ Foreign keys and vector embeddings for SQL DDL:
181
+
182
+ ```python
183
+ from kronos.types.db_types import FK, Vector, FKMeta, VectorMeta, extract_kron_db_meta
184
+
185
+ # In type annotations
186
+ class Post(BaseModel):
187
+ author_id: FK[User] # Expands to Annotated[UUID, FKMeta(User)]
188
+ embedding: Vector[1536] # Expands to Annotated[list[float], VectorMeta(1536)]
189
+
190
+ # Extract metadata
191
+ fk_meta = extract_kron_db_meta(field_info, metas="FK")
192
+ vec_meta = extract_kron_db_meta(field_info, metas="Vector")
193
+ ```
194
+
195
+ ## Testing Patterns
196
+
197
+ ### Test Structure
198
+
199
+ ```
200
+ tests/
201
+ ├── core/ # Node, Element, Event tests
202
+ ├── specs/ # Spec, Operable, Catalog tests
203
+ ├── services/ # iModel, hook tests
204
+ ├── enforcement/ # KronService, policy tests
205
+ └── utils/ # Utility function tests
206
+ ```
207
+
208
+ ### Key Test Utilities
209
+
210
+ ```python
211
+ import pytest
212
+
213
+ # Async tests
214
+ @pytest.mark.anyio
215
+ async def test_async_operation():
216
+ result = await some_async_call()
217
+ assert result == expected
218
+
219
+ # Testing abstract classes (provide required implementations)
220
+ class TestService(KronService):
221
+ @property
222
+ def event_type(self):
223
+ return Calling # Satisfy abstract property
224
+
225
+ # Mock policy engine/resolver (they're Protocols)
226
+ class MockPolicyEngine:
227
+ async def evaluate(self, policy_id, input_data, **options):
228
+ return {}
229
+ async def evaluate_batch(self, policy_ids, input_data, **options):
230
+ return []
231
+ ```
232
+
233
+ ## Common Gotchas
234
+
235
+ 1. **Circular imports in catalog**: Use direct imports from submodules:
236
+ ```python
237
+ # Wrong
238
+ from kronos.specs import Operable, Spec
239
+
240
+ # Right (in catalog files)
241
+ from kronos.specs.operable import Operable
242
+ from kronos.specs.spec import Spec
243
+ ```
244
+
245
+ 2. **PolicyEngine/PolicyResolver are Protocols**: Can't instantiate directly, create mock classes.
246
+
247
+ 3. **Node content flattening**: Only works with typed BaseModel content, not generic dicts.
248
+
249
+ 4. **Spec base_type for lists**: `list[float]` becomes `float` with `is_listable=True`.
250
+
251
+ 5. **compose_structure frozen param**: Currently broken in PydanticSpecAdapter (doesn't accept
252
+ `frozen` kwarg).
253
+
254
+ ## Running Tests
255
+
256
+ ```bash
257
+ cd libs/kronos
258
+
259
+ # All tests
260
+ uv run pytest tests/ -q
261
+
262
+ # With coverage
263
+ uv run pytest tests/ --cov=kronos --cov-report=term-missing
264
+
265
+ # Specific module
266
+ uv run pytest tests/specs/test_catalog.py -v
267
+
268
+ # Single test
269
+ uv run pytest tests/core/test_node.py::TestNodeCreation::test_node_with_dict -v
270
+ ```
271
+
272
+ ## Code Style
273
+
274
+ - Python 3.11+ with type hints
275
+ - Pydantic v2 for models
276
+ - anyio for async (not asyncio directly)
277
+ - ruff for linting (line-length=100)
278
+ - pytest with anyio plugin for async tests
279
+
280
+ ## File Naming Conventions
281
+
282
+ - `_internal.py` - Private module internals
283
+ - `catalog/_*.py` - Catalog spec definitions
284
+ - `adapters/*.py` - Framework adapters (Pydantic, SQL, etc.)
285
+ - `test_*.py` - Test files mirror source structure