The monthly financial close for the Zynkr Finance Ledger — reconciles one month's 台北富邦 bank statement against Gmail receipts, appends the rows that are missing, files the statement, and mails a performance report. Give it the statement PDF and a month; it reads every line on the statement as the spine of the month, sweeps the Finance Gmail label for invoices, receipts and remittance notices, works out which of them are already in the ledger, and proves the month is complete with a balance ide...
Scanned 9/19/2026
Install to Claude Code
npx -y skills add peter-tu-zynkr/zynkr-skill-builder --skill zynkr-accounting --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Zynkr Accounting?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/peter-tu-zynkr-zynkr-accounting)More formats (shields.io, HTML) on the badges page.
---
name: zynkr-accounting
sheetId: "8.01"
description: >-
The monthly financial close for the Zynkr Finance Ledger — reconciles one month's 台北富邦 bank
statement against Gmail receipts, appends the rows that are missing, files the statement, and
mails a performance report. Give it the statement PDF and a month; it reads every line on the
statement as the spine of the month, sweeps the Finance Gmail label for invoices, receipts and
remittance notices, works out which of them are already in the ledger, and proves the month is
complete with a balance identity that has to hold to the dollar before anything is written.
Appends are proposed as one batch and applied only on a single confirmation — it never writes
to the ledger unasked. Trigger EAGERLY on "/zynkr-accounting", "月結", "對帳", "銀行對帳",
"close the month", "月度財務結算", "幫我對帳", "reconcile the statement", "把八月的帳結一結",
"銀行對帳單來了", "monthly close", "對一下上個月的帳", or whenever Peter hands over a 台北富邦
對帳單 PDF with no further direction. BOUNDARY — do NOT hijack: /zynkr-gm (the company-level
weekly GM brief; it reads runway, it does not keep the books), /planning-tracker-sync (the H2
tracker), /consult-status-report (one consulting engagement). This skill owns exactly one
thing: turning a month of bank activity into ledger rows and a report. It writes to the
Transactions tab and nowhere else, and it never touches the Financial Model tab.
category: finance-admin
project: zynkr-accounting
platform: claude
status: WIP
author: Peter Tu
input: "The month (YYYY-MM) plus the 台北富邦 statement PDF for it — a local path, a Drive file, or a Gmail attachment. Everything else is discovered."
process: "Read the statement as the spine → sweep Gmail for the month → diff both against the ledger → run the balance identity gate → propose one append batch → on confirmation append, fill the derived-tab lookups, file the PDF, mail the report."
output: "Appended Transactions rows, a filed statement PDF, and an HTML monthly report — the close result, income and cost by line, open items, and the reimbursement balance owed."
synergy: [zynkr-gm, admin-governance]
handoff: []
house-style: bound
---
# zynkr-accounting
This skill has a `references/` directory, so the marketplace one-file `curl` install is not enough
for it — the reference files carry the ledger schema and the reconciliation rules, and the skill
cannot run without them. Install it with the skills CLI instead:
```bash
npx skills add https://github.com/peter-tu-zynkr/zynkr-skill-builder --skill zynkr-accounting
```
## What this is
Once a month the 台北富邦 statement arrives by mail. This skill turns it into bookkeeping: it reads
every line on the statement, finds the paperwork for those lines in Gmail, works out what the
ledger is already carrying, and appends only the difference. Then it files the PDF, writes a
performance report and mails it.
The statement is the **spine**, not one source among several. Several kinds of row exist *only*
there — 分潤 receipts, inbound 匯費, card settlements — and generate no email at all. A sweep that
starts from Gmail silently misses them. So the flow is always statement first, mail second.
The month is only closed when a balance identity holds to the dollar. That gate is the point of
the skill; everything before it is gathering, everything after it is reporting.
## Before you start
Read both reference files — they are the contract, and the failure modes in them are ones that
have actually bitten:
- `references/ledger-contract.md` — the 16-column schema, how the derived tabs are wired, the
append protocol, and what breaks the spreadsheet.
- `references/reconciliation-rules.md` — the balance identity, the NT$15 fee rules, bundled
transfers, and the vendor → product-line map.
Resolve these placeholders from the runtime substitution table before calling any tool:
| Placeholder | What it is |
|---|---|
| `<your-google-workspace-account>` | The Workspace account every Google call runs as |
| `<your-finance-ledger-sheet-id>` | The Zynkr Finance Ledger spreadsheet |
| `<your-finance-drive-folder-id>` | The Drive folder the statements are filed into |
## Step 0 — Anchor the month, then preflight
Establish the month (`YYYY-MM`) from what Peter said, or from the statement's 對帳單期間 header.
State it back before doing anything else — a close run against the wrong month is worse than no
close.
Then check three things and report them together:
1. **The ledger tail.** Read the `Transactions` tab and find the last populated row. Monthly
Summary's `SUMPRODUCT` is hard-capped at **row 200** — if this close would cross it, say so
now and extend the formulas first. Do not append past a cap that silently stops summing.
2. **Whether the month is already closed.** If rows already exist with `raw_ref` naming this
month's statement, this is a re-run. Reconcile as normal but expect the diff to be empty, and
never append a duplicate — ids are UUIDs, so the sheet will not stop you.
3. **The statement is readable.** `pdftotext -layout <pdf>` is the reliable path; the layout flag
is what keeps the 支出 / 收入 / 餘額 columns apart.
## Step 1 — Read the statement as the spine
Extract the 當月交易明細 table into an ordered list: date, 摘要, 支出, 收入, 餘額. Capture the
opening 承轉結餘 and the closing balance — the identity in Step 4 needs both.
Ignore everything else in the PDF. A 富邦 statement is three pages of regulatory boilerplate
wrapped around one small table; the 資產持有明細 block and the 訊息公告 numbered list carry nothing
to book.
Every line becomes a **bank line** with a status you will fill in during Step 4: `matched`,
`missing`, `split`, or `unexplained`.
## Step 2 — Sweep Gmail for the month
Search the Finance label and the month's date range for the paperwork behind those bank lines,
and for costs that never touch this account at all:
- Invoices and receipts — SaaS vendors, venue, 講師費, 記帳士, 國稅局
- Remittance and settlement notices — ACCUPASS 撥款, card settlements, client payments
- Transfer confirmations from the bank itself, which usually name the payee the statement 摘要
only abbreviates
Two things worth knowing. Personal-card charges (`source: personal`) will appear in mail but
**never** on this statement — they belong in the ledger and must be excluded from the balance
identity. And a bank line's 摘要 is often too terse to attribute on its own; the matching email is
usually what names the counterparty.
## Step 3 — Consolidate the month
Build the candidate row set from three streams:
1. **Bank lines** from Step 1 — every one becomes at least one ledger row.
2. **Personal-card costs** from Step 2 — `source: personal`, `reimbursement_status: pending`.
3. **Email-only costs** that settle off this account.
Then diff the whole set against what the ledger already holds for the month. Match on amount and
date first, counterparty second. What survives the diff is the append batch.
Run the recurring-vendor completeness check here — the monthly subscriptions are known, and a
missing month is nearly always an oversight rather than a real gap. `references/reconciliation-rules.md`
carries the list.
## Step 4 — Reconcile, and make the gate hold
This is the step the skill exists for. The identity:
```
opening balance + Σ(all ledger rows for the month where source ≠ personal) = closing balance
```
Compute it. If it holds to the dollar, the month is complete and you may proceed.
If it does not, the difference is a **finding**, and findings are the most valuable thing this
skill produces. Do not paper over one. Resolve each into exactly one of:
- **A missing row** — on the statement, absent from the ledger. Append it.
- **A split** — one bank line that is two or more ledger rows. A salary transfer carrying an
expense reimbursement is the common case, and the 摘要 usually hints at it.
- **A fee** — almost always NT$15. See the reference; the direction matters.
- **A ledger row that never hit the bank** — booked as if paid from this account but absent from
the statement. This is a real error: either the payment method is wrong, or it settles next
month. **Do not silently re-date it.** Report it and let Peter rule.
Show the arithmetic. State the identity, the two balances, the sum, and the residual — and show
that the findings close the residual exactly. A gate you cannot show the working for is not a gate.
## Step 5 — Append to the ledger
Propose the whole batch first — every row, in full, as a table — and apply it **only** on a single
confirmation from Peter. This is a financial record; a wrong append needs a correcting entry, not
an undo.
Where attribution is genuinely uncertain, the house convention is to **book it with a `⚠` note in
the `notes` column rather than block on it**. Say plainly in the proposal which rows carry a ⚠ and
what would settle them.
Then follow the append protocol in `references/ledger-contract.md` exactly. It is append-only to
`Transactions`, and there is a fill-down step afterwards that is easy to forget and silently
corrupts the derived tabs when you do.
## Step 6 — File the statement
Upload the PDF to `<your-finance-drive-folder-id>`, named `台北富邦銀行 <YYYY-MM>.pdf` so the folder
sorts chronologically. Keep the name stable — the ledger's `raw_ref` column cites the statement by
month, and that citation is the audit trail back from a row to its evidence.
Confirm the upload landed before moving on, and do not delete the local copy.
## Step 7 — Build the report
Compose the monthly performance report from `references/report-template.md`. It leads with the
close result — held or did not hold — because that is what tells Peter whether to trust the rest
of the numbers.
Every figure must be one you computed in this run and can point at a source for. Operating revenue
is **not** the ledger's `總收入` line; the reference explains what that line sweeps in and how to
state revenue honestly.
## Step 8 — Send
Send the report as HTML to `<your-google-workspace-account>`, subject
`【月結】<YYYY-MM> 財務結算 — <held | N findings>`.
Then report back in the conversation: rows appended, the identity result, anything still open, and
the ledger's remaining headroom to row 200.
## Failure modes worth naming
- **Writing into the Financial Model tab.** Every month column there is a spilled array formula.
Writing a value into one blocks the spill and turns the row into `#REF!`. This skill never
writes to that tab; it updates automatically from `Transactions`.
- **Forgetting the derived-tab fill-down.** The `Income` and `Costs` tabs re-sort on every append,
so a back-dated row pushes the last row past the hand-filled lookup column and leaves it with a
blank TWD amount. The totals then quietly disagree.
- **Closing on the ledger alone.** If you never open the statement you will miss every row that
has no email behind it, and the identity will look fine because you never computed it.
- **Treating a residual as rounding.** It is not rounding. This ledger ties to the dollar.
## House style
Writing style is **not owned by this file**. The house voice lives in two Google Docs under
`[@] 寫作指南` (`12DBdFz3SK22ie9im_ThFMI7IBRXsTZsV`), read at runtime:
- 《[2.0] Zynkr 通用風格指南 House Voice》 `10bOIQwRm9Pxwgct4hlwCwK_B4Pipai1HqBPZKzyRHSE` —
the universal core, plus the addendum for this surface
- 《[3.2] 禁用詞清單 Forbidden Words》 `1N5sHLP4qzmmhpCGsi6KElxi1z0MFe4QZ0Q_35T10Uyg`
Read both before producing client- or reader-facing text, and scan the draft against 《[3.2]》
before handing it over. If Drive is unreachable, say so in the output rather than proceeding
unchecked. Never re-implement either list inside this file.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!