Envelope budgeting ovanpå finance.journal
[2026-07-24 Fri]
Kuvertbudgeten ger varje krona ett jobb utan att blanda ihop budgetplanering med de verkliga banktransaktionerna.
finance.journal är sanningen om bank,
inkomster och utgifter.[budget:*]-posteringar.all.journal inkluderar båda
lagren.ledgerctl räknar den
auktoritativa statusen.Läs först Introduktion
till kuvertbudgetering om du vill förstå principerna bakom kuvert,
Ej fördelat, väntande köp och Att kategorisera innan du går vidare till
kommandona.
| Betydelse | Konto |
|---|---|
| Pengar på banken | konfigurerat assets:*-konto |
| Ej fördelat | budget:unallocated |
| Väntande inkomster | budget:pending-income |
| Ett kuvert | budget:groceries, budget:books, … |
| Virtuellt motkonto | budget:external |
| Verklig konsumtion | expenses:* |
Utöver balansinvarianten gäller en kuverttäckningsinvariant: varje
verklig post på ett budgetrelevant expenses:*-konto måste matcha exakt ett
namngivet kuvert. Noll träffar gör utgiften osynlig för budgeten; flera
träffar skulle tömma flera kuvert.
Det reserverade kuvertet Att kategorisera äger endast expenses:uncategorized och används som inkorg
för okända utgifter.
Systemets centrala balansinvariant är:
banktillgång + budget:external = 0
Om budgeten påstår att mer eller mindre pengar finns än banklagret
stödjer, misslyckas ledgerctl budget check.
Stå i en initierad ledgerctl-arbetsyta:
cd ~/budget
ledgerctl budget initDet skapar:
all.journal
budget/
envelopes.conf
auto.journal
funding.journal
och lägger normalt följande i ledgerctl.conf:
BUDGET_DIR=budget
ALL_LEDGER=all.journal
BUDGET_ENABLED=1Standardläget bootstrappar den ospeglade skillnaden mellan bankkontot
och budget:external till budget:unallocated. Hoppa över detta med:
ledgerctl budget init --no-bootstrap--force regenererar konfiguration och
genererade filer men bevarar den append-only historiken i funding.journal.
Den rekommenderade vardagsvägen är:
larin kuvert addKlienten frågar efter namn, kuvert-id och ett eller flera expenses:-konton. Kända konton har
TAB-komplettering. Motorn bygger en staged konfiguration, validerar den
och visar preview innan apply. larin
skriver aldrig envelopes.conf eller auto.journal direkt.
Direkt form:
larin kuvert add \
--label "Kläder" \
--id clothes \
--account expenses:shopping:clothes \
--account expenses:clothingAnvänd --preview-only för att granska
utan skrivning.
Lägg till eller ta bort kontorötter utan att redigera filer:
larin envelope update groceries \
--add-account expenses:restaurants \
--add-account expenses:fikaNamnbyte och borttagning kan kombineras i samma preview:
larin envelope update groceries \
--label "Mat och restaurang" \
--remove-account expenses:food \
--preview-onlyLedgerctl bygger envelopes.conf och
auto.journal i staging, kontrollerar
överlappning, reservkuvert och hledger check och publicerar filerna atomiskt
först efter apply.
När flera routes eller merchantkonton saknar kuvert:
ledgerctl suggest-envelopes
ledgerctl suggest-envelopes --scope all
ledgerctl suggest-envelopes --preview-onlyStandardomfattningen är routes. --scope all tar även med merchantstandardkonton
och verkliga journalposter. Assistenten:
Exempel: om du skriver Matvaror men
endast kuvertet Mat [groceries] finns,
visar assistenten det liknande befintliga kuvertet och frågar sedan om
Matvaror ska skapas som ett nytt kuvert.
Ett ja lägger bara till det i den ännu oskrivna planen; den samlade
previewn och slutliga bekräftelsen återstår.
När ett nytt kuvert skapas normaliseras namnet så att det börjar med
stor bokstav. Det permanenta kuvert-ID:t härleds därefter från det
slutliga namnet, skrivs med små bokstäver och använder bindestreck vid
behov. Skriver du matvaror blir därför
standardvärdena Matvaror och matvaror. Skriver du Hushåll och el blir standard-ID:t hushall-och-el. Båda värdena visas innan planen
godkänns och kan fortfarande ändras manuellt.
Valet detaljer visar endast underkonton
och konton i en tillräckligt specifik gemensam gren. För expenses:subscriptions:software kan exempelvis
expenses:subscriptions:streaming visas,
men ett enkelt konto som expenses:groceries leder inte längre till att
samtliga expenses:* listas.
Hela planen valideras mot den slutliga kuvertmodellen. Därför kan flera ändringar och nya kuvert publiceras som en enda revisions- och digest-skyddad mutation utan halvdant mellanläge.
För mer omfattande ändringar kan du redigera budget/envelopes.conf:
[settings]
asset_account = assets:se:swedbank:konto
currency = SEK
[income]
accounts = income:salary, income:other
[envelope groceries]
label = Mat
accounts = expenses:groceries, expenses:food
[envelope books]
label = Böcker
accounts = expenses:hobbies:books, expenses:hobbies:bookshopEfter varje ändring:
ledgerctl budget regen-auto
ledgerctl budget doctorEn kontorot matchar både kontot och underkonton. expenses:food matchar expenses:food:takeaway men inte expenses:foodtruck.
Kontorötter får inte överlappa mellan kuvert. Samma utgift skulle annars tömma flera kuvert och bryta invarianten.
Reserverade systemnamn som unallocated,
pending-income och external får inte användas som kuvert-id.
| Fil | Ägare | Redigering |
|---|---|---|
finance.journal |
bokföringslagret | endast med normal hLedger-försiktighet |
budget/envelopes.conf |
användaren | ja, följt av regen-auto |
budget/auto.journal |
ledgerctl | nej; regenerera |
budget/funding.journal |
ledgerctl | nej; append-only maskintillstånd |
all.journal |
ledgerctl-layout | ändra inte include-strukturen manuellt |
funding.journal har ett strikt
versionsmärkt format. Försök inte laga ett valideringsfel genom att göra
filen mer "hLedger-kompatibel" för hand; då kan hLedger och ledgerctl få
olika uppfattning om budgeten.
Snabb kontroll före import:
ledgerctl budget coverage --scope routesFull kontroll av routes, merchants och journalposter:
ledgerctl budget coverage --scope allResultatet skiljer på otäckta konton och konton som matchar flera kuvert. Verkliga journalposter utan entydigt kuvert är blockerande fel. En merchant med fel standardkonto rapporteras även om den ännu inte har skapat en journalpost.
Användarvänlig vy:
larin status
larin status --month 2026-07Motornära tabell och JSON:
ledgerctl budget status
ledgerctl budget status --month 2026-07
ledgerctl budget status --month 2026-07 --format jsonTabellen skiljer på:
Budgeterat: månadens avsiktliga
tilldelning,Använt: verkliga utgifter som mappas
till kuvertet,Kvar: tillgängligt efter budget och
utgifter,Pengar i JSON är exakta decimalsträngar, till exempel "700.00", aldrig flyttal.
ledgerctl budget history books
ledgerctl budget history books --month 2026-07 --months 12
ledgerctl budget history books --month 2026-07 --format jsonHistoriken visar bland annat:
För analys av ett kuvert:
ledgerctl budget analytics books \
--month 2026-07 \
--months 12 \
--format jsonledgerctl räknar förbrukningsgrad,
analystillstånd, historik och snitt. Emacs väljer sedan presentation:
SVG i grafiskt läge och Unicode eller ASCII i terminal. Konsumenterna
räknar inte om den ekonomiska analysen.
Följande budgetkommandon är preview som standard:
fund,move,set-budget,mirror,sweep-month,create, update och atomiska organize.--format json ändrar bara
presentationen. Det gör inte kommandot skrivande.
För att verkställa krävs:
--expected-revision REV,--apply.Om någon relevant fil ändras mellan läsning och apply stoppas operationen utan skrivning.
revision=$(ledgerctl budget status --month 2026-07 --format json \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["revision"])')Preview:
ledgerctl budget fund groceries 5000 --format jsonVerkställ med revisionen från den granskade previewn:
ledgerctl budget fund groceries 5000 \
--expected-revision "$revision" \
--format json \
--applyBeloppet ska vara positivt. Normalfallet tillåter inte att du
allokerar mer än vad som finns i Ej fördelat.
Preview:
ledgerctl budget set-budget books 900 \
--month 2026-07 \
--expected-revision "$revision" \
--format jsonVerkställ:
ledgerctl budget set-budget books 900 \
--month 2026-07 \
--expected-revision "$revision" \
--format json \
--applyDetta sätter månadens målbelopp genom en kontrollerad differenspost;
det skriver inte om äldre budgethistorik. set-budget får användas för aktuell eller
framtida månad. En framtida plan dateras kanoniskt den första dagen i
målmånaden.
I Emacs står du på kuvertet i den månad som visas och trycker e. Om budgetbokföringen har drift erbjuds en
separat mirror-preview. Efter godkänd reparation läses den valda månaden
om och den ursprungliga budgetredigeringen fortsätter automatiskt. Ingen
reparation sker tyst.
Preview:
ledgerctl budget move transport books 210 \
--month 2026-07 \
--expected-revision "$revision" \
--format jsonVerkställ med --apply efter
granskning.
Flytten påverkar inte Ej fördelat.
Källans budgeterade belopp får inte bli negativt, men dess faktiska
Kvar kan redan vara negativt när du gör en
medveten omprioritering.
En pending utgift (!) tömmer kuvertet
omedelbart, så att pengarna reserveras. När samma post blir cleared
(*) ska Kvar
förbli detsamma.
En pending inkomst läggs i budget:pending-income och kan inte fördelas. När
den blir cleared flyttas den automatiskt till budget:unallocated genom auto-reglerna.
Transaktioner utan statusmarkering träffar inte dessa regler och kan därför bryta invarianten. Använd pending eller cleared.
En överföring mellan egna konton ändrar bankkontot utan att vara inkomst eller utgift:
assets:se:swedbank:konto -5000 SEK
assets:se:sparande 5000 SEK
Då bryts invarianten tills ändringen speglas.
Preview mot Ej fördelat:
ledgerctl budget mirror --note "Överföring till sparande"Preview mot ett särskilt kuvert:
ledgerctl budget mirror \
--envelope buffer \
--note "Överföring till buffert" \
--format jsonVerkställ med previewns revision och --apply. När driften redan är noll är
operationen idempotent och skriver ingenting.
Preview:
ledgerctl budget sweep-month --format jsonKommandot visar vilka positiva kuvertsaldon som skulle flyttas till
Ej fördelat. Verkställ med revision och
--apply.
Negativa kuvert stoppar normalt sweep. Täck dem först med move. CLI-flaggan --force finns för ett uttryckligt undantag, men
Emacs-gränssnittet exponerar inte den.
Sweep skapar inte en permanent periodlåsning; det är en batchmutation som nollställer positiva månadssaldon.
Historiska perioder är skrivskyddade i Emacs. Budgetmål får däremot
planeras för aktuell eller framtida månad med set-budget eller e. Övriga normala budgetmutationer gäller
aktuell månad.
För en avsiktlig historisk rättelse via CLI krävs både ett explicit
datum och --allow-noncurrent, där
kommandot stöder det.
Exempel:
ledgerctl budget move transport books 100 \
--month 2026-06 \
--date 2026-06-30 \
--allow-noncurrent \
--expected-revision "$revision"Granska alltid sådana rättelser extra noggrant. Emacs exponerar inte den historiska undantagsvägen.
ledgerctl budget checkVid korrekt läge summerar bankkontot och budget:external till noll.
Djup kontroll:
ledgerctl budget doctor
ledgerctl budget doctor --format jsonKör budget mirror efter att du
verifierat den verkliga banktransaktionen.
Kör först:
ledgerctl budget coverage --scope allOm problemet är en route eller kontorot använder du ledgerctl suggest-envelopes eller larin envelope update. Om det är ett manuellt
köp med fel konto trycker du C i Emacs och
klassificerar om posten. Försök inte stänga sådan drift med mirror; då skulle klassificeringsfelet bara
maskeras.
Det tyder på överlappande kontorötter eller en manuellt modifierad
auto-journal. Kör ledgerctl budget doctor
och regenerera auto.journal först när
konfigurationen är korrigerad.
Återställ en känd korrekt version från backup eller versionskontroll. Redigera inte maskinjournalen godtyckligt.
ledgerctl archive tar snapshots av
budget/envelopes.conf och budget/funding.journal. Den aktiva, kumulativa
budgethistoriken fortsätter ändå in i nästa år.