Best for
- "reconcile January's Chase checking" / "reconcile Amex 9041 for
- "why is the general ledger off the bank by $X" / "what's in the outstanding
- Called by close-my-month for every account in
gethouston/houston/store/agents/bookkeeping/.agents/skills/reconcile-my-accounts/SKILL.md
Reconcile a single account — bank, credit card, payment processor, or subledger — for the period you pick. I tie the general ledger one side, the external statement the other, surface unmatched items aged into 0–30 / 31–60 / 61–90 / >90 day buckets, and render a three-way proof with the real numbers. Sub-mode `mode=transfer-detect` finds debit/credit pairs across all your accounts within ±2 days and tags them as Internal Transfers so they fall out of the P&L. I never silently plug a difference a
Decision brief
A three-way reconciliation on one account for one period. General ledger balance on one side, external statement or feed on the other, unmatched items aged in the middle. Every difference is either explained by a timing item, surfaced as an unmatched item, or escalated as a name…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/gethouston/houston --skill "store/agents/bookkeeping/.agents/skills/reconcile-my-accounts"Inspect the Agent Skill "reconcile-my-accounts" from https://github.com/gethouston/houston/blob/10d9551da3a639803421a9004117f9e5633ce3a1/store/agents/bookkeeping/.agents/skills/reconcile-my-accounts/SKILL.md at commit 10d9551da3a639803421a9004117f9e5633ce3a1. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
"reconcile January's Chase checking" / "reconcile Amex 9041 for
I run external work through Composio. Before this skill runs I check that the categories below are linked. Missing → I name the category, ask you to connect it from the Integrations tab, stop.
I read your bookkeeping context first. For every required field that's missing I ask ONE plain-language question (best modality: connected app file drop URL paste) and wait.
1. Parse inputs. Required: accountlast4 (or all for mode=transfer-detect) and period (YYYY-MM or YYYY-QN). Resolve {periodStart, periodEnd} from period slug.
reconciliations/{accountlast4}/{YYYY-MM}.md - full recon.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 84/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 91 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
A three-way reconciliation on one account for one period. General ledger balance on one side, external statement or feed on the other, unmatched items aged in the middle. Every difference is either explained by a timing item, surfaced as an unmatched item, or escalated as a named break. I never silently plug.
Drafts only: I never adjust your general ledger, never force-match in QuickBooks Online or Xero. I write the reconciliation doc and surface the breaks.
close-my-month for every account in
context-ledger.domains.banks.accounts[] for close period.mode=transfer-detect - "find the transfers across accounts for
March" / "tag the internal transfer pairs so they fall out of
P&L". Runs across all accounts at once, not single account.I run external work through Composio. Before this skill runs I check that the categories below are linked. Missing → I name the category, ask you to connect it from the Integrations tab, stop.
If neither accounting nor banking is connected I fall back to a dropped CSV / PDF. If you have nothing to share I stop and ask you to connect one or drop the period statement.
I read your bookkeeping context first. For every required field that's missing I ask ONE plain-language question (best modality: connected app > file drop > URL > paste) and wait.
Parse inputs. Required: account_last4 (or all for
mode=transfer-detect) and period (YYYY-MM or YYYY-QN).
Resolve {periodStart, periodEnd} from period slug.
Read context. Load context/bookkeeping-context.md (stop if
missing - ask user to run set-up-my-books
first), config/context-ledger.json, and
config/chart-of-accounts.json.
Identify account. Look up account_last4 in
context-ledger.domains.banks.accounts[]. Capture {bank, type, glCode, glName} (account code and account name). If account not registered, ask ONE
targeted question to register - never guess.
mode=transfer-detect branch. If triggered:
composio search accounting
/ composio search banking) > runs/{period}/run.json if
present > CSV drop.D ± 2 days. Amount tolerance: 1 cent.glCode = "9000", glName = "Internal Transfer", source = "transfer". Excluded from
P&L SUMIFS downstream.reconciliations/_transfers/{period}.md with each pair's
{date_a, account_a, date_b, account_b, amount, confidence}.Pull two sides.
composio search accounting, pick QuickBooks Online / Xero slug, pull general ledger register
for {glCode, periodStart, periodEnd}. Discover schema with
--get-schema; never hardcode. Fall back to CSV / paste
if unconnected.composio search banking (Plaid-backed) or
statements/{account_last4}/{YYYY-MM}.pdf if already
dropped during process-my-statements run.composio search billing, pull balance transactions
for period.{date, description, amount}
plus opening + closing balances.Match items. Exact match on (date, amount) first; then
(amount, date ± 2 days) tolerance. Description similarity
(token-set ratio ≥ 0.75) breaks ties when multiple candidates
tie on amount. Confidence thresholds:
≥ 0.95 - auto-match (exact).0.80–0.94 - tentative match, surface in review bucket.< 0.80 - unmatched.Classify unmatched items.
daysOld = runDate - transactionDate.draft-a-journal-entry type=adjustment.Compute three-way proof.
gl_ending_balance
+ (on statement, not in general ledger)
- (in general ledger, not on statement)
± amount_differences
= statement_ending_balance (within 1 cent)
If proof doesn't land within 1 cent, do NOT plug. Flag
named break in report and upsert to recon-breaks.json with
status: "unresolved".
Age unmatched items. Bucket each into 0-30d, 31-60d,
61-90d, >90d. Items > 90d old escalate - flag in
report header.
Write reconciliation doc to
reconciliations/{account_last4}/{YYYY-MM}.md. Structure:
clean / has-items / unresolved-break).{date, description, amount, daysOld, ageBucket}.{date, party, glAmount, statementAmount, delta}.draft-a-journal-entry type=adjustment (unrecorded fees,
interest, forex rounding).Update indexes.
recon-breaks.json (flat at agent root) - read-merge-write.
For each unresolved item upsert
{id, accountLast4, period, date, description, amount, direction, daysOld, status, addedAt, updatedAt}. Age-update
existing entries rather than duplicate.outputs.json - append
{type: "reconciliation", title: "Recon {bank} {last4} {YYYY-MM}", summary, path, status: "draft", domain: "close"}.Summarize to user. Two-line recap: three-way proof result, and count + dollar total of unmatched items by age bucket. Include path to full doc.
reconciliations/{account_last4}/{YYYY-MM}.md - full recon.reconciliations/_transfers/{period}.md - only in
mode=transfer-detect.recon-breaks.json - read-merge-write, unresolved items aged.outputs.json - one row appended, type: "reconciliation".