Workpaper Review Gate
+----------------------------------------------------------------------+
| Workpaper Review Gate |
+----------------------------------------------------------------------+
| Stop incomplete workpapers reaching manager review |
+----------------------------------+-----------------------------------+
| DR what it gives you | CR what it needs |
+----------------------------------+-----------------------------------+
| READY / NOT_READY / BLOCKED | a pack directory of artefacts |
| cover sheet for the reviewer | a self-review JSON from the prep |
| repeat-finding flags | - |
+----------------------------------+-----------------------------------+
Browser evaluation · Reproduce locally · Quick demo · Release notes
The maintained source is under
packages/review-ready-gate
in the Accounting Review Pipeline. The review-ready-gate distribution,
review-ready command and reviewready import remain compatibility identifiers.
A local, review-first readiness gate for Australian public-practice packs. You point it at a folder of workpapers from a junior, an offshore team, or an AI agent. It tells you whether that folder is allowed to enter manager review.
A public evaluation pack reproduces the v0.1.5 manager-review result on fabricated BAS fixtures. It is a local review aid, not an approval system.
Fabricated proof
| Pack | Result | What the gate reports |
|---|---|---|
examples/bas-ready |
READY |
No configured findings. A human still decides whether the pack may proceed. |
examples/bas-not-ready |
NOT_READY |
Missing GST control export, incomplete self-review and a blocking open item. |
Open the manager-facing browser evaluation or reproduce the versioned evaluation pack from the fabricated fixtures.
It is the missing upstream step in this stack:
Incomplete pack
|
v
review-ready-gate <-- maintained monorepo package
|
| READY
v
Manager review (judgement, risk, client impact)
|
v
Monthly Close Controls / payday-super-checker / other engines
Monthly Close Controls answers "what material exceptions exist on these trial balances?". This tool answers a prior question: "is the pack even allowed onto the review desk?" A file can have material variances and still be READY, because the variances are documented. A file with a missing GST control export is NOT_READY even if the numbers look tidy.
It does not connect to Xero, store OAuth tokens, write journals, lodge BAS, lock a period, call an LLM, or claim that a file is correct.
[!WARNING] Not tax advice. A
READYresult means no configured gate tripped on the files that were present. A human still decides. See DISCLAIMER.md.
Why this exists
Preparation got cheaper. Review did not. Software, offshore capacity, and AI all increase the number of files that hit the review desk. The scarce resource in a firm is the manager who can actually sign.
Missing tie-outs, open questions in email, an unbalanced trial balance and unresolved findings from last period send a pack back for more preparation. This gate checks for those gaps before the pack reaches the manager.
Quick demo
The repository contains fabricated data only. Do not commit client workpapers.
For the manager-facing, reproducible BAS evaluation, see the manager review gate evaluation pack.
examples/ is the assault course: every move the tool has, run against
fabricated data, with nothing at stake. Learn the flags here before pointing
it at a real pack.
python -m pip install -e ".[dev]"
review-ready gate \
--profile bas \
--pack examples/bas-ready \
--output ../../../review-ready-demo/bas-ready
The ready demo exits 0 and writes three files:
readiness-summary.md: cover sheet a manager reads top to bottomfindings.csv: one row per finding, for Excel or Power BIreadiness-pack.json: structured evidence, source hashes, and any supplied acknowledgement
review-ready gate \
--profile bas \
--pack examples/bas-not-ready \
--output ../../../review-ready-demo/bas-not-ready
The not-ready demo exits 2. The GST control export is missing, the preparer has not certified the pack, a blocking open item is still OPEN, and the same missing artefact was OPEN on the prior pack, so it is flagged as a repeat.
review-ready view --pack-dir ../../../review-ready-demo/bas-ready
--output points outside this checkout, and it has to: the command refuses an
output directory inside a version-control checkout, exiting 1 without
creating anything. A readiness pack names a client's file, its workpaper
references and every finding standing between it and manager review, and
inside a checkout it is one git add -A away from a history that every clone
copies. A .gitignore entry is a convention the next commit can waive, and it
does nothing about the copy sitting in the working tree meanwhile. A checkout
is any directory at or above the output holding .git, .hg, .svn or
.bzr, because the harm is the pack going under version control and every one
of those copies a committed pack to each clone. A directory inside the work
tree named by GIT_WORK_TREE counts too, since Git can hold its metadata
elsewhere and leave a tracked tree carrying no marker to find. A work tree
selected some other way, by --work-tree on another process's git invocation
or by core.worktree in a repository this command never opens, cannot be
discovered from here: the check is a backstop for the location you chose, not
a proof that a directory is untracked. An output the command cannot examine,
such as one behind a symbolic-link loop or an unreadable parent, is refused on
the same grounds rather than assumed safe. The refusal applies to
writing only: review-ready view still opens a pack wherever it already is.
Use exit code 0 only for READY, 2 for NOT_READY or BLOCKED, and 1 for a malformed file, an invalid command, an --output path inside a version-control checkout, or an --output path that cannot be written.
To run the gate on a schedule in CI, copy examples/github-actions-readiness-check.yml into .github/workflows/.
It runs against a repo-stored synthetic pack, fails the job when the pack is BLOCKED, and reports NOT_READY for a human. A READY result is still not an approval.
What gets gated
| Profile | Required artefacts | Extra controls |
|---|---|---|
bas |
trial balance, activity statement, GST control GL, open items, self-review | 1A less 1B ties to GST control movement |
month_end |
current TB, prior TB, open items, self-review | optional bank rec; prior date earlier; same tenant |
year_end |
current TB, prior TB, tie-out matrix, open items, self-review | no UNSUPPORTED statement lines |
Optional in every profile: prior_findings.csv. An OPEN prior finding that is still present is marked repeat.
Filenames inside the pack directory are fixed. Header-only CSV schemas live under schemas/, together with the JSON Schema for self_review.json.
Self-review
self_review.json is part of the pack, not a courtesy. Exact keys, exact assertion names, JSON booleans only:
{
"preparer_initials": "AB",
"prepared_on": "2026-04-10",
"engagement_type": "bas",
"period_end": "2026-03-31",
"assertions": {
"pack_complete": true,
"tie_outs_done": true,
"open_items_listed": true,
"variances_explained": true,
"self_reviewed": true
}
}
engagement_type must match --profile. prepared_on must not be earlier than period_end. Any assertion that is not true is NOT_READY. The assertions are necessary, not sufficient: a preparer who ticks pack_complete while the GST control file is missing still gets MISSING_ARTEFACT. The JSON Schema is schemas/self_review.json.
Open items
ItemID,Severity,Owner,DueDate,Status,Description,Resolution
Severity is BLOCKING, EXPLAIN, or TRIVIAL. Status is OPEN or CLEARED. A BLOCKING item that is still OPEN with no resolution blocks the gate. A CLEARED item with no resolution text also fails: cleared means someone wrote down what happened.
Trial balance
The ten-column canonical CSV from xero-trial-balance-export:
ReportDate,Tenant,Section,AccountID,AccountName,AccountCode,Debit,Credit,YTDDebit,YTDCredit
One tenant, one report date, unique Tenant+AccountID. Movement debit must equal movement credit, and YTD debit must equal YTD credit, or the pack is BLOCKED.
BAS tie-out
If both the activity statement and the GST control GL are present:
- labels
1Aand1Bare required 1A - 1Bis compared with GST-controlsum(Credit) - sum(Debit)- a difference beyond
--tieout-tolerance(default$0.01) isNOT_READY
This is a cash-style control-account tie-out on the files you supply. It is not a lodgment, not a cash-versus-accruals bridge, and not a substitute for the bas-preparation skill.
Human acknowledgement
Optional --review-note JSON:
{
"reviewer_initials": "RD",
"reviewed_on": "2026-04-12",
"comment": "Reviewed fabricated demo findings only; no client file was approved by this example."
}
reviewed_on must not be earlier than period_end. An acknowledgement is evidence of a human action only. It never changes NOT_READY or BLOCKED to READY.
Viewing an existing pack
review-ready view is the read-only half of the gate: it loads a generated pack, proves the three files still agree with each other, and prints the cover sheet. It never writes, renames or deletes anything, and it cannot change what the engine computed.
review-ready view --pack-dir outputs/bas-ready
Before displaying anything it fails closed on: a missing artefact; JSON that is not valid UTF-8, not valid JSON, or carries unknown, missing or duplicated top-level members; a threshold or nested source digest that no longer parses as the writer rendered it; a readiness-summary.md whose overall status, source-evidence digests or review-boundary statement disagree with the JSON (including a second, conflicting status line); and a findings.csv whose header, row count or any cell disagrees with the JSON findings, honouring the writer's formula-injection guard exactly. On success the sheet ends with the SHA-256 of each artefact's exact bytes, so the displayed evidence can itself be archived. Exit code is 0 when a pack was verified and shown, 1 when verification failed.
Design
- Exact
Decimalarithmetic for money, never binary floating point. - Schema, duplicate-key, date, and numeric gates fail closed: a malformed file is exit
1and writes no pack. - Missing or empty required artefacts are findings, not crashes, so the cover sheet can tell the preparer what to send back.
- Source SHA-256 digests travel with the pack. Each digest is taken from the same immutable byte snapshot the loader parsed.
- Spreadsheet-facing finding text whose first non-whitespace character is
=,+,-or@is prefixed with an apostrophe. - The three pack files are staged beside their destinations and moved into place only once all three have been written. A failed run does not leave two runs mixed together.
- No wall-clock timestamps in the pack.
Data boundary
- Use a separate, access-controlled working directory for client source files and outputs.
- A generated pack cannot be written into a version-control checkout at all.
write_review_packwalks up from the resolved--outputdirectory and refuses if any level holds.git,.hg,.svnor.bzr, before it creates anything; a.gitfile counts as well as a directory, so a worktree and a submodule are checkouts too. A level it cannot examine is refused rather than read as an absence. The library enforces this too, so a caller that bypasses the CLI does not bypass the rule. - Keep this checkout limited to fabricated fixtures. Its
.gitignoreblocks CSVs outsideexamples/andschemas/, and blocks all three generated pack files by name. That stays as a second line: it catches a pack copied in by hand, which no guard on the writer can see. - Do not use this as tax, financial, audit, or legal advice.
Related
- Monthly Close Controls - exception pack once a trial balance is allowed onto the review desk
- Xero Ledger Review Gate - zero-network variance boundary for AI-assisted TB review
- australian-accounting-skills -
workpaper-tie-outandbas-preparationworkflows this gate enforces mechanically - DrDebits - APES 110 / TPB guardrails for any LLM sitting after a READY pack
Development
Use the locked toolchain. python -m pytest is not what CI runs.
uv lock --check
uv sync --locked --all-extras
uv run pytest
uv run ruff check reviewready tests
uv run mypy reviewready
uv build
The test suite covers schema gates, the three fabricated engagement packs, empty and incomplete artefacts, GST and bank-rec breaks, unsupported tie-outs, acknowledgement parsing, deterministic pack generation, fail-closed pack viewing, and the command-line exit contract.
Continuous integration verifies the committed uv.lock, runs the test suite on Python 3.10, 3.11, 3.12, and 3.13, then builds and smoke-tests the wheel with the fabricated demo. CodeQL scans the Python source, and Dependabot is configured to propose updates for uv dependencies and pinned GitHub Actions. See CONTRIBUTING.md for the local verification and data-handling requirements. To cut a release, follow RELEASING.md. Do not tag until you intend to publish.
MIT licensed. Boundary statement: DISCLAIMER.md.
Metadata
Release files for review-ready-gate 0.1.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| review_ready_gate-0.1.6.tar.gz | 64.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| review_ready_gate-0.1.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 99.6 kB
Release files / review_ready_gate-0.1.6.tar.gz
| Download URL | review_ready_gate-0.1.6.tar.gz |
|---|---|
| Size | 64.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b80d6518513df3e31ea8c8e5d2180956d5bfab69c660bd93073113cf6fbeb732
|
|
BLAKE2b-256 checksum How to use checksums |
742bf5e26c335aa02fb2bdafafc456c41e6e5daf59d1b887fef11216a99f793a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency logRelease files / review_ready_gate-0.1.6-py3-none-any.whl
| Download URL | review_ready_gate-0.1.6-py3-none-any.whl |
|---|---|
| Size | 35.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62a97bfab500c887ff3ecd4ddde5a8252b456b045169a435b55b8fc7e3dbb170
|
|
BLAKE2b-256 checksum How to use checksums |
488f7c13e1dbb12d0e3c498cb233d9bddac2a95cdd8133bd185be44903db5d1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.
Transparency log