solomons-sword 0.1.3__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.
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+ indent_style = space
9
+ indent_size = 4
10
+
11
+ [*.{yml,yaml,json,md,toml}]
12
+ indent_size = 2
13
+
14
+ [*.md]
15
+ trim_trailing_whitespace = false
@@ -0,0 +1 @@
1
+ * @ryanduguid
@@ -0,0 +1,32 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "github-actions"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ groups:
8
+ github-actions:
9
+ patterns:
10
+ - "*"
11
+ codeql-action:
12
+ patterns:
13
+ - "github/codeql-action*"
14
+ ignore:
15
+ # ADR-0001: the release-policy pin is an immutable full commit SHA,
16
+ # advanced only by a reviewed migration that also updates the pin
17
+ # assertion and verifies attestations against the new signer workflow.
18
+ # Dependabot can do neither, so its bumps are refused by the pin tests
19
+ # and sit red forever. Pin drift is tracked by release-policy's canary
20
+ # audit instead.
21
+ - dependency-name: "ryanduguid/release-policy/.github/workflows/*"
22
+ - package-ecosystem: "uv"
23
+ directory: "/"
24
+ schedule:
25
+ interval: "weekly"
26
+ cooldown:
27
+ default-days: 7
28
+ open-pull-requests-limit: 2
29
+ groups:
30
+ python:
31
+ patterns:
32
+ - "*"
@@ -0,0 +1,49 @@
1
+ name: tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: tests-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ test:
17
+ name: pytest
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python: ["3.10", "3.11", "3.12", "3.13"]
22
+ runs-on: ubuntu-latest
23
+ timeout-minutes: 15
24
+ permissions:
25
+ contents: read
26
+ steps:
27
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
28
+ with:
29
+ persist-credentials: false
30
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
31
+ with:
32
+ python-version: ${{ matrix.python }}
33
+ - name: install the locked toolchain
34
+ uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
35
+ with:
36
+ version: "0.12.0"
37
+ enable-cache: true
38
+ - name: Ruff
39
+ run: uv run --locked --extra dev ruff check louisgoldberg tests
40
+ env:
41
+ UV_PYTHON: ${{ matrix.python }}
42
+ - name: Typecheck
43
+ run: uv run --locked --extra dev mypy louisgoldberg
44
+ env:
45
+ UV_PYTHON: ${{ matrix.python }}
46
+ - name: Run tests
47
+ run: uv run --locked --extra dev pytest -q
48
+ env:
49
+ UV_PYTHON: ${{ matrix.python }}
@@ -0,0 +1,38 @@
1
+ name: CodeQL
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ schedule:
9
+ - cron: "23 3 * * 1"
10
+ workflow_dispatch:
11
+
12
+ permissions:
13
+ contents: read
14
+
15
+ jobs:
16
+ analyze:
17
+ name: Analyze Python
18
+ runs-on: ubuntu-latest
19
+ timeout-minutes: 30
20
+ permissions:
21
+ contents: read
22
+ security-events: write # Upload CodeQL results for this job only.
23
+ steps:
24
+ - name: Check out source
25
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
26
+ with:
27
+ persist-credentials: false
28
+
29
+ - name: Initialise CodeQL
30
+ uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4
31
+ with:
32
+ languages: python
33
+ build-mode: none
34
+
35
+ - name: Perform CodeQL analysis
36
+ uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4
37
+ with:
38
+ category: "/language:python"
@@ -0,0 +1,22 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+
11
+ # Unit test / coverage
12
+ .pytest_cache/
13
+ .coverage
14
+ htmlcov/
15
+
16
+ # Environments
17
+ .env
18
+ .venv
19
+ env/
20
+ venv/
21
+ .env.*
22
+ !.env.example
@@ -0,0 +1,4 @@
1
+ # Canonical commit identity for Ryan Duguid.
2
+ Ryan Duguid <ryan@duguid.com.au> <152749594+ryanduguid@users.noreply.github.com>
3
+ Ryan Duguid <ryan@duguid.com.au> <ryanduguid@users.noreply.github.com>
4
+ Ryan Duguid <ryan@duguid.com.au> <noreply@duguid.com.au>
@@ -0,0 +1,46 @@
1
+ # Disclaimer
2
+
3
+ Solomon's Sword allocates trust income on proportionate entitlement under
4
+ Division 6 of the ITAA 1936 and evaluates caller-supplied facts against
5
+ Section 100A, Section 99B and 30 June resolution requirements. It is not tax,
6
+ legal, accounting, financial, investment, BAS-agent, registered-tax-agent, or
7
+ assurance advice. It is not an assessment, a private ruling, or a
8
+ determination.
9
+
10
+ This project is not affiliated with, sponsored by, endorsed by, or approved by:
11
+
12
+ - the Australian Taxation Office
13
+ - the Commonwealth of Australia
14
+ - any state or territory revenue office
15
+ - Chartered Accountants Australia and New Zealand
16
+ - any law firm, court, or tribunal
17
+
18
+ Outputs can be wrong, incomplete, stale, or unsuitable for a given set of
19
+ facts. Tax law, ATO guidance, practical compliance guidelines, rates and
20
+ thresholds change, and the engine sees only the facts it is handed. Confirm
21
+ every allocation, zone and exemption against the current law, the trust deed
22
+ and the entity's facts before acting, and leave lodgment decisions with a
23
+ registered practitioner.
24
+
25
+ Coverage is deliberately partial. Specifically streamed capital gains and
26
+ franked dividends, non-resident beneficiaries under s 98(2A) and s 98(3), nil
27
+ income of the trust estate, and s 99 or s 99A cases are refused rather than
28
+ allocated, because the Division 6E carve-out with Subdivision 115-C and
29
+ Subdivision 207-B is not implemented. A refusal is the engine declining to
30
+ answer, not a finding that no amount is assessable. The Section 100A matrix
31
+ returns only the zones the engine implements and does not decide the white
32
+ zone.
33
+
34
+ Nothing here lodges a trust tax return, a distribution statement, or any other
35
+ official form, posts journals, or sends client correspondence. Workpapers and
36
+ calculations are draft preparation artefacts.
37
+
38
+ Command output carries the beneficiary name supplied to it. Treat that output
39
+ as client data, write it to the firm's approved secure location, and never to
40
+ a path inside a repository. Do not publish private tax records, trust deeds,
41
+ TFNs, Medicare numbers, bank details, identity documents, or other sensitive
42
+ personal information in issues, pull requests, examples, tests, or repository
43
+ content. Fixtures in this repository are fabricated.
44
+
45
+ See [LICENSE](LICENSE) for copyright and [SECURITY.md](SECURITY.md) for
46
+ vulnerability reporting.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ryan Duguid
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.5
2
+ Name: solomons-sword
3
+ Version: 0.1.3
4
+ Summary: Trust distribution allocation, Section 100A / 99B risk evaluation, and Division 6 ITAA 1936 compliance for Australian trusts.
5
+ Project-URL: Homepage, https://github.com/ryanduguid/australian-accounting/tree/main/packages/solomons-sword
6
+ Project-URL: Repository, https://github.com/ryanduguid/australian-accounting/tree/main/packages/solomons-sword
7
+ Project-URL: Issues, https://github.com/ryanduguid/australian-accounting/issues
8
+ Author-email: Ryan Duguid <ryan@duguid.com.au>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: accounting,australian-tax,bamford,division-6,itaa1936,section-100a,section-99b,trust-accounting
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Financial and Insurance Industry
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Office/Business :: Financial :: Accounting
20
+ Requires-Python: >=3.10
21
+ Provides-Extra: dev
22
+ Requires-Dist: build>=1.2; extra == 'dev'
23
+ Requires-Dist: mypy>=1.14; extra == 'dev'
24
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
25
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
26
+ Requires-Dist: ruff>=0.11; extra == 'dev'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # Solomon's Sword
30
+
31
+ ```
32
+ +----------------------------------------------------------------------+
33
+ | SolomonsSword |
34
+ +----------------------------------------------------------------------+
35
+ | Division 6, s100A and s99B trust review tools |
36
+ +----------------------------------+-----------------------------------+
37
+ | DR what it gives you | CR what it needs |
38
+ +----------------------------------+-----------------------------------+
39
+ | s100A green red risk zones | beneficiary and amount data |
40
+ | s99B foreign trust review | trust facts like corpus value |
41
+ | Division 6 allocation review | - |
42
+ +----------------------------------+-----------------------------------+
43
+ ```
44
+
45
+ [![Python](https://img.shields.io/badge/Python-3.10+-5C2D91?logo=python&logoColor=white&labelColor=04001F)](https://www.python.org/)
46
+ [![tests](https://github.com/ryanduguid/australian-accounting/actions/workflows/ci-solomons-sword.yml/badge.svg)](https://github.com/ryanduguid/australian-accounting/actions/workflows/ci-solomons-sword.yml)
47
+ [![PyPI](https://img.shields.io/pypi/v/solomons-sword.svg?color=5C2D91&labelColor=04001F)](https://pypi.org/project/solomons-sword/)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-4F485E.svg?labelColor=04001F)](https://opensource.org/licenses/MIT)
49
+ [![ITAA 1936](https://img.shields.io/badge/Legislation-ITAA%201936%20Division%206-5C2D91?labelColor=04001F)](https://www.legislation.gov.au/C1936A00027/latest/text)
50
+
51
+ **Trust distribution allocation, Section 100A / 99B risk evaluation, and Division 6 ITAA 1936 review helpers for Australian trusts.**
52
+
53
+ **Package lifecycle:** published. Install `solomons-sword` from PyPI.
54
+
55
+ The `australian-accounting` repository contains the maintained source. The
56
+ `solomons-sword` distribution and command match the project identity. The
57
+ `louisgoldberg` import package remains unchanged, so internal Python imports do
58
+ not need a rename.
59
+
60
+ Release: [`v0.1.3`](https://github.com/ryanduguid/australian-accounting/releases/tag/solomons-sword/v0.1.3).
61
+
62
+ Named for the judgement of Solomon, where the threat of dividing the child in proportion is what reveals who the true claimant is. Division 6 allocates trust income by proportionate entitlement following *Bamford*; Section 100A asks who actually ended up with the benefit. The name is a tribute only.
63
+
64
+
65
+ ## Not advice
66
+
67
+ Nothing this engine produces is tax, legal or financial advice, an assessment or
68
+ a determination. Outputs are review aids: confirm every allocation, zone and
69
+ exemption against the current law, the trust deed and the entity's facts before
70
+ acting, and leave lodgment decisions with a registered practitioner. Where the
71
+ model does not implement a rule it refuses the input rather than returning a
72
+ number it cannot stand behind.
73
+
74
+ Command output carries the beneficiary name you supply, because a workpaper line
75
+ item is unusable without it. Treat that output as client data: write it to the
76
+ firm's approved secure location, never to a path inside a repository.
77
+
78
+ Full boundary statement: [DISCLAIMER.md](https://github.com/ryanduguid/australian-accounting/blob/main/packages/solomons-sword/DISCLAIMER.md).
79
+
80
+ ---
81
+
82
+ ## Core Features
83
+
84
+ - **Division 6 Proportionate Allocation (*Commissioner of Taxation v Bamford* [2010] HCA 10)**: Calculates present entitlement proportions and allocates *s 95(1) ITAA 1936* taxable net income and the franking credits that ride with it. Specifically streamed capital gains and franked dividends are **refused**, not allocated: the Division 6E carve-out with *Subdivision 115-C* (including s 115-220) and *Subdivision 207-B* is not implemented, so a proportionate answer would be wrong. Non-resident beneficiaries (*s 98(2A)/(3)*), nil income of the trust estate and no presently entitled beneficiary (*s 99 / s 99A*) are refused for the same reason.
85
+ - **Section 100A Reimbursement Agreement Matrix**: Classifies supplied facts against **ATO PCG 2022/2** as Green, Red, or outside those zones. The final guideline has white, green and red; the draft blue zone did not survive. White zone (income years ending before 1 July 2014) is out of scope because the function does not take an income year.
86
+ - **Section 99B Foreign Trust Receipt Assessment**: Computes assessable amounts under *s 99B(1)* after corpus exemptions (*s 99B(2)(a)*) and prior-taxed income.
87
+ - **Trust Resolution 30 June Schedule Verifier**: Checks timing, deed-power and percentage-completeness facts the caller supplies.
88
+
89
+ ---
90
+
91
+ ## Quickstart
92
+
93
+ ### Installation
94
+ ```bash
95
+ pip install solomons-sword
96
+ ```
97
+
98
+ ### CLI Usage
99
+ ```bash
100
+ # Evaluate Section 100A risk zone
101
+ solomons-sword s100a-check --beneficiary "Adult Child" --amount 40000 --adult-child --retained-by-parents
102
+
103
+ # Assess Section 99B receipt from foreign trust with corpus deduction
104
+ solomons-sword s99b-check --beneficiary "Jane Doe" --gross 150000 --corpus 50000
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Statutory Ground Truth & Test Harness
110
+
111
+ All allocation and threshold algorithms use exact `decimal.Decimal` calculations to prevent rounding discrepancies in trust tax schedules.
112
+
113
+ | Statutory Domain | Primary Authority | What the code actually does |
114
+ | :--- | :--- | :--- |
115
+ | **Proportionate Entitlement** | *ITAA 1936* s 95, s 97 (*Commissioner of Taxation v Bamford* [2010] HCA 10) | `Beneficiary Share = (Accounting Entitlement / Total Accounting Income) * s95 Net Income`. |
116
+ | **Section 100A Risk Matrix** | *ITAA 1936* s 100A, *ATO PCG 2022/2* | Returns GREEN, RED or OUTSIDE_GREEN from the supplied flags. It does not decide the white zone. |
117
+ | **Foreign Trust Distributions** | *ITAA 1936* s 99B(1), s 99B(2)(a) | Subtracts settled corpus and previously taxed income prior to assessable inclusion. |
118
+ | **Trust Resolution Timing** | Caller-supplied deed and execution facts | Refuses incomplete percentages and missing deed facts. This is not a substitute for current ATO guidance. |
119
+
120
+ ### Automated Test Suite
121
+ - Run the suite: `pytest tests/`
122
+ - The suite covers proportionate streaming, Section 100A zones the engine implements, Section 99B corpus deductions, and resolution gates. Do not treat a badge as a live coverage certificate.
123
+
124
+ ---
125
+
126
+ ## Licence
127
+ MIT License. Created by Ryan Duguid.
@@ -0,0 +1,99 @@
1
+ # Solomon's Sword
2
+
3
+ ```
4
+ +----------------------------------------------------------------------+
5
+ | SolomonsSword |
6
+ +----------------------------------------------------------------------+
7
+ | Division 6, s100A and s99B trust review tools |
8
+ +----------------------------------+-----------------------------------+
9
+ | DR what it gives you | CR what it needs |
10
+ +----------------------------------+-----------------------------------+
11
+ | s100A green red risk zones | beneficiary and amount data |
12
+ | s99B foreign trust review | trust facts like corpus value |
13
+ | Division 6 allocation review | - |
14
+ +----------------------------------+-----------------------------------+
15
+ ```
16
+
17
+ [![Python](https://img.shields.io/badge/Python-3.10+-5C2D91?logo=python&logoColor=white&labelColor=04001F)](https://www.python.org/)
18
+ [![tests](https://github.com/ryanduguid/australian-accounting/actions/workflows/ci-solomons-sword.yml/badge.svg)](https://github.com/ryanduguid/australian-accounting/actions/workflows/ci-solomons-sword.yml)
19
+ [![PyPI](https://img.shields.io/pypi/v/solomons-sword.svg?color=5C2D91&labelColor=04001F)](https://pypi.org/project/solomons-sword/)
20
+ [![License: MIT](https://img.shields.io/badge/License-MIT-4F485E.svg?labelColor=04001F)](https://opensource.org/licenses/MIT)
21
+ [![ITAA 1936](https://img.shields.io/badge/Legislation-ITAA%201936%20Division%206-5C2D91?labelColor=04001F)](https://www.legislation.gov.au/C1936A00027/latest/text)
22
+
23
+ **Trust distribution allocation, Section 100A / 99B risk evaluation, and Division 6 ITAA 1936 review helpers for Australian trusts.**
24
+
25
+ **Package lifecycle:** published. Install `solomons-sword` from PyPI.
26
+
27
+ The `australian-accounting` repository contains the maintained source. The
28
+ `solomons-sword` distribution and command match the project identity. The
29
+ `louisgoldberg` import package remains unchanged, so internal Python imports do
30
+ not need a rename.
31
+
32
+ Release: [`v0.1.3`](https://github.com/ryanduguid/australian-accounting/releases/tag/solomons-sword/v0.1.3).
33
+
34
+ Named for the judgement of Solomon, where the threat of dividing the child in proportion is what reveals who the true claimant is. Division 6 allocates trust income by proportionate entitlement following *Bamford*; Section 100A asks who actually ended up with the benefit. The name is a tribute only.
35
+
36
+
37
+ ## Not advice
38
+
39
+ Nothing this engine produces is tax, legal or financial advice, an assessment or
40
+ a determination. Outputs are review aids: confirm every allocation, zone and
41
+ exemption against the current law, the trust deed and the entity's facts before
42
+ acting, and leave lodgment decisions with a registered practitioner. Where the
43
+ model does not implement a rule it refuses the input rather than returning a
44
+ number it cannot stand behind.
45
+
46
+ Command output carries the beneficiary name you supply, because a workpaper line
47
+ item is unusable without it. Treat that output as client data: write it to the
48
+ firm's approved secure location, never to a path inside a repository.
49
+
50
+ Full boundary statement: [DISCLAIMER.md](https://github.com/ryanduguid/australian-accounting/blob/main/packages/solomons-sword/DISCLAIMER.md).
51
+
52
+ ---
53
+
54
+ ## Core Features
55
+
56
+ - **Division 6 Proportionate Allocation (*Commissioner of Taxation v Bamford* [2010] HCA 10)**: Calculates present entitlement proportions and allocates *s 95(1) ITAA 1936* taxable net income and the franking credits that ride with it. Specifically streamed capital gains and franked dividends are **refused**, not allocated: the Division 6E carve-out with *Subdivision 115-C* (including s 115-220) and *Subdivision 207-B* is not implemented, so a proportionate answer would be wrong. Non-resident beneficiaries (*s 98(2A)/(3)*), nil income of the trust estate and no presently entitled beneficiary (*s 99 / s 99A*) are refused for the same reason.
57
+ - **Section 100A Reimbursement Agreement Matrix**: Classifies supplied facts against **ATO PCG 2022/2** as Green, Red, or outside those zones. The final guideline has white, green and red; the draft blue zone did not survive. White zone (income years ending before 1 July 2014) is out of scope because the function does not take an income year.
58
+ - **Section 99B Foreign Trust Receipt Assessment**: Computes assessable amounts under *s 99B(1)* after corpus exemptions (*s 99B(2)(a)*) and prior-taxed income.
59
+ - **Trust Resolution 30 June Schedule Verifier**: Checks timing, deed-power and percentage-completeness facts the caller supplies.
60
+
61
+ ---
62
+
63
+ ## Quickstart
64
+
65
+ ### Installation
66
+ ```bash
67
+ pip install solomons-sword
68
+ ```
69
+
70
+ ### CLI Usage
71
+ ```bash
72
+ # Evaluate Section 100A risk zone
73
+ solomons-sword s100a-check --beneficiary "Adult Child" --amount 40000 --adult-child --retained-by-parents
74
+
75
+ # Assess Section 99B receipt from foreign trust with corpus deduction
76
+ solomons-sword s99b-check --beneficiary "Jane Doe" --gross 150000 --corpus 50000
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Statutory Ground Truth & Test Harness
82
+
83
+ All allocation and threshold algorithms use exact `decimal.Decimal` calculations to prevent rounding discrepancies in trust tax schedules.
84
+
85
+ | Statutory Domain | Primary Authority | What the code actually does |
86
+ | :--- | :--- | :--- |
87
+ | **Proportionate Entitlement** | *ITAA 1936* s 95, s 97 (*Commissioner of Taxation v Bamford* [2010] HCA 10) | `Beneficiary Share = (Accounting Entitlement / Total Accounting Income) * s95 Net Income`. |
88
+ | **Section 100A Risk Matrix** | *ITAA 1936* s 100A, *ATO PCG 2022/2* | Returns GREEN, RED or OUTSIDE_GREEN from the supplied flags. It does not decide the white zone. |
89
+ | **Foreign Trust Distributions** | *ITAA 1936* s 99B(1), s 99B(2)(a) | Subtracts settled corpus and previously taxed income prior to assessable inclusion. |
90
+ | **Trust Resolution Timing** | Caller-supplied deed and execution facts | Refuses incomplete percentages and missing deed facts. This is not a substitute for current ATO guidance. |
91
+
92
+ ### Automated Test Suite
93
+ - Run the suite: `pytest tests/`
94
+ - The suite covers proportionate streaming, Section 100A zones the engine implements, Section 99B corpus deductions, and resolution gates. Do not treat a badge as a live coverage certificate.
95
+
96
+ ---
97
+
98
+ ## Licence
99
+ MIT License. Created by Ryan Duguid.
@@ -0,0 +1,40 @@
1
+ # v0.1.3
2
+
3
+ This is the first PyPI release of `solomons-sword`.
4
+ The monorepo's [filtered GitHub Releases page](https://github.com/ryanduguid/australian-accounting/releases?q=solomons-sword)
5
+ is the canonical release history.
6
+
7
+ - Move the maintained source to `packages/solomons-sword` in the
8
+ `australian-accounting` monorepo.
9
+ - Publish through `release-solomons-sword.yml`, using the monorepo's
10
+ namespaced, attested release workflow.
11
+ - Preserve the v0.1.2 Division 6, Section 100A and Section 99B behavior.
12
+
13
+ # v0.1.2
14
+
15
+ Releases through v0.1.2 are recorded on the standalone repository's
16
+ [GitHub Releases page](https://github.com/ryanduguid/SolomonsSword/releases).
17
+ A separate changelog is intentionally not maintained.
18
+
19
+ Prepared 0.1.2 notes. No PyPI distribution has been published; this source-only
20
+ project currently installs from a clone. The statutory corrections below came
21
+ from an audit whose claims were checked against the ITAA 1936 compilation in
22
+ force from 1 July 2026 and the High Court's own citation of Bamford:
23
+
24
+ - Division 6 franking credits were allocated on two overlapping bases when dividends were streamed, distributing 150 per cent of the credit pool in the audited case. Streaming is now refused outright, because the Division 6E carve-out with Subdivisions 115-C and 207-B is not implemented and a proportionate answer would be wrong.
25
+ - The franking credit gross-up is no longer added on top of the s 95 net income share: s 207-35 ITAA 1997 already includes it in the trust's net income, so adding it counted the credits twice. It is reported separately for the s 207-45 offset.
26
+ - Allocation now carries unrounded ratios into the s 95 pool and assigns the rounding residual, so allocated shares reconcile to the net income exactly. Three equal thirds of $100,000 previously lost $10.
27
+ - Cases the model does not compute now fail closed instead of returning an empty list or a mislabelled section: no presently entitled beneficiary and nil income of the trust estate (s 99 or s 99A trustee assessment), and non-resident beneficiaries (s 98(2A) or s 98(3)).
28
+ - Entitlements outside 0 to 100 per cent are refused; a 150 per cent and negative 50 per cent pair previously allocated a negative assessable share.
29
+ - s 99B now models the s 99B(1) residency precondition, the s 99B(2)(a) proviso for corpus attributable to amounts that would have been assessable to a resident, and the s 99B(2)(b) limb; negative inputs and exemptions exceeding the receipt are refused.
30
+ - The PCG 2022/2 green zone no longer claims the s 100A(13) ordinary family dealing exception. The guideline is a compliance-resourcing stance, not a determination, and the ordinary-family-dealing field is undetermined for that zone.
31
+ - Bamford is cited correctly as Commissioner of Taxation v Bamford [2010] HCA 10; (2010) 240 CLR 481, and the streaming reference reads Subdivisions 115-C and 207-B.
32
+
33
+ Also: one version source, project URLs, mypy enforced in CI (five real errors
34
+ fixed) with Python 3.11 and 3.13 added, CodeQL, deduplicated Dependabot config,
35
+ a not-advice boundary in the README, module docstrings and CLI output. The
36
+ package release workflow is intentionally absent until publication has a named
37
+ user, a fresh index-name availability check and an explicit compatibility
38
+ contract.
39
+
40
+ Not advice. Outputs are review aids for a qualified professional, not determinations.
@@ -0,0 +1,15 @@
1
+ # Security policy
2
+
3
+ ## Supported versions
4
+
5
+ Security fixes are applied to the latest version on the default branch.
6
+
7
+ ## Reporting a vulnerability
8
+
9
+ Use this repository's private vulnerability-reporting feature (Security > Report a vulnerability). Do not open a public issue or pull request for a suspected vulnerability.
10
+
11
+ Include a clear description, reproduction steps using fabricated data, likely impact, and any suggested mitigation. Never include client, taxpayer, employee, payroll, access-token or other sensitive data.
12
+
13
+ A valid report will be acknowledged within seven days. The fix and disclosure timeline will be agreed with the reporter.
14
+
15
+ If GitHub private reporting is not visible, email is not published as a fallback on purpose: enable private reporting in repository settings rather than creating a public inbox.
@@ -0,0 +1,46 @@
1
+ """
2
+ Solomon's Sword: Trust Distribution & Section 100A / 99B Risk Engine
3
+ The distribution is `solomons-sword`; the import package remains `louisgoldberg`.
4
+ """
5
+
6
+ from importlib.metadata import PackageNotFoundError, version as _dist_version
7
+
8
+ try:
9
+ __version__ = _dist_version("solomons-sword")
10
+ except PackageNotFoundError: # running from a source tree without installation
11
+ __version__ = "0.0.0.dev0"
12
+ __author__ = "Ryan Duguid"
13
+
14
+ from .division6 import (
15
+ TrustIncomeAssessment,
16
+ BeneficiaryEntitlement,
17
+ calculate_proportionate_share,
18
+ )
19
+ from .section100a import (
20
+ Section100ARiskZone,
21
+ Section100AAssessment,
22
+ evaluate_section100a_risk,
23
+ )
24
+ from .section99b import (
25
+ ForeignTrustReceipt,
26
+ Section99BAssessment,
27
+ evaluate_section99b_liability,
28
+ )
29
+ from .trust_resolution import (
30
+ TrustResolutionSchedule,
31
+ validate_trust_resolution,
32
+ )
33
+
34
+ __all__ = [
35
+ "TrustIncomeAssessment",
36
+ "BeneficiaryEntitlement",
37
+ "calculate_proportionate_share",
38
+ "Section100ARiskZone",
39
+ "Section100AAssessment",
40
+ "evaluate_section100a_risk",
41
+ "ForeignTrustReceipt",
42
+ "Section99BAssessment",
43
+ "evaluate_section99b_liability",
44
+ "TrustResolutionSchedule",
45
+ "validate_trust_resolution",
46
+ ]