executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
business-profileUse when a business's operational knowledge should persist across sessions instead of being rediscovered every time — who each vendor and customer is, the bank narratives they appear under, how and how often they bill, their normal amount range, their category and VAT treatment, plus free-text notes on how each one actually behaves. Learns baselines from tr…
Independent GitHub snapshot · Automated classification · Original documentation governs
Stops every session starting from zero, and turns "that transaction looks odd" into "that transaction changed, here is what it used to be."
Per counterparty, learned from history rather than declared:
| Narratives | Every bank text this counterparty has appeared under |
| Cadence | monthly · weekly · quarterly · annual · irregular, inferred from the gaps |
| Amount range | Observed min / max / median — or an explicit "too few observations" |
| Category & VAT treatment | What it is normally coded as |
| Notes | Free text: how this one actually bills — the knowledge that otherwise lives in someone's head |
The notes field is the one that pays off. "Worldpay deducts the whole month's fees from a single
settlement around the 12th" is exactly the kind of thing that is rediscovered painfully every year
(bookkeeping-double-entry/references/transaction-patterns.md §2b).
P=.accounting/business-profile.json
# once, and again whenever you have a fresh batch of history
python3 ~/.claude/skills/business-profile/scripts/profile.py --profile "$P" \
learn --transactions transactions.json
# every session, before working: what changed?
python3 ~/.claude/skills/business-profile/scripts/profile.py --profile "$P" \
check --transactions new-transactions.json
# "who is this?" — instead of guessing again
python3 ~/.claude/skills/business-profile/scripts/profile.py --profile "$P" \
match --narrative "WORLDPAY SETTLEMENT 14/06"
# record what you learn about a counterparty
python3 ~/.claude/skills/business-profile/scripts/profile.py --profile "$P" \
note --id "WORLDPAY SETTLEMENT" --text "monthly fees deducted from one settlement ~12th"
Run check before working, not after. Its findings change what the rest of the session should
look at.
| Finding | Why it matters |
|---|---|
| missed_recurrence | A monthly bill stopped arriving. Cancelled, or a feed gap — and nothing else in the books can see this, because a transaction that never arrived has nothing to appear as |
| possible_rename | An unknown narrative resembling a known counterparty. Its history is about to be orphaned, and the bank rule keyed on the old name has silently stopped matching |
| narrative_changed | Known counterparty, new bank text. Same rule consequence |
| amount_outside_range | Price rise, a different service, or a keying error |
| vat_treatment_changed | Never fails a control-account proof — the money still balances, so nothing else will flag it |
| category_changed | Deliberate reclassification, or a mis-code |
| unknown_counterparty | Classify once, known from then on |
missed_recurrence is the one worth having. It is the only check in this whole family that
detects an absence. It caught the feed-gap class from the opposite direction to
quickbooks-bookkeeping §4 — that reconciles to a balance, this notices a habit that stopped.
amount_outside_range catches the Worldpay pattern for free. A settlement of £640 against an
observed £990–£1,010 is flagged without anyone knowing why yet — which is the right order.
The tool reports what moved against what baseline. It never concludes.
Vendors legitimately rename. Prices rise. Billing moves from monthly to annual. A business changes what it buys. Auto-classifying change as error would train people to dismiss the findings, which is worse than not producing them.
So the output is always "this changed, from this, is that expected?" — and a human answers.
Confidence is stated honestly. A baseline built on fewer than four observations reports
insufficient rather than asserting a range it cannot support. Two data points are not a pattern,
and a tool that pretends otherwise flags noise until nobody reads it.
Bank descriptions carry dates, references, card suffixes and payment ids that differ every time. Matching raw text means every transaction looks new, so narratives are normalised — volatile parts stripped, the stable stem kept — before comparison.
That is why ACME SUPPLIES LTD REF:88213 and ACME SUPPLIES LTD REF:92100 are one counterparty,
while ACME SUPPLIES LIMITED T/A ACME surfaces as a possible rename rather than silently
matching or silently not.
Rename detection is deliberately a weak signal offered as a question. "Ltd" becoming "Limited" and a genuinely new vendor sharing a word look identical from here.
financial-document-ingestion (validated rows), a bank/processor export, or the
QuickBooks API (quickbooks-api).quickbooks-bookkeeping — a narrative_changed finding is precisely the bank
rule that needs fixing before it silently mis-files a month.ledger-error-diagnosis when a finding turns out to be a real error.accounting-uk-ltd's tracker, which holds obligations and deadlines. This
holds who and how. Both persist; they answer different questions.financial-document-ingestion §4).missed_recurrence because nothing looks wrong — that is the point of it.