achlens 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 (97) hide show
  1. achlens-0.1.0/.github/workflows/ci.yml +36 -0
  2. achlens-0.1.0/.github/workflows/release.yml +65 -0
  3. achlens-0.1.0/.gitignore +33 -0
  4. achlens-0.1.0/CHANGELOG.md +5 -0
  5. achlens-0.1.0/CONTRIBUTING.md +5 -0
  6. achlens-0.1.0/LICENSE +154 -0
  7. achlens-0.1.0/PKG-INFO +216 -0
  8. achlens-0.1.0/README.md +50 -0
  9. achlens-0.1.0/SECURITY.md +38 -0
  10. achlens-0.1.0/docs/adr/001-python-and-sdk.md +18 -0
  11. achlens-0.1.0/docs/adr/002-layered-architecture.md +17 -0
  12. achlens-0.1.0/docs/adr/003-data-driven-layouts.md +17 -0
  13. achlens-0.1.0/docs/adr/004-data-driven-rules.md +17 -0
  14. achlens-0.1.0/docs/adr/005-default-masking.md +17 -0
  15. achlens-0.1.0/docs/adr/006-local-only-transport.md +16 -0
  16. achlens-0.1.0/docs/adr/007-structured-tool-errors.md +16 -0
  17. achlens-0.1.0/docs/adr/008-tolerant-parser-strict-validator.md +17 -0
  18. achlens-0.1.0/docs/core-01-source-verification.md +60 -0
  19. achlens-0.1.0/docs/demo.md +3 -0
  20. achlens-0.1.0/docs/differential-testing.md +29 -0
  21. achlens-0.1.0/docs/performance.md +63 -0
  22. achlens-0.1.0/docs/phase-validation-performance-and-release.md +248 -0
  23. achlens-0.1.0/docs/registry.md +24 -0
  24. achlens-0.1.0/docs/release.md +20 -0
  25. achlens-0.1.0/docs/rules.md +3 -0
  26. achlens-0.1.0/docs/threat-model.md +52 -0
  27. achlens-0.1.0/docs/tools.md +3 -0
  28. achlens-0.1.0/docs/validation-snapshot-contract.md +238 -0
  29. achlens-0.1.0/pyproject.toml +62 -0
  30. achlens-0.1.0/scripts/benchmark_validation.py +54 -0
  31. achlens-0.1.0/scripts/benchmark_validation_paths.py +52 -0
  32. achlens-0.1.0/scripts/differential_validation.py +73 -0
  33. achlens-0.1.0/scripts/package_smoke_test.py +50 -0
  34. achlens-0.1.0/server.json +22 -0
  35. achlens-0.1.0/src/achlens/__init__.py +3 -0
  36. achlens-0.1.0/src/achlens/cli.py +112 -0
  37. achlens-0.1.0/src/achlens/core/__init__.py +45 -0
  38. achlens-0.1.0/src/achlens/core/builder.py +71 -0
  39. achlens-0.1.0/src/achlens/core/calculators.py +131 -0
  40. achlens-0.1.0/src/achlens/core/data/ach_layouts.yaml +683 -0
  41. achlens-0.1.0/src/achlens/core/data/entry_codes.py +36 -0
  42. achlens-0.1.0/src/achlens/core/data/rules.yaml +339 -0
  43. achlens-0.1.0/src/achlens/core/generator.py +295 -0
  44. achlens-0.1.0/src/achlens/core/layouts.py +130 -0
  45. achlens-0.1.0/src/achlens/core/lines.py +105 -0
  46. achlens-0.1.0/src/achlens/core/masking.py +70 -0
  47. achlens-0.1.0/src/achlens/core/model.py +49 -0
  48. achlens-0.1.0/src/achlens/core/parser.py +157 -0
  49. achlens-0.1.0/src/achlens/core/reference.py +161 -0
  50. achlens-0.1.0/src/achlens/core/repair.py +151 -0
  51. achlens-0.1.0/src/achlens/core/rules/__init__.py +39 -0
  52. achlens-0.1.0/src/achlens/core/rules/addenda.py +250 -0
  53. achlens-0.1.0/src/achlens/core/rules/controls.py +348 -0
  54. achlens-0.1.0/src/achlens/core/rules/entry.py +589 -0
  55. achlens-0.1.0/src/achlens/core/rules/headers.py +395 -0
  56. achlens-0.1.0/src/achlens/core/rules/registry.py +153 -0
  57. achlens-0.1.0/src/achlens/core/rules/structural.py +272 -0
  58. achlens-0.1.0/src/achlens/core/validation_snapshot.py +436 -0
  59. achlens-0.1.0/src/achlens/core/validator.py +118 -0
  60. achlens-0.1.0/src/achlens/server/__init__.py +1 -0
  61. achlens-0.1.0/src/achlens/server/app.py +84 -0
  62. achlens-0.1.0/src/achlens/server/config.py +46 -0
  63. achlens-0.1.0/src/achlens/server/inputs.py +123 -0
  64. achlens-0.1.0/src/achlens/server/prompts.py +26 -0
  65. achlens-0.1.0/src/achlens/server/resources.py +31 -0
  66. achlens-0.1.0/src/achlens/server/tools.py +575 -0
  67. achlens-0.1.0/tests/fixtures/__init__.py +1 -0
  68. achlens-0.1.0/tests/fixtures/builders.py +160 -0
  69. achlens-0.1.0/tests/fixtures/golden/sample_valid.ach +10 -0
  70. achlens-0.1.0/tests/fixtures/regen.py +16 -0
  71. achlens-0.1.0/tests/test_addenda.py +184 -0
  72. achlens-0.1.0/tests/test_builder.py +167 -0
  73. achlens-0.1.0/tests/test_calculators.py +139 -0
  74. achlens-0.1.0/tests/test_cli.py +42 -0
  75. achlens-0.1.0/tests/test_controls.py +164 -0
  76. achlens-0.1.0/tests/test_differential.py +38 -0
  77. achlens-0.1.0/tests/test_entry.py +260 -0
  78. achlens-0.1.0/tests/test_fixture_builders.py +43 -0
  79. achlens-0.1.0/tests/test_generator.py +92 -0
  80. achlens-0.1.0/tests/test_headers.py +152 -0
  81. achlens-0.1.0/tests/test_inputs.py +114 -0
  82. achlens-0.1.0/tests/test_layouts.py +64 -0
  83. achlens-0.1.0/tests/test_lines.py +68 -0
  84. achlens-0.1.0/tests/test_masking.py +147 -0
  85. achlens-0.1.0/tests/test_parser.py +212 -0
  86. achlens-0.1.0/tests/test_repair.py +57 -0
  87. achlens-0.1.0/tests/test_rules.py +107 -0
  88. achlens-0.1.0/tests/test_security.py +85 -0
  89. achlens-0.1.0/tests/test_server_app.py +62 -0
  90. achlens-0.1.0/tests/test_smoke.py +6 -0
  91. achlens-0.1.0/tests/test_structural.py +126 -0
  92. achlens-0.1.0/tests/test_tools.py +193 -0
  93. achlens-0.1.0/tests/test_validation_snapshot.py +95 -0
  94. achlens-0.1.0/tests/test_validation_snapshot_context.py +46 -0
  95. achlens-0.1.0/tests/test_validation_snapshot_findings.py +56 -0
  96. achlens-0.1.0/tests/test_validator.py +93 -0
  97. achlens-0.1.0/uv.lock +1347 -0
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ quality:
9
+ runs-on: ${{ matrix.os }}
10
+ strategy:
11
+ matrix:
12
+ os: [ubuntu-latest, macos-latest]
13
+ python-version: ["3.11", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v5
16
+ - uses: astral-sh/setup-uv@v6
17
+ with:
18
+ version: latest
19
+ enable-cache: false
20
+ - name: Set up Python
21
+ run: uv python install ${{ matrix.python-version }}
22
+ - name: Install dependencies
23
+ run: uv sync --python ${{ matrix.python-version }}
24
+ - name: Ruff lint
25
+ run: uv run ruff check .
26
+ - name: Ruff format
27
+ run: uv run ruff format --check .
28
+ - name: Mypy
29
+ run: uv run mypy --strict src
30
+ - name: Tests
31
+ run: uv run pytest -q --cov=src/achlens --cov-fail-under=0
32
+ - name: Docs regeneration (Sprint 0 placeholder)
33
+ run: |
34
+ python -c "print('Docs regeneration placeholder: no generator exists in Sprint 0')"
35
+ - name: Dependency audit
36
+ run: uv run pip-audit
@@ -0,0 +1,65 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+ id-token: write
11
+
12
+ jobs:
13
+ build:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v5
17
+ - uses: astral-sh/setup-uv@v6
18
+ with:
19
+ version: latest
20
+ enable-cache: false
21
+ - name: Set up Python
22
+ run: uv python install 3.12
23
+ - name: Build package
24
+ run: uv build
25
+ - name: Check package metadata
26
+ run: uv run --with twine twine check dist/*
27
+ - name: Smoke-test packaged CLI
28
+ run: uv run --with build python scripts/package_smoke_test.py
29
+ - name: Upload artifacts
30
+ uses: actions/upload-artifact@v4
31
+ with:
32
+ name: python-package
33
+ path: dist/*
34
+
35
+ publish:
36
+ needs: build
37
+ runs-on: ubuntu-latest
38
+ environment:
39
+ name: pypi
40
+ url: https://pypi.org/p/achlens
41
+ permissions:
42
+ id-token: write
43
+ steps:
44
+ - uses: actions/download-artifact@v4
45
+ with:
46
+ name: python-package
47
+ path: dist
48
+ - name: Publish to PyPI
49
+ uses: pypa/gh-action-pypi-publish@release/v1
50
+ with:
51
+ packages-dir: dist/
52
+
53
+ github-release:
54
+ needs: publish
55
+ runs-on: ubuntu-latest
56
+ permissions:
57
+ contents: write
58
+ steps:
59
+ - uses: actions/checkout@v5
60
+ with:
61
+ fetch-depth: 0
62
+ - name: Create GitHub release
63
+ env:
64
+ GH_TOKEN: ${{ github.token }}
65
+ run: gh release create "${GITHUB_REF_NAME}" --generate-notes
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyd
5
+ *.so
6
+ .Python
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ venv/
11
+ env/
12
+ ENV/
13
+
14
+ # Test and tool caches
15
+ .pytest_cache/
16
+ .mypy_cache/
17
+ .ruff_cache/
18
+ .coverage
19
+ htmlcov/
20
+ .hypothesis/
21
+
22
+ # Build artifacts
23
+ build/
24
+ dist/
25
+ *.egg-info/
26
+
27
+ # Local configuration and secrets
28
+ .env
29
+ .env.*
30
+ !.env.example
31
+
32
+ # uv
33
+ .uv/
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ - Added the Sprint 0 repository foundation and CLI entry point.
@@ -0,0 +1,5 @@
1
+ # Contributing
2
+
3
+ Install development dependencies with `uv sync`, then run the quality checks
4
+ listed in `README.md`. Keep foundation changes small and use synthetic data
5
+ only.
achlens-0.1.0/LICENSE ADDED
@@ -0,0 +1,154 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship. For the purposes
43
+ of this License, Derivative Works shall not include works that remain
44
+ separable from, or merely link (or bind by name) to the interfaces of,
45
+ the Work and Derivative Works thereof.
46
+
47
+ "Contribution" shall mean any work of authorship, including
48
+ the original version of the Work and any modifications or additions
49
+ to that Work or Derivative Works thereof, that is intentionally
50
+ submitted to Licensor for inclusion in the Work by the copyright owner
51
+ or by an individual or Legal Entity authorized to submit on behalf of
52
+ the copyright owner. For the purposes of this definition, "submitted"
53
+ means any form of electronic, verbal, or written communication sent
54
+ to the Licensor or its representatives, including but not limited to
55
+ communication on electronic mailing lists, source code control systems,
56
+ and issue tracking systems that are managed by, or on behalf of, the
57
+ Licensor for the purpose of discussing and improving the Work, but
58
+ excluding communication that is conspicuously marked or otherwise
59
+ designated in writing by the copyright owner as "Not a Contribution."
60
+
61
+ "Contributor" shall mean Licensor and any individual or Legal Entity
62
+ on behalf of whom a Contribution has been received by Licensor and
63
+ subsequently incorporated within the Work.
64
+
65
+ 2. Grant of Copyright License. Subject to the terms and conditions of
66
+ this License, each Contributor hereby grants to You a perpetual,
67
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68
+ copyright license to reproduce, prepare Derivative Works of,
69
+ publicly display, publicly perform, sublicense, and distribute the
70
+ Work and such Derivative Works in Source or Object form.
71
+
72
+ 3. Grant of Patent License. Subject to the terms and conditions of
73
+ this License, each Contributor hereby grants to You a perpetual,
74
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75
+ (except as stated in this section) patent license to make, have made,
76
+ use, offer to sell, sell, import, and otherwise transfer the Work,
77
+ where such license applies only to those patent claims licensable
78
+ by such Contributor that are necessarily infringed by their
79
+ Contribution(s) alone or by combination of their Contribution(s)
80
+ with the Work to which such Contribution(s) was submitted.
81
+
82
+ 4. Redistribution. You may reproduce and distribute copies of the
83
+ Work or Derivative Works thereof in any medium, with or without
84
+ modifications, and in Source or Object form, provided that You meet
85
+ the following conditions:
86
+
87
+ (a) You must give any other recipients of the Work or Derivative Works
88
+ a copy of this License; and
89
+
90
+ (b) You must cause any modified files to carry prominent notices
91
+ stating that You changed the files; and
92
+
93
+ (c) You must retain, in the Source form of any Derivative Works that
94
+ You distribute, all copyright, patent, trademark, and attribution
95
+ notices from the Source form of the Work, excluding those notices
96
+ that do not pertain to any part of the Derivative Works; and
97
+
98
+ (d) If the Work includes a "NOTICE" text file as part of its
99
+ distribution, then any Derivative Works that You distribute must
100
+ include a readable copy of the attribution notices contained
101
+ within such NOTICE file, excluding those notices that do not
102
+ pertain to any part of the Derivative Works, in at least one
103
+ of the following places: within a NOTICE text file distributed
104
+ as part of the Derivative Works; within the Source form or
105
+ documentation, if provided along with the Derivative Works; or,
106
+ within a display generated by the Derivative Works, if and
107
+ wherever such third-party notices normally appear.
108
+
109
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
110
+ any Contribution intentionally submitted for inclusion in the Work
111
+ by You to the Licensor shall be under the terms and conditions of
112
+ this License, without any additional terms or conditions.
113
+
114
+ 6. Trademarks. This License does not grant permission to use the trade
115
+ names, trademarks, service marks, or product names of the Licensor,
116
+ except as required for reasonable and customary use in describing the
117
+ origin of the Work and reproducing the content of the NOTICE file.
118
+
119
+ 7. Disclaimer of Warranty. Unless required by applicable law or
120
+ agreed to in writing, Licensor provides the Work (and each
121
+ Contributor provides its Contributions) on an "AS IS" BASIS,
122
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
123
+ implied, including, without limitation, any warranties or conditions
124
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
125
+ PARTICULAR PURPOSE. You are solely responsible for determining the
126
+ appropriateness of using or redistributing the Work and assume any
127
+ risks associated with Your exercise of permissions under this License.
128
+
129
+ 8. Limitation of Liability. In no event and under no legal theory,
130
+ whether in tort (including negligence), contract, or otherwise,
131
+ unless required by applicable law (such as deliberate and grossly
132
+ negligent acts) or agreed to in writing, shall any Contributor be
133
+ liable to You for damages, including any direct, indirect, special,
134
+ incidental, or consequential damages of any character arising as a
135
+ result of this License or out of the use or inability to use the
136
+ Work (including but not limited to damages for loss of goodwill,
137
+ work stoppage, computer failure or malfunction, or any and all
138
+ other commercial damages or losses), even if such Contributor
139
+ has been advised of the possibility of such damages.
140
+
141
+ 9. Accepting Warranty or Additional Liability. While redistributing
142
+ the Work or Derivative Works thereof, You may choose to offer,
143
+ and charge a fee for, acceptance of support, warranty, indemnity,
144
+ or other liability obligations and/or rights consistent with this
145
+ License. However, in accepting such obligations, You may act only
146
+ on Your own behalf and on Your sole responsibility, not on behalf
147
+ of any other Contributor, and only if You agree to indemnify,
148
+ defend, and hold each Contributor harmless for any liability
149
+ incurred by, or claims asserted against, such Contributor by reason
150
+ of your accepting any such warranty or additional liability.
151
+
152
+ END OF TERMS AND CONDITIONS
153
+
154
+ Copyright 2026 achlens contributors
achlens-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,216 @@
1
+ Metadata-Version: 2.5
2
+ Name: achlens
3
+ Version: 0.1.0
4
+ Summary: A local-first ACH file validation foundation.
5
+ Author: achlens contributors
6
+ License: Apache License
7
+ Version 2.0, January 2004
8
+ http://www.apache.org/licenses/
9
+
10
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
11
+
12
+ 1. Definitions.
13
+
14
+ "License" shall mean the terms and conditions for use, reproduction,
15
+ and distribution as defined by Sections 1 through 9 of this document.
16
+
17
+ "Licensor" shall mean the copyright owner or entity authorized by
18
+ the copyright owner that is granting the License.
19
+
20
+ "Legal Entity" shall mean the union of the acting entity and all
21
+ other entities that control, are controlled by, or are under common
22
+ control with that entity. For the purposes of this definition,
23
+ "control" means (i) the power, direct or indirect, to cause the
24
+ direction or management of such entity, whether by contract or
25
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
26
+ outstanding shares, or (iii) beneficial ownership of such entity.
27
+
28
+ "You" (or "Your") shall mean an individual or Legal Entity
29
+ exercising permissions granted by this License.
30
+
31
+ "Source" form shall mean the preferred form for making modifications,
32
+ including but not limited to software source code, documentation
33
+ source, and configuration files.
34
+
35
+ "Object" form shall mean any form resulting from mechanical
36
+ transformation or translation of a Source form, including but
37
+ not limited to compiled object code, generated documentation,
38
+ and conversions to other media types.
39
+
40
+ "Work" shall mean the work of authorship, whether in Source or
41
+ Object form, made available under the License, as indicated by a
42
+ copyright notice that is included in or attached to the work.
43
+
44
+ "Derivative Works" shall mean any work, whether in Source or Object
45
+ form, that is based on (or derived from) the Work and for which the
46
+ editorial revisions, annotations, elaborations, or other modifications
47
+ represent, as a whole, an original work of authorship. For the purposes
48
+ of this License, Derivative Works shall not include works that remain
49
+ separable from, or merely link (or bind by name) to the interfaces of,
50
+ the Work and Derivative Works thereof.
51
+
52
+ "Contribution" shall mean any work of authorship, including
53
+ the original version of the Work and any modifications or additions
54
+ to that Work or Derivative Works thereof, that is intentionally
55
+ submitted to Licensor for inclusion in the Work by the copyright owner
56
+ or by an individual or Legal Entity authorized to submit on behalf of
57
+ the copyright owner. For the purposes of this definition, "submitted"
58
+ means any form of electronic, verbal, or written communication sent
59
+ to the Licensor or its representatives, including but not limited to
60
+ communication on electronic mailing lists, source code control systems,
61
+ and issue tracking systems that are managed by, or on behalf of, the
62
+ Licensor for the purpose of discussing and improving the Work, but
63
+ excluding communication that is conspicuously marked or otherwise
64
+ designated in writing by the copyright owner as "Not a Contribution."
65
+
66
+ "Contributor" shall mean Licensor and any individual or Legal Entity
67
+ on behalf of whom a Contribution has been received by Licensor and
68
+ subsequently incorporated within the Work.
69
+
70
+ 2. Grant of Copyright License. Subject to the terms and conditions of
71
+ this License, each Contributor hereby grants to You a perpetual,
72
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
73
+ copyright license to reproduce, prepare Derivative Works of,
74
+ publicly display, publicly perform, sublicense, and distribute the
75
+ Work and such Derivative Works in Source or Object form.
76
+
77
+ 3. Grant of Patent License. Subject to the terms and conditions of
78
+ this License, each Contributor hereby grants to You a perpetual,
79
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
80
+ (except as stated in this section) patent license to make, have made,
81
+ use, offer to sell, sell, import, and otherwise transfer the Work,
82
+ where such license applies only to those patent claims licensable
83
+ by such Contributor that are necessarily infringed by their
84
+ Contribution(s) alone or by combination of their Contribution(s)
85
+ with the Work to which such Contribution(s) was submitted.
86
+
87
+ 4. Redistribution. You may reproduce and distribute copies of the
88
+ Work or Derivative Works thereof in any medium, with or without
89
+ modifications, and in Source or Object form, provided that You meet
90
+ the following conditions:
91
+
92
+ (a) You must give any other recipients of the Work or Derivative Works
93
+ a copy of this License; and
94
+
95
+ (b) You must cause any modified files to carry prominent notices
96
+ stating that You changed the files; and
97
+
98
+ (c) You must retain, in the Source form of any Derivative Works that
99
+ You distribute, all copyright, patent, trademark, and attribution
100
+ notices from the Source form of the Work, excluding those notices
101
+ that do not pertain to any part of the Derivative Works; and
102
+
103
+ (d) If the Work includes a "NOTICE" text file as part of its
104
+ distribution, then any Derivative Works that You distribute must
105
+ include a readable copy of the attribution notices contained
106
+ within such NOTICE file, excluding those notices that do not
107
+ pertain to any part of the Derivative Works, in at least one
108
+ of the following places: within a NOTICE text file distributed
109
+ as part of the Derivative Works; within the Source form or
110
+ documentation, if provided along with the Derivative Works; or,
111
+ within a display generated by the Derivative Works, if and
112
+ wherever such third-party notices normally appear.
113
+
114
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
115
+ any Contribution intentionally submitted for inclusion in the Work
116
+ by You to the Licensor shall be under the terms and conditions of
117
+ this License, without any additional terms or conditions.
118
+
119
+ 6. Trademarks. This License does not grant permission to use the trade
120
+ names, trademarks, service marks, or product names of the Licensor,
121
+ except as required for reasonable and customary use in describing the
122
+ origin of the Work and reproducing the content of the NOTICE file.
123
+
124
+ 7. Disclaimer of Warranty. Unless required by applicable law or
125
+ agreed to in writing, Licensor provides the Work (and each
126
+ Contributor provides its Contributions) on an "AS IS" BASIS,
127
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
128
+ implied, including, without limitation, any warranties or conditions
129
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
130
+ PARTICULAR PURPOSE. You are solely responsible for determining the
131
+ appropriateness of using or redistributing the Work and assume any
132
+ risks associated with Your exercise of permissions under this License.
133
+
134
+ 8. Limitation of Liability. In no event and under no legal theory,
135
+ whether in tort (including negligence), contract, or otherwise,
136
+ unless required by applicable law (such as deliberate and grossly
137
+ negligent acts) or agreed to in writing, shall any Contributor be
138
+ liable to You for damages, including any direct, indirect, special,
139
+ incidental, or consequential damages of any character arising as a
140
+ result of this License or out of the use or inability to use the
141
+ Work (including but not limited to damages for loss of goodwill,
142
+ work stoppage, computer failure or malfunction, or any and all
143
+ other commercial damages or losses), even if such Contributor
144
+ has been advised of the possibility of such damages.
145
+
146
+ 9. Accepting Warranty or Additional Liability. While redistributing
147
+ the Work or Derivative Works thereof, You may choose to offer,
148
+ and charge a fee for, acceptance of support, warranty, indemnity,
149
+ or other liability obligations and/or rights consistent with this
150
+ License. However, in accepting such obligations, You may act only
151
+ on Your own behalf and on Your sole responsibility, not on behalf
152
+ of any other Contributor, and only if You agree to indemnify,
153
+ defend, and hold each Contributor harmless for any liability
154
+ incurred by, or claims asserted against, such Contributor by reason
155
+ of your accepting any such warranty or additional liability.
156
+
157
+ END OF TERMS AND CONDITIONS
158
+
159
+ Copyright 2026 achlens contributors
160
+ License-File: LICENSE
161
+ Requires-Python: <3.14,>=3.11
162
+ Requires-Dist: mcp<3.0,>=2.2
163
+ Requires-Dist: pyyaml<7.0,>=6.0
164
+ Requires-Dist: typer<1.0,>=0.12
165
+ Description-Content-Type: text/markdown
166
+
167
+ # achlens
168
+
169
+ <!-- mcp-name: io.github.mscott9160-web/achlens -->
170
+
171
+ achlens is a local-first Python MCP server and CLI for inspecting synthetic ACH
172
+ files. It parses fixed-width records, validates structure and control totals,
173
+ explains findings, masks sensitive fields, repairs derived controls, and
174
+ generates deterministic test files. It never transmits ACH files or makes
175
+ bank/network calls.
176
+
177
+ Use synthetic data only. This project is not a bank gateway, compliance
178
+ advisor, or transmission system.
179
+
180
+ ## Quick Start
181
+
182
+ ```text
183
+ uv sync
184
+ uv run achlens --help
185
+ uv run achlens validate tests/fixtures/golden/sample_valid.ach
186
+ uv run achlens generate --sec PPD --entries 5 --seed 7 > synthetic.ach
187
+ ```
188
+
189
+ Run the MCP server over stdio:
190
+
191
+ ```text
192
+ uv run achlens serve
193
+ ```
194
+
195
+ The MCP server exposes validation, summaries, parsed-record paging, control
196
+ explanations, routing checks, code lookup, synthetic generation, and control
197
+ repair. See [docs/tools.md](docs/tools.md) for the current tool surface.
198
+
199
+ Sensitive fields are masked by default. Configure `ACHLENS_ALLOWED_ROOTS` to
200
+ enable MCP path inputs; otherwise provide file content directly. See
201
+ [SECURITY.md](SECURITY.md) for the data and write boundaries.
202
+
203
+ ## Development
204
+
205
+ This project uses [uv](https://docs.astral.sh/uv/).
206
+
207
+ ```text
208
+ uv sync
209
+ uv run achlens --help
210
+ uv run pytest -q
211
+ uv run ruff check .
212
+ uv run ruff format --check .
213
+ uv run mypy --strict src
214
+ ```
215
+
216
+ Never add real payment data, account numbers, or ACH files to this repository.
@@ -0,0 +1,50 @@
1
+ # achlens
2
+
3
+ <!-- mcp-name: io.github.mscott9160-web/achlens -->
4
+
5
+ achlens is a local-first Python MCP server and CLI for inspecting synthetic ACH
6
+ files. It parses fixed-width records, validates structure and control totals,
7
+ explains findings, masks sensitive fields, repairs derived controls, and
8
+ generates deterministic test files. It never transmits ACH files or makes
9
+ bank/network calls.
10
+
11
+ Use synthetic data only. This project is not a bank gateway, compliance
12
+ advisor, or transmission system.
13
+
14
+ ## Quick Start
15
+
16
+ ```text
17
+ uv sync
18
+ uv run achlens --help
19
+ uv run achlens validate tests/fixtures/golden/sample_valid.ach
20
+ uv run achlens generate --sec PPD --entries 5 --seed 7 > synthetic.ach
21
+ ```
22
+
23
+ Run the MCP server over stdio:
24
+
25
+ ```text
26
+ uv run achlens serve
27
+ ```
28
+
29
+ The MCP server exposes validation, summaries, parsed-record paging, control
30
+ explanations, routing checks, code lookup, synthetic generation, and control
31
+ repair. See [docs/tools.md](docs/tools.md) for the current tool surface.
32
+
33
+ Sensitive fields are masked by default. Configure `ACHLENS_ALLOWED_ROOTS` to
34
+ enable MCP path inputs; otherwise provide file content directly. See
35
+ [SECURITY.md](SECURITY.md) for the data and write boundaries.
36
+
37
+ ## Development
38
+
39
+ This project uses [uv](https://docs.astral.sh/uv/).
40
+
41
+ ```text
42
+ uv sync
43
+ uv run achlens --help
44
+ uv run pytest -q
45
+ uv run ruff check .
46
+ uv run ruff format --check .
47
+ uv run mypy --strict src
48
+ ```
49
+
50
+ Never add real payment data, account numbers, or ACH files to this repository.
@@ -0,0 +1,38 @@
1
+ # Security
2
+
3
+ `achlens` is local-first software for inspecting synthetic ACH files. It does
4
+ not transmit files, connect to banks, or make outbound network calls as part of
5
+ its runtime tools.
6
+
7
+ ## Data Rules
8
+
9
+ - Never report or commit real payment data, account numbers, routing/account
10
+ pairs, or real ACH files.
11
+ - Use generated fixtures and the synthetic generator for tests and examples.
12
+ - Sensitive parsed fields are masked by default: account numbers, individual
13
+ identification numbers, and NOC corrected data expose only a masked value
14
+ with the final four characters preserved.
15
+ - Reveal behavior is disabled unless `ACHLENS_ALLOW_REVEAL=1` is explicitly
16
+ configured by the local operator.
17
+
18
+ ## File Access
19
+
20
+ MCP path inputs are disabled unless `ACHLENS_ALLOWED_ROOTS` is configured.
21
+ Configured paths are resolved before checking containment, so `..` traversal
22
+ and symlink escapes are rejected. Directories, missing paths, non-UTF-8 files,
23
+ and files above `ACHLENS_MAX_BYTES` are rejected.
24
+
25
+ The CLI accepts explicit local paths because it is a user-run command-line
26
+ program. MCP path access remains subject to the allowlist.
27
+
28
+ ## Writes
29
+
30
+ Only the repair tool writes files. Path-mode repair writes a new sibling file
31
+ with a `.repaired` suffix and refuses to overwrite an existing output. It does
32
+ not return repaired file content in path mode.
33
+
34
+ ## Reporting
35
+
36
+ Report suspected vulnerabilities privately through the repository's GitHub
37
+ security channel. Do not include real ACH content in an issue, pull request,
38
+ log, or test fixture.
@@ -0,0 +1,18 @@
1
+ # ADR 001: Python and MCP SDK
2
+
3
+ ## Context
4
+
5
+ The project needs a supported Python runtime and an official MCP integration
6
+ path. Sprint 0 must remain usable without implementing or importing MCP.
7
+
8
+ ## Decision
9
+
10
+ Use Python >=3.12,<3.14 for local scaffolding. The future MCP adapter will use
11
+ the official `mcp` package and FastMCP interface, pinned when that adapter is
12
+ implemented.
13
+
14
+ ## Consequences
15
+
16
+ The package has a clear runtime range and can ship a CLI without an MCP
17
+ dependency today. CI also exercises the specified 3.11, 3.12, and 3.13 matrix;
18
+ the Python 3.11 compatibility decision must be reconciled before release.
@@ -0,0 +1,17 @@
1
+ # ADR 002: Layered Architecture
2
+
3
+ ## Context
4
+
5
+ ACH domain logic, MCP protocol behavior, and command-line behavior have
6
+ different testing and reuse needs.
7
+
8
+ ## Decision
9
+
10
+ Use a pure core library, a thin MCP adapter, and a thin CLI. The core must not
11
+ import the MCP SDK.
12
+
13
+ ## Consequences
14
+
15
+ Core behavior can be tested independently of protocol concerns. The project
16
+ has explicit boundaries to maintain when later sprints add parser and server
17
+ features.
@@ -0,0 +1,17 @@
1
+ # ADR 003: Data-Driven Record Layouts
2
+
3
+ ## Context
4
+
5
+ ACH records have fixed-width fields that must be shared by parsing, building,
6
+ documentation, and tests.
7
+
8
+ ## Decision
9
+
10
+ Represent record layouts as data in `ach_layouts.yaml`, rather than encoding
11
+ field positions directly in Python logic.
12
+
13
+ ## Consequences
14
+
15
+ One layout definition can drive multiple features and reduce duplicated
16
+ position logic. Layout verification is deferred to CORE-01 and no layout data
17
+ is included in Sprint 0.