Skip to content

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 ID 64dd84a6-fbfe-45dd-8a66-cff2bd16807e authenticated.
  • 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.py run, 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.md for post-JME-deliverable review.
  • 2026-04-21 Phase 4 ✅ — scripts/fpa/xero_migrate_moksha.py executed against RFH. Created 26 chart accounts (filtered 6 out: 3 BANK dupes + 3 semantic dupes — 1000 Cash, 6122 Miscellaneous, 6125 Professional Fees already 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]

  1. Log into Xero as the Moksha-org owner.
  2. Go to Xero Developer → My Apps → New app → Custom Connection.
  3. Name it "Moksha Rollup" (or similar). Scopes needed (copy from the Renfroe Holdings Custom Connection):
  4. accounting.transactions
  5. accounting.reports.read
  6. accounting.journals.read
  7. accounting.contacts
  8. accounting.settings
  9. accounting.attachments
  10. Authorize the app against the Moksha tenant.
  11. Copy client ID + secret.
  12. On claude-code-01, create ~/.config/renfroe-fpa/xero-moksha.env with the same format as xero.env:
    XERO_CLIENT_ID=<moksha custom connection client id>
    XERO_CLIENT_SECRET=<moksha custom connection client secret>
    
    Set permissions: 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:

python3 scripts/fpa/xero_backup.py --tenant moksha --date 2026-04-20

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]

  1. 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.
  2. 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.
  3. 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.
  4. Claude removes ~/.config/renfroe-fpa/xero-moksha.env once Austin confirms subscription canceled (simple rm).
  5. 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

  1. Complete Phase 0 — create the Moksha Custom Connection and drop creds into ~/.config/renfroe-fpa/xero-moksha.env.
  2. 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.
  • scripts/fpa/xero_client.py — now supports --tenant moksha
  • scripts/fpa/xero_backup.py — now supports --tenant moksha
  • scripts/fpa/xero_rename_accounts.py — extensible to --tenant moksha if needed
  • decisions/log.md 2026-04-19 single-org decision
  • context/entities.md — canonical entity map (where Moksha should end up nowhere, since single-org)