Files
oikos/.agents/skills/runbook-budget-from-csv/SKILL.md
dtoro d80a394b7f
Some checks failed
ci / build-test (push) Has been cancelled
ci / docker-build (push) Has been cancelled
docs: fix plan/repo drift, retire dead Goose+Nomos and Caveman tooling
Documentation and repo-hygiene pass following the client/server split:

Plan drift (audited all other active plans against current code):
- oikos-gaps-and-improvements.md: mark Section C and D.5 resolved (both
  described cmd/hermes, renamed to cmd/nomos with a real LLM loop since);
  refresh ~10 stale file:line citations; fix tool-count (33, not 28).
- liveness-drift-and-ux-cohesion.md: fix stale default-model claim (now
  deepseek-v4-pro since 2026-07-10) and "not yet deployed" status.
- nomos-agent-code-review.md: fix C1's citation (one unauthenticated route
  to nomos now, not two, after the client/server split).
- wails-desktop-app.md: record the production deploy outcome.

Repo structure: added missing directories to README/CONTRIBUTING layout
tables (checks/, tools/, cmd/webhook/, docs/operations/), fixed a broken
link, added ADR 0015 documenting the auth/CORS/client-split model (there
wasn't one despite CONTRIBUTING's own process requiring it), normalized
ADR 0013/0014's format drift, added an Authentication section to
AGENTS.md/CLIENTS.md (every example call was missing the now-required
bearer header).

Retired the Goose+Nomos workstation flow (bootstrap.sh --with-nomos,
tools/setup-nomos-soul.sh, .agents/operations/nomos-agent.md) and the
Caveman auto-install tooling (tools/setup-caveman.sh, tools/caveman/) —
both superseded by the production containerized Nomos agent, which has
never used either. Kept .agents/shared/caveman.md itself (the terse
writing-style convention agents still follow by reading it).

Deleted the orphaned legacy Python oikos/ directory — nothing imports it,
and bin/homelab (the CLI it was kept for) no longer exists in the repo.

Rewrote .agents/operations/agent-enrollment.md (365 -> ~110 lines) and
commands.md to match the current architecture instead of the retired
`homelab` CLI; migrated the still-true networking prerequisites (Netbird,
split-horizon DNS, SSH key distribution) into the knowledge base as a
runbook via upsert_knowledge rather than duplicating them in markdown.
Updated all 10 .agents/skills/ runbooks referencing the dead CLI with
their real MCP tool / REST API equivalents, or flagged them as needing
verification where no equivalent is confirmed yet.

Two real bugs found and fixed, not just docs:
- The tools/setup-*.sh auto-setup glob was tools/*.setup.sh in THREE
  places (tools/post-pull.sh, bootstrap.sh, and internal/httpapi/impl.go's
  GetClientContext handler) since the mechanism's introduction on
  2026-06-02 — never matched any real filename, so no client has ever
  picked up an auto-setup script via git-pull or the context-poller sync.
  Fixed all three; the Go server-side fix is the one that actually matters
  since it's what the current context-poller mechanism depends on.
- bootstrap.sh removed dead vestigial --gitea-token/--gitea-user flags
  (parsed, never consumed) left over from an earlier clone-based model.

Also flagged, not fixed (documented as an open gap in
client-enrollment/SKILL.md): bootstrap.sh tells a freshly-enrolled client
to call POST /api/v1/clients/{slug}/activate to finish enrollment, but
that route doesn't exist in api/openapi.yaml — EnrollClient sets entities
to provisioning and nothing currently transitions them to active.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 18:19:41 +02:00

7.7 KiB
Raw Blame History

name, risk_class, inputs, references
name risk_class inputs references
budget-import-from-csv config_mutation
csv_file
containers/129-house.md

Runbook: Budget import from N26 CSV → Yuvomi

Distil a bank-export CSV into Yuvomi's Budget and Subscriptions modules using the yuvomi-mcp tools. Run this whenever a new CSV period needs to be summarised into targets and fixed costs.


Prerequisites

  • yuvomi-mcp is running on LXC 129 and connected as an MCP server in Claude.
  • The CSV is an N26 export (columns: Booking Date, Value Date, Partner Name, Partner Iban, Type, Payment Reference, Account Name, Amount (EUR), …).
  • API token: yuvomi-api-token, via Infisical (primary) or oikos secret (SOPS fallback).
  • Direct API base: https://house.hubris.network/api/v1

API quirks (Yuvomi ≤ 0.77.x)

  • Subscriptions live under /budget/subscriptions, NOT /subscriptions/. A top-level /subscriptions route returns 404.
  • GET /budget/subscriptions{ data: { subscriptions: [...], summary: {...} } }
  • GET /budget/subscriptions/meta{ data: { categories: [...], payment_methods: [...] } }
  • POST /budget/subscriptions → create a subscription (name, amount, billing_cycle, cycle_interval, next_payment_date, currency, category_id, payment_method_id required)
  • GET /budget/ (no month) → returns only non-recurring base entries. Use GET /budget/?month=YYYY-MM to get all entries (recurring + one-time) for a month.
  • GET /budget/categories → expense category keys + income category names (German keys like "Erwerbseinkommen", "Sozialleistungen", "Geschenke & Transfers").
  • Budget entries: amount positive = income, negative = expense.
  • Recurring entries: set is_recurring: 1 + recurrence_interval: "monthly". The date field sets the start month.
  • recurrence_virtual: 1 smooths non-monthly amounts across all months in the summary (e.g. 55.08 € quarterly → shows as ~18.36 €/month).
  • Custom RRULE strings (recurrence_rule) are not accepted by the API — use cycle_interval on the subscription instead, or recurrence_interval on budget entries.

Subscription category IDs (as of 2026-06-26)

id name budget_subcategory_key
1 Entertainment subscription_entertainment
2 Productivity subscription_productivity
3 Utilities subscription_utilities
4 Health subscription_health
5 Education subscription_education
6 Other subscription_other

Payment method IDs

id name
1 Credit Card
2 Debit Card
3 PayPal
6 Bank Transfer / SEPA
7 Other

Step 1 — Categorise the transactions

Skip these as internal/already-covered:

  • Fixed costs you'll enter as subscriptions (Miete, SWM, SYNVIA, Hundefutter, Netflix, Grover, Rundfunk ARD, KuKita, Lillydoo)
  • Internal transfers (The Joy Pot ↔ Cookie, Hauptkonto, Tagesgeldkonto splits)
  • Identified income (Cookie Share, Kindergeld, Pocket Money credits, Distributor)
  • Fun Money pass-throughs (in and out same month → net zero)

Variable expense taxonomy:

Category key Subcategory key Examples
food groceries E-Center, Knuspr, EDEKA, Tegut, VollCorner, Lidl, Netto, REWE, KoRo, Roast Market
food restaurants_bars Restaurants, Lieferando, Cafes, Zeit für Brot, Baobab, Höflinger
personal_health beauty_cosmetics DM, Rossmann
personal_health pharmacy Apotheke, MVZ Dermatologie
transport apps_taxi Uber, RYD GMBH, MVG, Handyparken
shopping_clothing gifts Children products: Schlummersack, Catchy Kids, SP EVERY., Dukal, Berger-Lernwelt
shopping_clothing clothes_shoes Zalando, Ernsting's, Schuhmair, Thalia, Vinted, Airbnb, Hotel at Booking.com
shopping_clothing electronics Amazon, AMZN Mktp DE
housing renovation_maintenance IKEA, Markus Festl, Granit, Sostrene Grene, Mol* tischdecken, Gaertnerei, Dehner
education courses_college Kathrin Orlob (PEKiP), Nerina Aupperle
leisure streaming WOW wowtv.de
financial_other bank_fees Unidentified PayPal, Ratepay, N26 fees
Geschenke & Transfers (income) One-off incoming transfers

Step 2 — Create subscriptions

get_subscriptions_meta()    ← get category_id and payment_method_id

Standard Cookie household subscriptions (as of 2026-07):

Name Amount billing_cycle cycle_interval category_id payment_method_id
Miete 1080.00 monthly 1 6 (Other) 6 (Bank Transfer)
Strom (SWM) 79.00 monthly 1 3 (Utilities) 6
Internet / TV / Telefon 29.99 monthly 1 3 (Utilities) 6
Hundefutter 75.00 monthly 1 6 (Other) 6
Netflix 8.00 monthly 1 1 (Entertainment) 6
Grover 16.90 monthly 1 6 (Other) 2 (Debit Card)
Rundfunk ARD / ZDF 55.08 monthly 3 1 (Entertainment) 6
KuKita Daycare (Leon) 503.00 monthly 1 5 (Education) 6
Lillydoo diapers 56.70 monthly 2 4 (Health) 3 (PayPal)

Monthly equivalent total: 1,838.60 € (Yuvomi applies cycle_interval to prorate).


Step 3 — Add recurring income entries

stage_add_budget_entry(
    title="Kindergeld",
    amount=55.00,
    category="Sozialleistungen",
    date="YYYY-MM-01",
    is_recurring=True,
    recurrence_interval="monthly",
)
commit_pending(pending_id)

Standard recurring income:

Title Amount category
Kindergeld +55.00 Sozialleistungen
Cookie Share +2650.00 Erwerbseinkommen (see recommended amount below)

Step 4 — Post variable transactions

For each non-skipped CSV row, call stage_add_budget_entry with the mapped category/subcategory and the actual transaction amount and date. Use the Partner Name + Payment Reference as the title (truncate to 100 chars).


Step 5 — Verify

get_budget_summary("YYYY-MM")
list_subscriptions()

Expected for a full month with KuKita:

  • Fixed expenses ≥ 1,838 € (subscriptions)
  • Variable expenses ≥ 500 € (groceries alone)

Calculated from JanJun 2026 data (Cookie account, one-offs stripped):

€/month
Fixed costs (subscriptions) 1,839
Miete 1,080
KuKita (permanent from Jul 2026) 503
Strom + SYNVIA + Rundfunk + Netflix + Grover + Hundefutter + Lillydoo 256
Variable (6-month averages) 1,032
Groceries 595
Children products 142
Dining & cafes 100
Transport 66
Drugstore 52
Clothing, Amazon, Pharmacy 77
Total monthly spend ≈ 2,871
Minus Kindergeld (fixed income) 55
Minus Pocket Money (conservative ~600 €) 600
→ Recommended Cookie Share ≈ 2,650 €
With 200 € buffer ≈ 2,850 €

Current Cookie Share (Jun 2026): 1,995 € — shortfall ~655 €.

The gap was covered by irregular Pocket Money top-ups (avg 962 €/mo over 6 months, but highly variable: 121 €3,000 €). KuKita starting in June is the biggest step-up; raising Cookie Share to 2,650 € makes the budget self-sufficient without relying on top-ups.


Changelog

2026-06-29 — Corrections from first real import

  • Subscriptions endpoint is /budget/subscriptions, NOT /subscriptions/ (404).
  • recurrence_rule RRULE strings are rejected by the API; use cycle_interval instead.
  • GET /budget/ (no filter) returns only non-recurring entries; use ?month= for full view.
  • Added Cookie Share recommendation (2,650 €/month) based on 6-month expense analysis.
  • Added full category taxonomy table.

2026-06-29 — Initial runbook

Created from JanJun 2026 N26 Cookie account analysis.