sugar-dsl 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 (79) hide show
  1. sugar_dsl-1.0.0/.github/workflows/publish.yml +105 -0
  2. sugar_dsl-1.0.0/.gitignore +49 -0
  3. sugar_dsl-1.0.0/AGENTS.md +240 -0
  4. sugar_dsl-1.0.0/CHANGELOG.md +1 -0
  5. sugar_dsl-1.0.0/LICENSE +674 -0
  6. sugar_dsl-1.0.0/PKG-INFO +26 -0
  7. sugar_dsl-1.0.0/README.md +257 -0
  8. sugar_dsl-1.0.0/pyproject.toml +77 -0
  9. sugar_dsl-1.0.0/requirements-dev.txt +7 -0
  10. sugar_dsl-1.0.0/setup.cfg +4 -0
  11. sugar_dsl-1.0.0/setup.py +18 -0
  12. sugar_dsl-1.0.0/sugar/__init__.py +16 -0
  13. sugar_dsl-1.0.0/sugar/_version.py +24 -0
  14. sugar_dsl-1.0.0/sugar/api/__init__.py +16 -0
  15. sugar_dsl-1.0.0/sugar/api/builder.py +233 -0
  16. sugar_dsl-1.0.0/sugar/catalog/__init__.py +28 -0
  17. sugar_dsl-1.0.0/sugar/catalog/artifacts.py +167 -0
  18. sugar_dsl-1.0.0/sugar/catalog/local_flavors.py +154 -0
  19. sugar_dsl-1.0.0/sugar/catalog/models.py +564 -0
  20. sugar_dsl-1.0.0/sugar/catalog/registry.py +187 -0
  21. sugar_dsl-1.0.0/sugar/catalog/subgraphs.py +265 -0
  22. sugar_dsl-1.0.0/sugar/compiler/__init__.py +24 -0
  23. sugar_dsl-1.0.0/sugar/compiler/aliases.py +64 -0
  24. sugar_dsl-1.0.0/sugar/compiler/analyzer.py +909 -0
  25. sugar_dsl-1.0.0/sugar/compiler/codegen.py +134 -0
  26. sugar_dsl-1.0.0/sugar/compiler/flavors.py +190 -0
  27. sugar_dsl-1.0.0/sugar/compiler/graph.py +64 -0
  28. sugar_dsl-1.0.0/sugar/compiler/graph_ops.py +654 -0
  29. sugar_dsl-1.0.0/sugar/compiler/inheritance.py +642 -0
  30. sugar_dsl-1.0.0/sugar/compiler/input_materialization.py +199 -0
  31. sugar_dsl-1.0.0/sugar/compiler/ir.py +284 -0
  32. sugar_dsl-1.0.0/sugar/compiler/links.py +40 -0
  33. sugar_dsl-1.0.0/sugar/compiler/materializer.py +457 -0
  34. sugar_dsl-1.0.0/sugar/compiler/plan_validation.py +85 -0
  35. sugar_dsl-1.0.0/sugar/compiler/recipe.py +193 -0
  36. sugar_dsl-1.0.0/sugar/compiler/resolver.py +275 -0
  37. sugar_dsl-1.0.0/sugar/compiler/subgraph_expand.py +298 -0
  38. sugar_dsl-1.0.0/sugar/compiler/subgraph_interfaces.py +124 -0
  39. sugar_dsl-1.0.0/sugar/compiler/subgraph_links.py +302 -0
  40. sugar_dsl-1.0.0/sugar/compiler/subgraph_rewrite.py +112 -0
  41. sugar_dsl-1.0.0/sugar/compiler/ui_workflow.py +1308 -0
  42. sugar_dsl-1.0.0/sugar/dsl/__init__.py +63 -0
  43. sugar_dsl-1.0.0/sugar/dsl/ast.py +178 -0
  44. sugar_dsl-1.0.0/sugar/dsl/lexer.py +253 -0
  45. sugar_dsl-1.0.0/sugar/dsl/parser.py +419 -0
  46. sugar_dsl-1.0.0/sugar/dsl/tokens.py +74 -0
  47. sugar_dsl-1.0.0/sugar/runtime/__init__.py +16 -0
  48. sugar_dsl-1.0.0/sugar/runtime/executor.py +254 -0
  49. sugar_dsl-1.0.0/sugar/runtime/modifiers.py +91 -0
  50. sugar_dsl-1.0.0/sugar/runtime/normalization.py +39 -0
  51. sugar_dsl-1.0.0/sugar/shared/__init__.py +20 -0
  52. sugar_dsl-1.0.0/sugar/shared/seed.py +36 -0
  53. sugar_dsl-1.0.0/sugar_dsl.egg-info/PKG-INFO +26 -0
  54. sugar_dsl-1.0.0/sugar_dsl.egg-info/SOURCES.txt +77 -0
  55. sugar_dsl-1.0.0/sugar_dsl.egg-info/dependency_links.txt +1 -0
  56. sugar_dsl-1.0.0/sugar_dsl.egg-info/not-zip-safe +1 -0
  57. sugar_dsl-1.0.0/sugar_dsl.egg-info/requires.txt +8 -0
  58. sugar_dsl-1.0.0/sugar_dsl.egg-info/top_level.txt +1 -0
  59. sugar_dsl-1.0.0/tests/__init__.py +16 -0
  60. sugar_dsl-1.0.0/tests/__snapshots__/test_golden_master_advanced_logic.json +171 -0
  61. sugar_dsl-1.0.0/tests/__snapshots__/test_golden_master_basic_flow.json +113 -0
  62. sugar_dsl-1.0.0/tests/__snapshots__/test_golden_master_data_types.json +57 -0
  63. sugar_dsl-1.0.0/tests/__snapshots__/test_golden_master_disable_features.json +67 -0
  64. sugar_dsl-1.0.0/tests/__snapshots__/test_golden_master_random_keyword.json +53 -0
  65. sugar_dsl-1.0.0/tests/fixtures/__init__.py +16 -0
  66. sugar_dsl-1.0.0/tests/fixtures/cubes.py +198 -0
  67. sugar_dsl-1.0.0/tests/test_artifact_resolution.py +187 -0
  68. sugar_dsl-1.0.0/tests/test_compiler_contracts.py +2216 -0
  69. sugar_dsl-1.0.0/tests/test_dsl_parser.py +151 -0
  70. sugar_dsl-1.0.0/tests/test_flavor_support.py +416 -0
  71. sugar_dsl-1.0.0/tests/test_golden_master.py +377 -0
  72. sugar_dsl-1.0.0/tests/test_license_headers.py +82 -0
  73. sugar_dsl-1.0.0/tests/test_plan_validation.py +233 -0
  74. sugar_dsl-1.0.0/tests/test_runtime_executor.py +301 -0
  75. sugar_dsl-1.0.0/tests/test_seed_behavior.py +214 -0
  76. sugar_dsl-1.0.0/tests/test_spawn_plan.py +918 -0
  77. sugar_dsl-1.0.0/tests/test_subgraph_expansion.py +1005 -0
  78. sugar_dsl-1.0.0/tests/test_ui_workflow.py +891 -0
  79. sugar_dsl-1.0.0/tools/add_license_headers.py +206 -0
@@ -0,0 +1,105 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ release:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: write
12
+ outputs:
13
+ version: ${{ steps.semver.outputs.version }}
14
+ released: ${{ steps.semver.outputs.released }}
15
+ steps:
16
+ - name: Check out source
17
+ uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+ fetch-tags: true
21
+ token: ${{ secrets.GITHUB_TOKEN }}
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: "3.12"
27
+
28
+ - name: Install dependencies
29
+ run: |
30
+ python -m pip install --upgrade pip
31
+ python -m pip install -e .[dev]
32
+
33
+ - name: Verify license headers
34
+ run: |
35
+ python tools/add_license_headers.py
36
+ git diff --exit-code
37
+
38
+ - name: Lint
39
+ run: ruff check .
40
+
41
+ - name: Check formatting
42
+ run: ruff format --check .
43
+
44
+ - name: Type check
45
+ run: mypy --strict sugar tests
46
+
47
+ - name: Test
48
+ run: python -m pytest -n auto -q
49
+
50
+ - name: Capture previous version
51
+ id: prev
52
+ run: echo "version=$(python -m semantic_release version --print-last-released)" >> "$GITHUB_OUTPUT"
53
+
54
+ - name: Create release
55
+ env:
56
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57
+ run: |
58
+ git config --global user.name "github-actions"
59
+ git config --global user.email "github-actions@github.com"
60
+ python -m semantic_release -v changelog
61
+ python -m semantic_release -v version --skip-build
62
+
63
+ - name: Capture released version
64
+ id: semver
65
+ run: |
66
+ prev="${{ steps.prev.outputs.version }}"
67
+ curr="$(python -m semantic_release version --print-last-released)"
68
+ echo "version=$curr" >> "$GITHUB_OUTPUT"
69
+ if [ "$prev" != "$curr" ]; then
70
+ echo "released=true" >> "$GITHUB_OUTPUT"
71
+ else
72
+ echo "released=false" >> "$GITHUB_OUTPUT"
73
+ fi
74
+
75
+ - name: Build dist
76
+ if: steps.semver.outputs.released == 'true'
77
+ run: python -m build
78
+
79
+ - name: Upload dist
80
+ if: steps.semver.outputs.released == 'true'
81
+ uses: actions/upload-artifact@v4
82
+ with:
83
+ name: dist-${{ steps.semver.outputs.version }}
84
+ path: dist/*
85
+
86
+ publish-pypi:
87
+ needs: release
88
+ runs-on: ubuntu-latest
89
+ if: needs.release.outputs.released == 'true'
90
+ environment:
91
+ name: pypi
92
+ url: https://pypi.org/p/sugar-dsl
93
+ permissions:
94
+ id-token: write
95
+ steps:
96
+ - name: Download dist
97
+ uses: actions/download-artifact@v4
98
+ with:
99
+ name: dist-${{ needs.release.outputs.version }}
100
+ path: dist/
101
+
102
+ - name: Publish to PyPI
103
+ uses: pypa/gh-action-pypi-publish@release/v1
104
+ with:
105
+ packages-dir: dist/
@@ -0,0 +1,49 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyd
5
+ *.so
6
+ *.egg-info/
7
+ .eggs/
8
+ pip-wheel-metadata/
9
+
10
+ # Packaging
11
+ build/
12
+ dist/
13
+ *.egg
14
+ MANIFEST
15
+ sugar/_version.py
16
+
17
+ # Tooling
18
+ .coverage
19
+ .coverage.*
20
+ coverage.xml
21
+ htmlcov/
22
+ .mypy_cache/
23
+ .pytest_cache/
24
+ .ruff_cache/
25
+ .tox/
26
+ .nox/
27
+
28
+ # OS
29
+ .DS_Store
30
+ Thumbs.db
31
+ desktop.ini
32
+
33
+ # Virtual environments
34
+ .venv/
35
+ venv/
36
+ env/
37
+ ENV/
38
+
39
+ # Local environment
40
+ .env
41
+ .env.*
42
+ !.env.example
43
+
44
+ # IDE/editor
45
+ .idea/
46
+ .vscode/
47
+ *.swp
48
+ *.swo
49
+ *~
@@ -0,0 +1,240 @@
1
+ # AGENTS.md
2
+
3
+ ## Mission Statement
4
+
5
+ This project provides a high-quality Python package for compiling Sugar DSL scripts and SugarCube assets into ComfyUI workflow JSON.
6
+
7
+ Engineering priority is strict architecture, strong separation of concerns, complete refactors, complete feature integrations, behavior safety during structural change, stable cube identity, strict validation, deterministic compilation, and long-term maintainability.
8
+
9
+ ## Purpose
10
+
11
+ - This file defines engineering guardrails for this repository.
12
+ - This file governs architecture, code quality, typing, testing, observability, runtime safety, DSL behavior, cube catalog behavior, and compiler safety.
13
+ - Do not use this file for feature specs or product planning.
14
+
15
+ ## Behavior Boundary
16
+
17
+ - Preserve existing user-facing behavior unless explicitly approved to change.
18
+ - Preserve compatibility for supported Sugar DSL syntax unless explicitly approved to change.
19
+ - Preserve compatibility for supported `.cube` document formats, local flavor state, spawn plan structure, and generated ComfyUI workflow JSON unless explicitly approved to change.
20
+ - Treat current DSL behavior, cube validation behavior, spawn plan shape, and workflow output as the contract.
21
+ - Change internals freely within that boundary.
22
+
23
+ ## Environment and Gate Execution
24
+
25
+ - All verification commands must run against the repository virtual environment at `.venv`.
26
+ - Do not run quality gates with global/system Python.
27
+ - If `.venv` is missing or stale, recreate it and install the project plus development tooling before running gates.
28
+ - Run all commands from the repository root.
29
+
30
+ ### Required command forms
31
+
32
+ - Tests: `.\.venv\Scripts\python.exe -m pytest -n auto -q`
33
+ - License headers: `.\.venv\Scripts\python.exe tools\add_license_headers.py`
34
+ - Lint: `.\.venv\Scripts\ruff.exe check .`
35
+ - Format: `.\.venv\Scripts\ruff.exe format .`
36
+ - Type check: `.\.venv\Scripts\mypy.exe --strict sugar tests`
37
+
38
+ If a required tool is missing from `.venv`, install or update development dependencies in `.venv` before verification. Do not substitute global tools.
39
+
40
+ ## Core Engineering Principles
41
+
42
+ - Use strict object-oriented design where ownership, state, lifecycle, or collaboration boundaries exist.
43
+ - Enforce strong separation of concerns as the primary architecture objective.
44
+ - Keep modules cohesive and boundaries explicit.
45
+ - Assign one authoritative owner per concern.
46
+ - Other components may participate in a concern only by using the authoritative owner. They must not re-implement that concern in parallel.
47
+ - Reassess ownership before extending an existing structure.
48
+ - If a change introduces a distinct responsibility, change cadence, or collaboration boundary, split or extract it as part of the change.
49
+ - Complete refactors fully. Update all callsites, remove dead code, remove temporary bridges, and make the new design native to the codebase.
50
+ - Complete feature additions fully. Wire the feature through the relevant API, compiler, runtime, tests, typing, and validation paths required by the behavior.
51
+ - Do not leave partial implementations, unused code paths, TODO-driven behavior, or follow-up cleanup inside the completed change.
52
+ - Do not add internal compatibility layers, internal shims, dual internal paths, legacy fallbacks, or transitional adapters.
53
+ - Preserve compatibility only at public or persisted boundaries when required by the behavior contract.
54
+ - Favor DRY when it reduces repeated change risk.
55
+ - Avoid abstractions that hide intent.
56
+
57
+ ## Architecture Rules
58
+
59
+ - Organize code into clear layers with one-way dependencies.
60
+ - Public API layer: stable package-facing entry points such as `sugar.api.builder`.
61
+ - DSL/Language layer: tokenization, parsing, AST definitions, and syntax-only validation.
62
+ - Catalog layer: cube discovery, cube document validation, local flavor loading, and asset indexing.
63
+ - Compiler/Application layer: semantic analysis, compilation flow, spawn plan construction, workflow code generation, inheritance, flavors, and cube operations.
64
+ - Runtime/Adapter layer: ComfyUI HTTP execution, workflow patching, filesystem paths, save-path patching, random seed patching, subprocess boundaries, and network boundaries.
65
+ - Shared layer: small cross-layer primitives with no higher-level dependencies.
66
+ - Higher-level layers may depend on lower-level layers.
67
+ - Lower-level layers must not depend on higher-level layers.
68
+ - The DSL parser must not perform catalog IO or semantic cube validation.
69
+ - The catalog must not know about DSL syntax or workflow generation.
70
+ - The analyzer owns DSL semantic interpretation against catalog data.
71
+ - Codegen owns conversion from spawn plans into ComfyUI workflow JSON.
72
+ - Runtime adapters own external system interaction.
73
+ - Keep ComfyUI HTTP details out of parser, catalog, and core semantic analysis.
74
+ - Place code by ownership and dependency direction, not convenience or proximity.
75
+ - Avoid god classes and monolithic files.
76
+ - Split by responsibility, not convenience.
77
+
78
+ ## Structural Change Rules
79
+
80
+ - For behavior-critical areas, work in two steps:
81
+ 1. Add characterization/regression tests for existing behavior.
82
+ 2. Perform structural changes behind those tests.
83
+ - Behavior-critical areas include DSL parsing, cube validation, flavor resolution, spawn plan generation, workflow codegen, subgraph expansion, inheritance, disable rewiring, random seed behavior, and ComfyUI execution behavior.
84
+ - Do not start structural changes in an area without behavior safeguards for that area.
85
+ - When behavior spans multiple components, trace the current ownership and data flow before editing.
86
+ - Correct the ownership model instead of layering compensating patches across consumers.
87
+ - Land structural changes as complete vertical slices.
88
+ - Do not land large unverified rewrites.
89
+ - If behavior changes are intentional, explicitly call them out and test them as new behavior.
90
+ - Current module layout does not constrain improvement.
91
+ - Reorganize modules when it improves architecture.
92
+ - Align touched modules with the ownership and dependency rules in this file.
93
+
94
+ ## Code Organization and Readability
95
+
96
+ - Write self-documenting code with expressive, concise names.
97
+ - Place new code deliberately in the module where it naturally belongs.
98
+ - Keep files intentionally organized so reading order reflects design intent.
99
+ - Do not place code opportunistically "where it works".
100
+ - Remove obsolete code paths when replacements are complete.
101
+ - Keep DSL syntax concerns in `sugar.dsl`.
102
+ - Keep cube schema and catalog concerns in `sugar.catalog`.
103
+ - Keep compile-time semantic and workflow concerns in `sugar.compiler`.
104
+ - Keep ComfyUI runtime communication and workflow patching in `sugar.runtime`.
105
+
106
+ ## Docstrings and Comments
107
+
108
+ - Docstrings are mandatory for all new and changed modules, classes, functions, and methods.
109
+ - Use concise imperative docstrings for simple logic.
110
+ - Use Google-style docstrings for complex logic.
111
+ - Docstrings must explain rationale, constraints, and intent.
112
+ - Docstrings must not restate obvious mechanics.
113
+ - Inline comments are allowed only for non-obvious behavior, invariants, edge cases, or external constraints.
114
+
115
+ ## Documentation Policy
116
+
117
+ - Do not create new docs files, README variants, design docs, ADRs, roadmap files, or notes unless explicitly requested by the maintainer.
118
+ - Required context must live in code, type hints, tests, and docstrings.
119
+ - Documentation and explanatory writing must describe the product directly as it exists now.
120
+ - Do not document against removed features, imagined alternatives, or non-existent choices.
121
+
122
+ ## Typing Policy
123
+
124
+ - Strong typing is required for all new code.
125
+ - Modified code must be typed as part of the change.
126
+ - Type hints are mandatory on function signatures and key internal state.
127
+ - Use explicit domain types, dataclasses, TypedDicts, Protocols, and type narrowing instead of `Any`.
128
+ - `Any` is allowed only at external JSON/dynamic boundaries and must be narrowed before core logic relies on it.
129
+ - Run `mypy --strict` for type verification.
130
+ - Temporary typing relaxations are allowed only when explicitly justified inline and tracked for removal.
131
+
132
+ ## Logging, Errors, and Observability
133
+
134
+ - Observability is mandatory.
135
+ - Use structured, actionable logging with context identifiers where relevant.
136
+ - Include enough context to diagnose failures quickly, such as script path, cube root, cube ID, cube alias, version pin, flavor name, node key, binding name, prompt ID, output path, and operation.
137
+ - Use log levels consistently: `debug`, `info`, `warning`, `error`.
138
+ - Preserve exception context and stack traces for unexpected failures.
139
+ - `print` is not allowed for runtime diagnostics.
140
+ - Bare `except:` is not allowed.
141
+ - `except Exception` must be narrow, intentional, and log context plus failure reason.
142
+ - Silent exception swallowing is not allowed.
143
+ - Errors exposed from parser, analyzer, catalog, codegen, and runtime boundaries must be explicit and actionable.
144
+
145
+ ## Desktop Security and Safety Rules
146
+
147
+ - Treat cube loading, local flavor loading, workflow generation, filesystem paths, ComfyUI HTTP calls, subprocess execution, and network access as security-sensitive.
148
+ - Never execute untrusted code paths from cube files, local flavor files, scripts, or generated workflow data.
149
+ - Validate and sanitize external paths and user-provided file references.
150
+ - Use structured JSON parsing and validation for `.cube` and local flavor files.
151
+ - Use subprocess argument lists, never shell-string execution.
152
+ - Set explicit timeouts for network operations.
153
+ - Fail closed when trust, schema validation, path validation, or version validation is uncertain.
154
+ - Never log secrets, tokens, credentials, or sensitive local paths beyond what is necessary for diagnosis.
155
+ - Do not silently continue after invalid cube metadata, duplicate cube IDs, invalid flavor state, unresolved aliases, unresolved nodes, or invalid bindings.
156
+
157
+ ## DSL and Compiler Rules
158
+
159
+ - The parser must remain syntax-only.
160
+ - Semantic checks must live in compiler analysis, not in tokenization or parsing.
161
+ - Cube identity is `cube_id`.
162
+ - Alias is instance identity within a script.
163
+ - Alias collisions are fatal.
164
+ - Version pin mismatches are fatal.
165
+ - Missing cube IDs are fatal and must report available IDs when practical.
166
+ - Plan entries must carry cube identity and alias explicitly.
167
+ - Internal references during workflow construction must use aliases and normalized node keys, not filenames.
168
+ - Deprecated internal paths must be removed after replacement.
169
+ - Do not keep compatibility shims inside the compiler.
170
+ - Do not preserve old internal DSL, catalog, compiler, or runtime paths after their replacements are complete.
171
+
172
+ ## Testing Policy
173
+
174
+ - Add or update tests for every behavior change and every bug fix.
175
+ - Add characterization tests before structural changes to behavior-critical areas.
176
+ - New behavior must not be unverified.
177
+ - Include success and failure path coverage.
178
+ - Include regression tests for fixed bugs.
179
+ - Keep tests deterministic and isolated.
180
+ - Use real behavior tests over excessive mocking.
181
+ - Mock only external boundaries such as HTTP calls, filesystem errors, random seed generation, and time.
182
+ - Compiler behavior must be tested at the narrowest useful level and through integration/golden tests when output shape matters.
183
+ - DSL changes require parser tests and analyzer or workflow tests when semantics change.
184
+ - Cube schema changes require catalog validation tests.
185
+ - Runtime HTTP behavior requires tests for success and failure paths.
186
+
187
+ ## Test Execution Rules
188
+
189
+ - Run tests in parallel using xdist.
190
+ - Default command: `.\.venv\Scripts\python.exe -m pytest -n auto -q`.
191
+ - If running a focused subset during development, run the full suite before completion.
192
+ - Failing tests are blocking.
193
+
194
+ ## Python Toolchain
195
+
196
+ - Formatter: `ruff format`
197
+ - Linter: `ruff check`
198
+ - Type checker: `mypy --strict`
199
+ - Test runner: `pytest -n auto -q`
200
+
201
+ ## Verification Workflow
202
+
203
+ - Run focused checks continuously while implementing.
204
+ - Verify the specific reported behavior directly when feasible.
205
+ - Do not declare a compiler, DSL, workflow, or runtime issue fixed from code inspection alone when a direct test is feasible.
206
+ - Run full gates before reporting completion.
207
+ - Distinguish observed results from inferred results in updates and completion reports.
208
+ - Do not introduce new lint/type failures in modified files.
209
+ - Do not report completion if any blocking gate fails.
210
+ - If a gate is intentionally deferred, explicitly state the reason and risk.
211
+
212
+ ## Definition of Done
213
+
214
+ Per change, all of the following are required:
215
+
216
+ - Behavior is safeguarded by tests.
217
+ - New/modified code follows architecture boundaries.
218
+ - New/modified code placement reflects ownership and dependency rules in this file.
219
+ - Refactors are complete, with callsites updated and obsolete internal paths removed.
220
+ - Features are complete, with API, compiler, runtime, validation, typing, and tests updated wherever the behavior requires them.
221
+ - New/modified code is typed.
222
+ - Required docstrings are present and meaningful.
223
+ - Logging/error handling is actionable.
224
+ - Security-sensitive boundaries validate inputs and fail closed.
225
+ - `ruff format` passes.
226
+ - `ruff check` passes.
227
+ - `mypy --strict` passes for the enforced scope.
228
+ - `pytest -n auto -q` passes.
229
+
230
+ ## Commit Policy
231
+
232
+ - Use Conventional Commits: `type(scope): subject`.
233
+ - Allowed types: `feat`, `fix`, `refactor`, `test`, `chore`, `docs`, `build`, `ci`.
234
+ - Keep commits atomic and cohesive.
235
+ - Breaking structural changes must be clearly labeled.
236
+
237
+ ## Maintainer Authority
238
+
239
+ - Maintainer instructions override this file.
240
+ - If constraints conflict, pause and ask for maintainer direction before proceeding.
@@ -0,0 +1 @@
1
+ # Changelog