domain-errors 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 (95) hide show
  1. domain_errors-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +34 -0
  2. domain_errors-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  3. domain_errors-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +37 -0
  4. domain_errors-0.1.0/.github/workflows/ci.yml +56 -0
  5. domain_errors-0.1.0/.github/workflows/cleanup-guard.yml +70 -0
  6. domain_errors-0.1.0/.github/workflows/dto-strict.yml +36 -0
  7. domain_errors-0.1.0/.github/workflows/no-ai-attribution.yml +73 -0
  8. domain_errors-0.1.0/.github/workflows/publish.yml +35 -0
  9. domain_errors-0.1.0/.github/workflows/ruff.yml +29 -0
  10. domain_errors-0.1.0/.gitignore +134 -0
  11. domain_errors-0.1.0/CHANGELOG.md +28 -0
  12. domain_errors-0.1.0/CODE_OF_CONDUCT.md +31 -0
  13. domain_errors-0.1.0/CONTRIBUTING.md +70 -0
  14. domain_errors-0.1.0/LICENSE +201 -0
  15. domain_errors-0.1.0/PKG-INFO +298 -0
  16. domain_errors-0.1.0/README.md +276 -0
  17. domain_errors-0.1.0/SECURITY.md +28 -0
  18. domain_errors-0.1.0/docs/apps/chain.md +391 -0
  19. domain_errors-0.1.0/docs/apps/cloud.md +164 -0
  20. domain_errors-0.1.0/docs/apps/diagrams.md +265 -0
  21. domain_errors-0.1.0/docs/apps/domain_error.md +218 -0
  22. domain_errors-0.1.0/docs/apps/http.md +158 -0
  23. domain_errors-0.1.0/docs/apps/python.md +166 -0
  24. domain_errors-0.1.0/docs/apps/wrap_errors.md +299 -0
  25. domain_errors-0.1.0/docs/architecture/.gitkeep +0 -0
  26. domain_errors-0.1.0/docs/audits/.gitkeep +0 -0
  27. domain_errors-0.1.0/docs/audits/2026-06-13-chain-security-audit.md +55 -0
  28. domain_errors-0.1.0/docs/audits/2026-06-13-domain_error-security-audit.md +55 -0
  29. domain_errors-0.1.0/docs/audits/2026-06-14-cloud-security-audit.md +53 -0
  30. domain_errors-0.1.0/docs/audits/2026-06-14-http-security-audit.md +53 -0
  31. domain_errors-0.1.0/docs/audits/2026-06-14-python-security-audit.md +53 -0
  32. domain_errors-0.1.0/docs/audits/2026-06-14-wrap_errors-security-audit.md +192 -0
  33. domain_errors-0.1.0/docs/reviews/.gitkeep +0 -0
  34. domain_errors-0.1.0/docs/reviews/2026-06-13-chain-review.md +49 -0
  35. domain_errors-0.1.0/docs/reviews/2026-06-13-domain_error-review.md +53 -0
  36. domain_errors-0.1.0/docs/reviews/2026-06-14-cloud-review.md +46 -0
  37. domain_errors-0.1.0/docs/reviews/2026-06-14-http-review.md +45 -0
  38. domain_errors-0.1.0/docs/reviews/2026-06-14-python-review.md +45 -0
  39. domain_errors-0.1.0/docs/reviews/2026-06-14-wrap_errors-review.md +179 -0
  40. domain_errors-0.1.0/domain_errors/__init__.py +27 -0
  41. domain_errors-0.1.0/domain_errors/common/__init__.py +1 -0
  42. domain_errors-0.1.0/domain_errors/common/constants/__init__.py +1 -0
  43. domain_errors-0.1.0/domain_errors/common/constants/tests.py +1 -0
  44. domain_errors-0.1.0/domain_errors/common/tests/__init__.py +1 -0
  45. domain_errors-0.1.0/domain_errors/config/__init__.py +1 -0
  46. domain_errors-0.1.0/domain_errors/config/_version.py +3 -0
  47. domain_errors-0.1.0/domain_errors/decorators/__init__.py +1 -0
  48. domain_errors-0.1.0/domain_errors/decorators/tests/__init__.py +0 -0
  49. domain_errors-0.1.0/domain_errors/decorators/tests/test_wrap_errors/__init__.py +0 -0
  50. domain_errors-0.1.0/domain_errors/decorators/tests/test_wrap_errors/conftest.py +1 -0
  51. domain_errors-0.1.0/domain_errors/decorators/tests/test_wrap_errors/test_wrap_errors_client.py +541 -0
  52. domain_errors-0.1.0/domain_errors/decorators/wrap_errors/__init__.py +8 -0
  53. domain_errors-0.1.0/domain_errors/decorators/wrap_errors/wrap_errors_client.py +95 -0
  54. domain_errors-0.1.0/domain_errors/domains/__init__.py +1 -0
  55. domain_errors-0.1.0/domain_errors/domains/cloud/__init__.py +5 -0
  56. domain_errors-0.1.0/domain_errors/domains/cloud/cloud_client.py +18 -0
  57. domain_errors-0.1.0/domain_errors/domains/constants/__init__.py +1 -0
  58. domain_errors-0.1.0/domain_errors/domains/constants/cloud.py +20 -0
  59. domain_errors-0.1.0/domain_errors/domains/constants/domain_error.py +20 -0
  60. domain_errors-0.1.0/domain_errors/domains/constants/http.py +20 -0
  61. domain_errors-0.1.0/domain_errors/domains/constants/python.py +20 -0
  62. domain_errors-0.1.0/domain_errors/domains/domain_error/__init__.py +1 -0
  63. domain_errors-0.1.0/domain_errors/domains/domain_error/domain_error.py +22 -0
  64. domain_errors-0.1.0/domain_errors/domains/http/__init__.py +5 -0
  65. domain_errors-0.1.0/domain_errors/domains/http/http_client.py +18 -0
  66. domain_errors-0.1.0/domain_errors/domains/python/__init__.py +5 -0
  67. domain_errors-0.1.0/domain_errors/domains/python/python_client.py +26 -0
  68. domain_errors-0.1.0/domain_errors/domains/tests/__init__.py +1 -0
  69. domain_errors-0.1.0/domain_errors/domains/tests/test_cloud/__init__.py +0 -0
  70. domain_errors-0.1.0/domain_errors/domains/tests/test_cloud/conftest.py +1 -0
  71. domain_errors-0.1.0/domain_errors/domains/tests/test_cloud/test_cloud_client.py +121 -0
  72. domain_errors-0.1.0/domain_errors/domains/tests/test_domain_error/__init__.py +1 -0
  73. domain_errors-0.1.0/domain_errors/domains/tests/test_domain_error/conftest.py +21 -0
  74. domain_errors-0.1.0/domain_errors/domains/tests/test_domain_error/test_domain_error.py +163 -0
  75. domain_errors-0.1.0/domain_errors/domains/tests/test_http/__init__.py +0 -0
  76. domain_errors-0.1.0/domain_errors/domains/tests/test_http/conftest.py +1 -0
  77. domain_errors-0.1.0/domain_errors/domains/tests/test_http/test_http_client.py +183 -0
  78. domain_errors-0.1.0/domain_errors/domains/tests/test_python/__init__.py +0 -0
  79. domain_errors-0.1.0/domain_errors/domains/tests/test_python/conftest.py +1 -0
  80. domain_errors-0.1.0/domain_errors/domains/tests/test_python/test_python_client.py +133 -0
  81. domain_errors-0.1.0/domain_errors/py.typed +0 -0
  82. domain_errors-0.1.0/domain_errors/services/__init__.py +1 -0
  83. domain_errors-0.1.0/domain_errors/services/chain/__init__.py +11 -0
  84. domain_errors-0.1.0/domain_errors/services/chain/chain_client.py +90 -0
  85. domain_errors-0.1.0/domain_errors/services/chain/chain_objects.py +89 -0
  86. domain_errors-0.1.0/domain_errors/services/constants/__init__.py +1 -0
  87. domain_errors-0.1.0/domain_errors/services/constants/chain.py +14 -0
  88. domain_errors-0.1.0/domain_errors/services/constants/services.py +1 -0
  89. domain_errors-0.1.0/domain_errors/services/tests/__init__.py +1 -0
  90. domain_errors-0.1.0/domain_errors/services/tests/test_chain/__init__.py +1 -0
  91. domain_errors-0.1.0/domain_errors/services/tests/test_chain/conftest.py +21 -0
  92. domain_errors-0.1.0/domain_errors/services/tests/test_chain/test_chain_client.py +312 -0
  93. domain_errors-0.1.0/domain_errors/services/tests/test_chain/test_chain_objects.py +360 -0
  94. domain_errors-0.1.0/pyproject.toml +87 -0
  95. domain_errors-0.1.0/uv.lock +1320 -0
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: Bug report
3
+ about: Report a bug or unexpected behavior
4
+ title: ''
5
+ labels: 'bug'
6
+ ---
7
+
8
+ ## Description
9
+
10
+ A clear, concise description of what the bug is.
11
+
12
+ ## Steps to Reproduce
13
+
14
+ 1.
15
+ 2.
16
+ 3.
17
+
18
+ ## Expected Behavior
19
+
20
+ What should happen?
21
+
22
+ ## Actual Behavior
23
+
24
+ What actually happened instead?
25
+
26
+ ## Environment
27
+
28
+ - Python version:
29
+ - domain-errors version:
30
+ - OS:
31
+
32
+ ## Additional Context
33
+
34
+ Any other context, code snippets, or error messages that help clarify the issue.
@@ -0,0 +1,22 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for domain-errors
4
+ title: ''
5
+ labels: 'enhancement'
6
+ ---
7
+
8
+ ## Problem Statement
9
+
10
+ What problem or use case would this feature address? What is the pain point today?
11
+
12
+ ## Proposed Solution
13
+
14
+ How should this feature work? Describe the behavior and any new APIs or changes.
15
+
16
+ ## Alternatives
17
+
18
+ Have you considered other approaches? What are the trade-offs?
19
+
20
+ ## Additional Context
21
+
22
+ Any examples, code sketches, or related issues that provide context.
@@ -0,0 +1,37 @@
1
+ ## Description
2
+
3
+ What does this PR do? Why is the change needed?
4
+
5
+ ## Related Issue(s)
6
+
7
+ Closes #
8
+
9
+ ## Type of Change
10
+
11
+ - [ ] Bug fix
12
+ - [ ] Feature addition
13
+ - [ ] Documentation update
14
+ - [ ] Refactoring
15
+ - [ ] Dependency update
16
+
17
+ ## Testing
18
+
19
+ How has this been tested? What test cases are included?
20
+
21
+ - [ ] Unit tests added/updated
22
+ - [ ] Tests pass locally (`uv run pytest`)
23
+
24
+ ## Code Quality
25
+
26
+ - [ ] Style checks pass (`uv run ruff check` and `uv run ruff format`)
27
+ - [ ] Type checking passes (`uv run mypy` and `uv run pyright`)
28
+ - [ ] Documentation and docstrings updated
29
+ - [ ] CHANGELOG.md updated (if applicable)
30
+ - [ ] No co-author or AI attribution trailers in commits
31
+
32
+ ## Checklist
33
+
34
+ - [ ] I have read [CONTRIBUTING.md](../CONTRIBUTING.md)
35
+ - [ ] I have followed the project's code style and conventions
36
+ - [ ] My commits follow the commit message guidelines (no attribution trailers)
37
+ - [ ] All checks pass locally before opening this PR
@@ -0,0 +1,56 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ test:
17
+ runs-on: ubuntu-latest
18
+ strategy:
19
+ matrix:
20
+ python-version: ["3.11", "3.12"]
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: astral-sh/setup-uv@v4
24
+ with:
25
+ enable-cache: true
26
+ - name: Install Python
27
+ run: uv python install ${{ matrix.python-version }}
28
+ - name: Sync dependencies
29
+ run: uv sync --all-extras
30
+ - name: Test
31
+ # Collection probe: pytest exit 5 = no tests collected (skeleton stage);
32
+ # once the first suite lands, the full coverage-gated run applies.
33
+ run: |
34
+ set +e
35
+ uv run pytest --collect-only -q
36
+ collect=$?
37
+ set -e
38
+ if [ "$collect" -eq 5 ]; then
39
+ echo "No tests collected yet; skeleton stage."
40
+ exit 0
41
+ fi
42
+ uv run pytest -v --cov --cov-fail-under=95
43
+
44
+ mypy:
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - uses: astral-sh/setup-uv@v4
49
+ with:
50
+ enable-cache: true
51
+ - name: Install Python 3.12
52
+ run: uv python install 3.12
53
+ - name: Sync dependencies
54
+ run: uv sync --all-extras
55
+ - name: Type-check
56
+ run: uv run mypy domain_errors/
@@ -0,0 +1,70 @@
1
+ name: Cleanup Guard
2
+
3
+ on:
4
+ pull_request
5
+
6
+ jobs:
7
+ feature-documentation:
8
+ name: Verify all features have audit and review docs
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - name: Check feature documentation completeness
13
+ run: |
14
+ set -e
15
+
16
+ echo "Checking that all implemented features have audit and review documentation..."
17
+
18
+ AUDITS_DIR="docs/audits"
19
+ REVIEWS_DIR="docs/reviews"
20
+
21
+ FEATURES_DIRS="domain_errors/services domain_errors/domains"
22
+ FEATURES=""
23
+ for FEATURES_DIR in $FEATURES_DIRS; do
24
+ if [ -d "$FEATURES_DIR" ]; then
25
+ FEATURES="$FEATURES $(find "$FEATURES_DIR" -maxdepth 1 -type d ! -name "__pycache__" ! -name "tests" ! -name "constants" ! -path "$FEATURES_DIR")"
26
+ fi
27
+ done
28
+
29
+ if [ -z "$FEATURES" ]; then
30
+ echo "ERROR: No features found in domain_errors/services/ or domain_errors/domains/"
31
+ exit 1
32
+ fi
33
+
34
+ MISSING_DOCS=0
35
+
36
+ for feature_dir in $FEATURES; do
37
+ feature_name=$(basename "$feature_dir")
38
+
39
+ # Skip features with no source files
40
+ if [ -z "$(find "$feature_dir" -maxdepth 1 -type f -name '*.py')" ]; then
41
+ continue
42
+ fi
43
+
44
+ # Skip features that are not implemented yet (docstring-only stubs, no classes or functions)
45
+ if ! grep -lqE '^(class |def )' "$feature_dir"/*.py 2>/dev/null; then
46
+ echo "SKIP: feature '$feature_name' has no implementation yet"
47
+ continue
48
+ fi
49
+
50
+ audit_file=$(find "$AUDITS_DIR" -name "*$feature_name*audit*" 2>/dev/null | head -1)
51
+ review_file=$(find "$REVIEWS_DIR" -name "*$feature_name*review*" 2>/dev/null | head -1)
52
+
53
+ if [ -z "$audit_file" ]; then
54
+ echo "FAIL: feature '$feature_name' missing audit doc in $AUDITS_DIR"
55
+ MISSING_DOCS=$((MISSING_DOCS + 1))
56
+ fi
57
+
58
+ if [ -z "$review_file" ]; then
59
+ echo "FAIL: feature '$feature_name' missing review doc in $REVIEWS_DIR"
60
+ MISSING_DOCS=$((MISSING_DOCS + 1))
61
+ fi
62
+ done
63
+
64
+ if [ $MISSING_DOCS -gt 0 ]; then
65
+ echo ""
66
+ echo "ERROR: $MISSING_DOCS feature(s) missing documentation."
67
+ exit 1
68
+ fi
69
+
70
+ echo "All implemented features have corresponding audit and review docs."
@@ -0,0 +1,36 @@
1
+ name: dto-strict
2
+
3
+ # DTO-discipline lint (frozen+slots, facade-ban, R001-R006). Per-repo copy of
4
+ # the canonical gate; runs on the root-layout package. Empty baseline at
5
+ # v0.3.0 (clean rebuild — 0 violations).
6
+
7
+ on:
8
+ pull_request:
9
+ push:
10
+ branches: [main]
11
+
12
+ concurrency:
13
+ group: ${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ lint:
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+ - uses: astral-sh/setup-uv@v4
25
+ with:
26
+ enable-cache: true
27
+ - name: Install Python 3.12
28
+ run: uv python install 3.12
29
+ - name: Run dto-strict
30
+ run: uvx --python 3.12 dto-strict@0.4.0 domain_errors/ --format github
31
+ - name: Check LOC cap (source dirs only)
32
+ run: |
33
+ # LOC-cap step: source dirs only (test density exempt from cap per review record)
34
+ for dir in domain_errors/common/constants domain_errors/config domain_errors/services/chain domain_errors/services/constants domain_errors/domains/domain_error domain_errors/domains/python domain_errors/domains/http domain_errors/domains/botocore domain_errors/domains/constants; do
35
+ uvx --python 3.12 dto-strict@0.4.0 loc-cap "$dir"
36
+ done
@@ -0,0 +1,73 @@
1
+ name: Attribution Gate
2
+
3
+ # Server-side enforcement: rejects pushes/PRs whose commit messages contain
4
+ # Claude/Anthropic attribution. Catches GitHub squash-merge propagation that
5
+ # bypasses local commit-msg, pre-push, and PreToolUse hooks.
6
+ #
7
+ # Per-repo copy of the canonical attribution gate.
8
+
9
+ on:
10
+ push:
11
+ pull_request:
12
+
13
+ permissions:
14
+ contents: read
15
+ pull-requests: read
16
+
17
+ jobs:
18
+ scan:
19
+ name: Scan commit messages for attribution
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - name: Checkout (full history)
23
+ uses: actions/checkout@v4
24
+ with:
25
+ fetch-depth: 0
26
+
27
+ - name: Determine commit range
28
+ id: range
29
+ env:
30
+ EVENT_NAME: ${{ github.event_name }}
31
+ PR_BASE: ${{ github.event.pull_request.base.sha }}
32
+ PR_HEAD: ${{ github.event.pull_request.head.sha }}
33
+ PUSH_BEFORE: ${{ github.event.before }}
34
+ PUSH_AFTER: ${{ github.event.after }}
35
+ run: |
36
+ set -euo pipefail
37
+ if [ "$EVENT_NAME" = "pull_request" ]; then
38
+ BASE="$PR_BASE"
39
+ HEAD="$PR_HEAD"
40
+ else
41
+ BASE="$PUSH_BEFORE"
42
+ HEAD="$PUSH_AFTER"
43
+ if [ "$BASE" = "0000000000000000000000000000000000000000" ] || [ -z "$BASE" ]; then
44
+ git fetch origin main:refs/remotes/origin/main 2>/dev/null || true
45
+ BASE=$(git merge-base origin/main "$HEAD" 2>/dev/null || git rev-list --max-parents=0 "$HEAD" | tail -1)
46
+ fi
47
+ fi
48
+ echo "base=$BASE" >> "$GITHUB_OUTPUT"
49
+ echo "head=$HEAD" >> "$GITHUB_OUTPUT"
50
+
51
+ - name: Scan for Claude/Anthropic attribution
52
+ env:
53
+ BASE: ${{ steps.range.outputs.base }}
54
+ HEAD: ${{ steps.range.outputs.head }}
55
+ PATTERN: 'co-authored-by.*(claude|anthropic)|generated with claude|@claude|noreply@anthropic|🤖'
56
+ run: |
57
+ set -uo pipefail
58
+ OFFENDING=""
59
+ for sha in $(git rev-list "$BASE..$HEAD"); do
60
+ MSG=$(git log -1 --pretty=format:"%B" "$sha")
61
+ if echo "$MSG" | grep -qiE "$PATTERN"; then
62
+ AUTHOR=$(git log -1 --pretty=format:"%an" "$sha")
63
+ SUBJECT=$(git log -1 --pretty=format:"%s" "$sha")
64
+ OFFENDING="${OFFENDING} ${sha:0:8} | author=${AUTHOR} | ${SUBJECT}"$'\n'
65
+ fi
66
+ done
67
+ if [ -n "$OFFENDING" ]; then
68
+ echo "::error::Claude/Anthropic attribution detected in commit messages"
69
+ echo "Offending commits in range $BASE..$HEAD:"
70
+ printf '%s' "$OFFENDING"
71
+ exit 1
72
+ fi
73
+ echo "OK: no attribution detected in $BASE..$HEAD"
@@ -0,0 +1,35 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ name: Build + publish
10
+ runs-on: ubuntu-latest
11
+ environment: pypi # second-layer GitHub deployment-environment gate
12
+ permissions:
13
+ id-token: write # OIDC trusted publisher
14
+ contents: read
15
+
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: '3.12'
24
+
25
+ - name: Install build deps
26
+ run: python -m pip install --upgrade build
27
+
28
+ - name: Build sdist + wheel
29
+ run: python -m build
30
+
31
+ - name: Verify artifacts
32
+ run: python -m pip install --upgrade twine && python -m twine check dist/*
33
+
34
+ - name: Publish to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,29 @@
1
+ name: Ruff
2
+
3
+ # Ruff lint + format check. Pinned to 0.15.14 to match local version.
4
+ # Format drift was previously undetected; this gate prevents future drift.
5
+
6
+ on:
7
+ pull_request:
8
+ push:
9
+ branches: [main]
10
+
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ ruff:
20
+ runs-on: ubuntu-latest
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+ - uses: astral-sh/setup-uv@v4
24
+ with:
25
+ enable-cache: true
26
+ - name: Ruff lint
27
+ run: uvx ruff@0.15.14 check domain_errors/
28
+ - name: Ruff format check
29
+ run: uvx ruff@0.15.14 format --check domain_errors/
@@ -0,0 +1,134 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
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
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ .tox/
41
+ .nox/
42
+ .coverage
43
+ .coverage.*
44
+ .cache
45
+ nosetests.xml
46
+ coverage.xml
47
+ *.cover
48
+ *.py,cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+
52
+ # Translations
53
+ *.mo
54
+ *.pot
55
+
56
+ # Django stuff:
57
+ *.log
58
+ local_settings.py
59
+ db.sqlite3
60
+ db.sqlite3-journal
61
+
62
+ # Flask stuff:
63
+ instance/
64
+ .webassets-cache
65
+
66
+ # Scrapy stuff:
67
+ .scrapy
68
+
69
+ # Sphinx documentation
70
+ docs/_build/
71
+
72
+ # PyBuilder
73
+ target/
74
+
75
+ # Jupyter Notebook
76
+ .ipynb_checkpoints
77
+
78
+ # IPython
79
+ profile_default/
80
+ ipython_config.py
81
+
82
+ # pyenv
83
+ .python-version
84
+
85
+ # pipenv
86
+ Pipfile.lock
87
+
88
+ # PEP 582
89
+ __pypackages__/
90
+
91
+ # Celery stuff
92
+ celerybeat-schedule
93
+ celerybeat.pid
94
+
95
+ # SageMath parsed files
96
+ *.sage.py
97
+
98
+ # Environments
99
+ .env
100
+ .venv
101
+ env/
102
+ venv/
103
+ ENV/
104
+ env.bak/
105
+ venv.bak/
106
+
107
+ # Spyder project settings
108
+ .spyderproject
109
+ .spyproject
110
+
111
+ # Rope project settings
112
+ .ropeproject
113
+
114
+ # mkdocs documentation
115
+ /site
116
+
117
+ # mypy
118
+ .mypy_cache/
119
+ .dmypy.json
120
+ dmypy.json
121
+
122
+ # Pyre type checker
123
+ .pyre/
124
+
125
+ # IDE
126
+ .vscode/
127
+ .idea/
128
+ *.swp
129
+ *.swo
130
+ *~
131
+
132
+ # uv
133
+ .venv
134
+ .venv.lock
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-06-15
11
+
12
+ ### Added
13
+
14
+ - **DomainError base class:** Typed exception hierarchy with class contract (code, domain, http_status, retryable, default_message).
15
+ - **Instance state:** message (string) and context (dict) for structured logging.
16
+ - **ErrorChain service:** Static methods for wrapping, walking, and analyzing exception chains.
17
+ - `wrap(err, as_=ErrorType, message=None, **context)` — construct typed domain errors.
18
+ - `history(err, classifiers=())` — walk exception cascade into ChainLink objects.
19
+ - `crossings(err, classifiers=())` — identify domain boundary crossings.
20
+ - **ChainLink value object:** Structured representation of one exception chain hop, with `to_log_extra()` for JSON-ready logging.
21
+ - **DomainCrossing value object:** Causation hop where errors cross domain boundaries, with `to_log_extra()` for logging.
22
+ - **ChainVia enum:** Tags for how a link entered the chain (ROOT, CAUSE, CONTEXT).
23
+ - **DomainClassifier protocol:** Contract for resolving domains of foreign (non-DomainError) exceptions.
24
+ - **Python stdlib domain classifier:** Built-in `python` classifier for mapping stdlib exception families (network, OS, logic, assertion) to domain strings.
25
+ - **HTTP-client domain classifier:** Built-in `http` classifier for mapping httpx, requests, and aiohttp exceptions to the http domain. By-origin design (type(err).__module__) catches the entire library surface including exceptions outside main error trees; no runtime dependency on the libraries.
26
+ - **AWS cloud domain classifier:** Built-in `cloud` classifier for mapping botocore and boto3 exceptions to the cloud domain. By-origin design (type(err).__module__) catches the entire AWS SDK surface; no runtime dependency on the libraries.
27
+ - **@wrap_errors decorator:** Declarative error wrapping for functions and async callables. Catches specified exceptions, wraps them into a target DomainError via ErrorChain.wrap(), and preserves causation via raise-from. Captures function arguments into error context for structured logging (disable via capture=False). DomainError instances pass through unchanged. Works on both sync and async functions.
28
+ - **Logging payload DTOs:** LinkLogExtra and CrossingLogExtra for structured audit trails.
@@ -0,0 +1,31 @@
1
+ # Code of Conduct
2
+
3
+ ## My Commitment
4
+
5
+ I maintain this project solo, and I am committed to keeping it a welcoming space for everyone who participates in issues, pull requests, and discussions. I pledge to treat every participant with respect and dignity, regardless of age, body size, caste, disability, ethnicity, sex characteristics, gender, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, sexual identity and orientation, or any other dimension of diversity.
6
+
7
+ ## Standards
8
+
9
+ Behavior that keeps this a positive space:
10
+
11
+ - Welcoming and inclusive language
12
+ - Respect for differing viewpoints and experiences
13
+ - Gracefully accepting constructive criticism
14
+ - Focusing on what is best for the project
15
+ - Empathy toward other participants
16
+
17
+ Behavior I will not accept:
18
+
19
+ - Harassment or insulting or derogatory comments
20
+ - Personal attacks
21
+ - Public or private harassment
22
+ - Publishing someone's private information without consent
23
+ - Conduct that could reasonably be considered inappropriate
24
+
25
+ ## Enforcement
26
+
27
+ Report unacceptable behavior to me through GitHub, either by opening an issue or, where discretion is warranted, through private vulnerability reporting. I review and act on every report promptly and fairly, and I respect the privacy and security of anyone who reports.
28
+
29
+ ## Attribution
30
+
31
+ This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
@@ -0,0 +1,70 @@
1
+ # Contributing
2
+
3
+ Thank you for your interest in contributing to domain-errors. This guide explains how to set up your development environment, run tests and linters, and follow our code standards.
4
+
5
+ ## Development Setup
6
+
7
+ This project uses **uv** for dependency management. Install it first, then sync dependencies:
8
+
9
+ ```bash
10
+ uv sync
11
+ ```
12
+
13
+ This creates a virtual environment and installs all development dependencies, including testing, linting, type-checking, and formatting tools.
14
+
15
+ ## Running Checks
16
+
17
+ All checks must pass before code is merged:
18
+
19
+ ```bash
20
+ # Run tests
21
+ uv run pytest
22
+
23
+ # Check code style and imports
24
+ uv run ruff check
25
+
26
+ # Format code
27
+ uv run ruff format
28
+
29
+ # Type check (mypy)
30
+ uv run mypy
31
+
32
+ # Type check (pyright alternative)
33
+ uv run pyright
34
+ ```
35
+
36
+ Run these locally before opening a pull request to catch issues early.
37
+
38
+ ## Code Style
39
+
40
+ This project follows these conventions:
41
+
42
+ - **Dataclasses**: Use `@dataclass(frozen=True, slots=True)` for immutable value types.
43
+ - **Docstrings**: One-line docstrings for modules, classes, and functions. Use triple quotes even for single lines.
44
+ - **Imports**: Import abstract base classes from `collections.abc` (not `typing`). Use absolute imports (no relative imports).
45
+ - **Methods**: Every method lives in a class or container—no module-level functions. Containers keep methods organized.
46
+ - **Constants**: Extract magic constants to `constants/` directory only when they are semantically significant (shared across modules or define behavior).
47
+
48
+ ## Pull Request Flow
49
+
50
+ 1. **Branch**: Create a feature branch off `main` (e.g., `git checkout -b feature/my-feature`).
51
+ 2. **Commit**: Make small, clear commits. Each commit author is the person who wrote the code—no co-author or AI attribution trailers.
52
+ 3. **Push**: Push your branch and open a pull request on GitHub.
53
+ 4. **Review**: The maintainer will review your code, request changes if needed, and merge when ready. Contributors do not merge their own PRs.
54
+
55
+ ## Commit Messages
56
+
57
+ Write clear, descriptive commit messages that explain *why* the change was made. Example:
58
+
59
+ ```
60
+ Add @wrap_errors decorator for automatic error domain wrapping
61
+
62
+ Simplifies error handling across services by applying domain
63
+ classification to function arguments without try/except boilerplate.
64
+ ```
65
+
66
+ Do not include co-author or AI attribution trailers in commit messages.
67
+
68
+ ## Community Standards
69
+
70
+ Please read [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) before participating. We expect respectful collaboration and inclusive language in all interactions.