Thanks for contributing to Accrue. This repository ships two sibling Mix packages:
accrue/for the core billing libraryaccrue_admin/for the LiveView admin UI
Install the supported toolchain first:
- Elixir 1.17+
- OTP 27+
- PostgreSQL 14+
- Node.js for browser UAT in
examples/accrue_host
Then bootstrap both packages:
cd accrue
mix deps.get
cd ../accrue_admin
mix deps.get
npm ciUse the package-local READMEs and guides for host-app wiring, browser UAT, and release-oriented docs checks.
Doc PRs that touch First Hour or the host README proof spine must follow the same-PR capsule parity checklist in scripts/ci/README.md (search for First Hour + host README capsule parity — INT-11). For when Accrue is in maintenance posture vs active feature milestones, read accrue/guides/maturity-and-maintenance.md.
Pull requests that introduce non-token color or layout exceptions in accrue_admin must add a row to the theme exception register at accrue_admin/guides/theme-exceptions.md so reviewers can track intentional deviations (D-13 / Phase 50).
Accrue uses Conventional Commits so Release Please can cut package-local changelogs and version bumps correctly.
Use commit subjects like:
feat(accrue): add invoice retry helperfix(accrue_admin): preserve filter params on paginationdocs: clarify webhook replay setup
Keep the type accurate. feat, fix, and docs affect release notes and versioning.
Run the release gate from each package directory before opening a PR:
mix format --check-formatted
mix compile --warnings-as-errors
mix test --warnings-as-errors
mix credo --strict
mix dialyzer
mix docs --warnings-as-errors
mix hex.auditFor accrue_admin, use publish-mode dry runs when validating release packaging:
cd accrue_admin
export ACCRUE_ADMIN_HEX_RELEASE=1
mix hex.build
mix hex.publish --dry-runFor provider-parity checks against Stripe test mode, follow the setup in guides/testing-live-stripe.md. That lane is advisory/manual, not part of the required deterministic release gate, and it exists to catch provider-parity drift rather than replace Fake. Please keep real credentials out of shell history and logs.
The required deterministic release gate still includes the checked-in trust review artifact, generated drift/docs drift, seeded performance smoke, compatibility floor/target checks, and browser accessibility/responsive checks. Keep webhook secrets, customer data, and PII out of docs, issue templates, screenshots, traces, and copied terminal output.
v1.7 adoption requirements (ADOPT-01–ADOPT-06) are enforced mostly through documentation gates in scripts/ci/. When verify_package_docs or VERIFY-01 checks fail in CI, open scripts/ci/README.md for the requirement → script → ExUnit map so you edit the owning files first instead of silencing unrelated prose.
v1.16 integrator + proof (INT-06..INT-09): Verifier ownership for those rows lives under ## INT gates (v1.16 integrator + proof continuity) in scripts/ci/README.md — edit that section (not this file) when INT-related merge-blocking checks or owning VERIFICATION.md paths change.
Before you open a PR that touches First Hour, the root/host README, accrue/guides/quickstart.md, or any verify_package_docs needle, run this minimum local doc preflight from the repository root (ordered; fast failures first). It mirrors job docs-contracts-shift-left and does not replace the host-integration merge-blocking job.
bash scripts/ci/verify_package_docs.sh && \
bash scripts/ci/verify_v1_17_friction_research_contract.sh && \
bash scripts/ci/verify_verify01_readme_contract.sh && \
bash scripts/ci/verify_production_readiness_discoverability.sh && \
bash scripts/ci/verify_adoption_proof_matrix.sh && \
bash scripts/ci/verify_core_admin_invoice_verify_ids.shAfter you git push to main, you can wait on GitHub’s CI workflow locally with bash scripts/ci/watch_ci.sh (uses gh run watch on the latest run for that branch).
Hex-only mix deps.get vs @version on main: When mix.exs @version bumps on main ahead of the matching Hex publish, mix deps.get against published ~> pins can fail until the new artifacts ship. Prefer a path: dependency into this workspace, a git ref to the commit you need, or wait for publish before expecting Hex to resolve the newer number.
Host integration proofs sit in Layer B and Layer C relative to the per-package release gate:
- Layer A —
accrue/andaccrue_admin/mix test, Credo, Dialyzer, docs, and related release checks (above). - Layer B — from the repo root,
cd examples/accrue_hostthenmix verify(fast Fake slice) ormix verify.full(CI-equivalent host stack). See examples/accrue_host/README.md#proof-and-verification for VERIFY-01 detail. - Layer C — merge-blocking PR jobs
docs-contracts-shift-left(bash contracts) thenhost-integration(BEAM + Playwright) are the contract, not “I ranmix verify.fulllocally” alone; use scripts/ci/README.md to map scripts and lanes before you change CI-facing prose.
Phase verification (/gsd-verify-work N) defaults to 0 human steps. Every truth in a phase's *-UAT.md must point at a green automated check or carry an explicit automation_deferred: reason.
Automatable by default — write the test, don't write a checkbox:
- File existence / non-existence →
File.exists?,Path.wildcard,refute File.exists?(precedent:accrue/test/accrue/emails/mailglass_cleanup_test.exs). mix.exsdeps present/absent →File.read!("mix.exs") =~ "..."in ExUnit (same file).- Guide / doc content →
File.read!("guides/<name>.md") =~ "..."(same file). - Module / function exported / removed →
function_exported?/3,Code.ensure_loaded?/1. - Fixture or coverage breadth → enumerate
Accrue.Emails.Fixtures.all/0(or equivalent) and assert per-key. - Admin LiveView page renders →
Phoenix.LiveViewTestviaAccrueAdmin.LiveCase(precedent:accrue_admin/test/accrue_admin/dev/email_preview_live_test.exs). - Browser-only behavior (real navigation, JS interop, visual diff) → Playwright spec under
examples/accrue_host/e2e/oraccrue_admin/e2e/(precedent:phase7-uat.spec.js).
automation_deferred: is permitted only when the check genuinely requires hardware, a third-party live account, or human judgment that no assertion can encode. Record the reason in the UAT entry and link a follow-up issue.
Closed UAT files should include an ## Automation Map section mapping each truth → test path[:line range] → CI gate, so the next phase's verifier can audit the trail without reopening the question. See .planning/milestones/v1.29-phases/090-full-template-port-cleanup/090-UAT.md for the canonical shape.
Accrue does not require a Contributor License Agreement at this time. By submitting a contribution, you confirm that you have the right to license your work under the repository's MIT license.