Moksha Xero Org — Rollup & Decommission Plan¶
Purpose: Austin has a second paid Xero organization called "Moksha" with 5 bank accounts. It predates the 2026-04-19 single-org decision. Plan is to roll relevant data into the Renfroe Holdings Xero org, then decommission the Moksha org to stop the recurring Xero subscription and consolidate on one source of truth.
Status: COMPLETE 2026-04-22. Phases 0–5 executed. Moksha backup committed, 26 CM-specific chart accounts + Santander supplier rolled into RFH, 5 POSTED Moksha journals intentionally skipped (bookkeeper-built, to be superseded by JME deliverable — see todo/for-austin.md). Austin canceled Moksha subscription + revoked Custom Connection 2026-04-22. Local creds + token cache removed. Decision logged in decisions/log.md.
Reference: decisions/log.md 2026-04-19 "SUPERSEDES 2026-04-18 'Two Xero organizations' decision — ONE Xero org".
Execution log¶
- 2026-04-21 Phase 0 ✅ — Austin created Moksha Custom Connection, creds dropped at
~/.config/renfroe-fpa/xero-moksha.env. Tenant ID64dd84a6-fbfe-45dd-8a66-cff2bd16807eauthenticated. - 2026-04-21 Phase 1 ✅ — Full backup →
source-data/xero-backups/moksha-2026-04-21/(78 accounts, 4 contacts, 21 manual journals, 10 bank transactions, 85 Xero journals, all reports). - 2026-04-21 Phase 2 ✅ —
scripts/fpa/xero_diff_tenants.pyrun, full diff report →accounting/moksha-rfh-diff-report.md. Found only 5 of 21 manual journals POSTED (rest VOIDED), only 2 of 10 bank txns AUTHORISED (rest DELETED). 32 Moksha-unique chart accounts identified. - 2026-04-21 Phase 3 ✅ — Austin chose skip-and-archive: skip all journal/transaction migration, fold the 32 unique CM chart accounts in, create Santander contact, decommission Moksha (it's a paid org). Austin noted the Moksha books were built by a bookkeeper — JME-revisit task logged in
todo/for-austin.mdfor post-JME-deliverable review. - 2026-04-21 Phase 4 ✅ —
scripts/fpa/xero_migrate_moksha.pyexecuted against RFH. Created 26 chart accounts (filtered 6 out: 3 BANK dupes + 3 semantic dupes —1000 Cash,6122 Miscellaneous,6125 Professional Feesalready in RFH) and 1 Santander supplier contact. RFH chart: 113 → 139 accounts. Post-migration backup →source-data/xero-backups/2026-04-21-post-moksha-migration/. Migration history:source-data/xero-backups/_migration-history/20260422T052557Z.json. - 2026-04-22 Phase 5 ✅ — Austin canceled Moksha Xero subscription + revoked "Moksha Rollup" Custom Connection. Claude removed
~/.config/renfroe-fpa/xero-moksha.env+ token cache. Decision logged. Rollup complete. - Note: fresh-token test at 09:14 local on 2026-04-22 still authenticated successfully against the Moksha tenant — Xero appears to have a propagation delay on Custom Connection revocation. Austin should re-check the app listing at developer.xero.com in 24h to confirm full revocation. No action needed — the env file is already deleted, so Claude cannot call the API regardless.
Phase 0 — Austin unblocks credentials (5 min) [COMPLETE]¶
- Log into Xero as the Moksha-org owner.
- Go to Xero Developer → My Apps → New app → Custom Connection.
- Name it "Moksha Rollup" (or similar). Scopes needed (copy from the Renfroe Holdings Custom Connection):
accounting.transactionsaccounting.reports.readaccounting.journals.readaccounting.contactsaccounting.settingsaccounting.attachments- Authorize the app against the Moksha tenant.
- Copy client ID + secret.
- On
claude-code-01, create~/.config/renfroe-fpa/xero-moksha.envwith the same format asxero.env:Set permissions:XERO_CLIENT_ID=<moksha custom connection client id> XERO_CLIENT_SECRET=<moksha custom connection client secret>chmod 600 ~/.config/renfroe-fpa/xero-moksha.env
All scripts (xero_client.py, xero_backup.py, xero_rename_accounts.py) accept --tenant moksha once that env file exists. The Renfroe Holdings creds remain the default.
Phase 1 — Capture the Moksha snapshot¶
Pre-flight: confirm the creds work.
python3 scripts/fpa/xero_client.py --tenant moksha whoami
# (or) python3 -c "from xero_client import XeroClient; print(XeroClient.from_env(tenant='moksha').connections())"
Then run the full backup:
Output lands in source-data/xero-backups/moksha-2026-04-20/. This is the disaster-recovery baseline — if the rollup fumbles, everything Moksha ever held is in this snapshot.
Phase 2 — Diff Moksha against Renfroe Holdings¶
Compare what's in Moksha against what's already in Renfroe Holdings to identify what needs rollup. Produces a rollup-candidates list.
Candidate categories to diff:
| Category | Rollup mechanism | Risk |
|---|---|---|
| Organisation-level settings (name, address, currency) | Nothing to roll — Renfroe Holdings settings are authoritative | — |
| Chart of Accounts | Identify any account in Moksha NOT in RH; decide keep vs. drop | Low — just adds accounts |
| Tracking categories | Identify any option in Moksha not in RH | Low |
| Tax rates | Identify any Mexican IVA or other rate in Moksha not in RH | Low |
| Contacts (customers + suppliers) | Bulk copy unique contacts to RH | Low — names + contact info |
| Bank accounts | Moksha's 5 bank accounts — verify each has an equivalent in RH's 28 | Low — most likely already mapped |
| Invoices (ACCREC/ACCPAY) | Copy posted invoices to RH with date-preserving manual entry | Medium — re-creates posting history |
| Bills | Copy open bills to RH | Medium |
| Credit notes | Copy to RH if material | Medium |
| Manual journals | Re-post in RH if material | Medium |
| Bank transactions | Re-post in RH if material; or just reference via the backup | High — easy to double-count |
| Attachments | Re-attach to RH counterparts | Low — just files |
| Payments | Re-create if material | Medium |
I'll write a diff script (scripts/fpa/xero_diff_tenants.py) once Moksha's backup is captured. It reads both JSON dumps and surfaces:
- Moksha-only items (rollup candidates)
- Items in both (potential dupes to skip)
- Semantic name matches (e.g. "Casa Moksha" in Moksha might be "RHG: Brex Casa Moksha Dep" in RH now)
Phase 3 — Rollup decisions (Austin + Claude review)¶
Before any writes to Renfroe Holdings, walk through the diff output together. For each category, decide: 1. Skip (data is test-only, outdated, or superseded by decisions made since) 2. Copy as-is (safe bulk migration) 3. Copy with transformation (rename, re-tag with Entity dimension, re-classify) 4. Manual re-entry (one-off items that need Austin's judgment)
Given the 2026-04-19 single-org decision was made AFTER Moksha was set up, much of what's in Moksha is probably pre-decision test content. My expectation: mostly category 1 (skip) + a few category ⅔ items.
Phase 4 — Execute the rollup¶
Write a migration script (scripts/fpa/xero_migrate_moksha.py) that takes the approved diff and posts to the Renfroe Holdings tenant. Dry-run by default; --execute to commit. Mirror pattern of xero_rename_accounts.py.
Critical safeguards: - Fresh backup of Renfroe Holdings immediately before execution — so any mistakes are recoverable. - Idempotency: re-running the script should be a no-op if already applied. - Tag every migrated item with a note/tracking category so we can find and undo migrated items post-hoc.
Phase 5 — Verify + decommission [PENDING]¶
- Verify ✅ done — post-migration RFH backup at
source-data/xero-backups/2026-04-21-post-moksha-migration/. Account count 113 → 139 (net +26 new chart entries). Santander contact created. - Austin cancels Moksha Xero subscription — log into Xero as Moksha-org owner → Settings → Subscription → Cancel. Xero retains a 7-year archive of canceled orgs for historical lookup. This is the only remaining action.
- Austin revokes "Moksha Rollup" Custom Connection at developer.xero.com → My Apps → Moksha Rollup → Disconnect / Remove. Stops Claude's creds from working against a soon-to-be-canceled org.
- Claude removes
~/.config/renfroe-fpa/xero-moksha.envonce Austin confirms subscription canceled (simplerm). - Log decision in
decisions/log.md— "Moksha org decommissioned; rollup completed".
Estimated effort¶
| Phase | Austin's time | Claude's time | Blockers |
|---|---|---|---|
| 0. Credentials | 10 min | — | Austin must be at a Xero-logged-in browser + have access to the Moksha org |
| 1. Backup | 2 min | 1 min (automated) | Phase 0 done |
| 2. Diff | — | ~20 min to write script + run | Phase 1 done |
| 3. Decisions | 30-60 min (walk through diff) | — | Phase 2 done |
| 4. Execute | 5 min review | ~30 min to write + run script | Phase 3 done |
| 5. Decommission | 5 min | 5 min | Phase 4 verified |
Total: ~1-2 hours of elapsed work once Phase 0 unblocks.
What I need from Austin right now¶
- Complete Phase 0 — create the Moksha Custom Connection and drop creds into
~/.config/renfroe-fpa/xero-moksha.env. - Confirm: do you want me to run Phase 1-2 autonomously when Phase 0 is done, or walk through each phase with you? Per current auto-mode direction, default is autonomous unless you say otherwise.
Related files¶
scripts/fpa/xero_client.py— now supports--tenant mokshascripts/fpa/xero_backup.py— now supports--tenant mokshascripts/fpa/xero_rename_accounts.py— extensible to--tenant mokshaif neededdecisions/log.md2026-04-19 single-org decisioncontext/entities.md— canonical entity map (where Moksha should end up nowhere, since single-org)