Workflow
One project over three weeks, day by day, from madelog init to the link you send. What you type, what gets recorded, and what the page makes of it.
This page follows ledger, a CLI that reconciles bank CSV exports against invoices, from the first commit on Monday 31 August 2026 to a published page on Thursday 17 September. The log listings, analysis and summaries are the real output of madelog 0.1.0 over that log. Times in the log are UTC; the developer is in Zagreb, two hours ahead.
Before the first commit
Install madelog, then set the repository up while the intent is fresh. The four answers become the headline of the page, so write them the way you would say them to a person.
$ curl -fsSL https://madelog.app/install.sh | sh
$ cd ~/projects/ledger && git init -b main
$ madelog init
What are you building? A CLI that reconciles bank CSV exports against invoices
Who is it for? A small accounting firm that closes its books by hand
Which AI tools do you use? (comma separated) claude-code, cursor
Record AI sessions from Git AI? [Y/n] yIf you use an AI coding agent, install Git AI now. It attributes lines at commit time; a commit made before it was installed carries no attribution and never will.
Week 1: 31 August to 6 September
Monday. Two commits: the skeleton at 09:12 UTC and, after a note, the SQLite store with its first migration. The note takes ten seconds and lands between the two commits, anchored to the first:
$ madelog note "chose SQLite over Postgres: one binary, no service to run"
noted at 162c5dbThat order matters later. A decision followed by a commit that opens a directory no earlier commit touched (migrations/) is what the analysis calls a direction change.
Tuesday. A Claude Code session writes src/import.rs. Git AI attributes 51 of its 58 lines to the session; the hook records the commit and one ai_session event with the session's first prompt. At 17:05 a fix to the same file: the importer dropped the last row of a file without a trailing newline. Nothing to type; the hook records both.
Wednesday. Three commits on src/matcher.rs inside 50 minutes, all with "wip: matching by amount" in the subject. The analysis will call this a retry.
Thursday. A report command, reverted an hour and a half later, and two notes. One of them is private:
$ madelog note "dropped the report command for now: the client only needs the matched list as CSV"
noted at 50f2f57
$ madelog note --private "ask Ivana whether the bank export can include the counterparty IBAN"
noted at 50f2f57 (private, never published)The private note is in the chain and in madelog log, marked (private). It is not in the summaries, not in the preview, not on the page.
Week 2: 7 to 13 September
Nothing until Thursday the 10th. Then one commit of 12 files and 444 lines: the matcher rewritten around a rules table. Six days of silence followed by a large commit is a stall in the analysis, and the longest stall becomes a moment on the page, with the length of the gap and the size of the commit that ended it.
Week 3: 14 to 20 September
Tuesday. Documentation. Wednesday. A note, then a Cursor session writes the CSV export. Cursor's session id is not a Claude Code transcript, so the event has no prompt; the page will say "No prompt was recorded for this session". Thursday. The release commit, and time to look at what was recorded.
$ madelog log
1 2026-08-31T09:00:00.000Z intent A CLI that reconciles bank CSV exports against invoices
2 2026-08-31T09:12:00.000Z commit 162c5db feat: project skeleton
3 2026-08-31T09:40:00.000Z decision 162c5db chose SQLite over Postgres: one binary, no service to run
4 2026-08-31T10:05:00.000Z commit d7448f4 feat: sqlite store and first migration
5 2026-09-01T14:20:00.000Z commit fb7eeec feat: csv import with BOM handling
6 2026-09-01T14:20:01.000Z ai_session fb7eeec claude-code: Write src/import.rs: read a bank CSV with columns amount, reference, booked_on into a Vec<Row>. Strip a UTF-8 BOM, skip the header, store amounts as integer cents.
7 2026-09-01T17:05:00.000Z commit d366a14 fix: importer dropped the last row when the file has no trailing newline
8 2026-09-02T10:00:00.000Z commit fcd9b5f wip: matching by amount
9 2026-09-02T10:25:00.000Z commit b17e06a wip: matching by amount and date
10 2026-09-02T10:50:00.000Z commit 1595716 wip: matching by amount and reference
11 2026-09-03T09:30:00.000Z commit ea23143 feat: report command
12 2026-09-03T11:00:00.000Z commit 50f2f57 Revert "feat: report command"
13 2026-09-03T11:10:00.000Z decision 50f2f57 dropped the report command for now: the client only needs the matched list as CSV
14 2026-09-03T11:12:00.000Z decision 50f2f57 ask Ivana whether the bank export can include the counterparty IBAN (private)
15 2026-09-10T09:00:00.000Z commit 72ddd54 feat: matcher rewrite with explicit rules and a rules table
16 2026-09-15T08:40:00.000Z commit b80d5ec docs: usage and the matching rules
17 2026-09-16T09:05:00.000Z decision b80d5ec kept the export in the same binary: a second tool means a second install for the client
18 2026-09-16T11:30:00.000Z commit a54c60b feat: export matched rows as csv
19 2026-09-16T11:30:01.000Z ai_session a54c60b cursor: (prompt not recorded)
20 2026-09-17T16:02:00.000Z commit f850c1c chore: release 0.1.0Twenty events in three weeks, of which you typed four. Check the chain, then run the analysis:
$ madelog verify
chain ok
20 events, root fee0947a2807ec497d534040725b20c26975e617c6c45fc9623b10f1a546ae62
$ madelog analyze
4 patterns in this log:
fix_after_ai fb7eeec d366a14 d366a14 reworked AI-written code in src/import.rs two hours after fb7eeec.
retry fcd9b5f b17e06a 1595716 Three commits in 50 minutes reworked the same file.
revert ea23143 50f2f57 Reverted 2 files changed in ea23143 one hour earlier.
stall 50f2f57 72ddd54 After six days without commits, 72ddd54 changed 12 files (444 lines).
recorded 4 new pattern events
4 moments for the page:
1. Fixing AI-written code in src/import.rs (fix_after_ai)
fb7eeec ("feat: csv import with BOM handling") carried AI-written lines in src/import.rs. Two hours later, d366a14 went back to the same code: "fix: importer dropped the last row when the file has no trai...". Git AI attributed 51 lines in fb7eeec to the model.
2. A decision, then a new migrations/ (direction_change)
You wrote down a decision: "chose SQLite over Postgres: one binary, no service to run". The next commit, d7448f4, added 1 file under migrations/. It was called "feat: sqlite store and first migration".
3. A decision, then a new src/rules/ (direction_change)
You wrote down a decision: "dropped the report command for now: the client only needs the matched list as CSV". The next commit, 72ddd54, added 3 files under src/rules/. It was called "feat: matcher rewrite with explicit rules and a rules table".
4. Six days away, then 12 files at once (stall)
Nothing was committed for six days. Work restarted with 72ddd54 ("feat: matcher rewrite with explicit rules and a rules table"), touching 12 files and 444 lines. The next commit followed four days later.The retry and the revert are patterns but not moments: the page tells stories about fixes after AI, direction changes and stalls, and the summaries mention the rest. madelog publish runs analyze and summarize itself, so this step is optional; running it first lets you read the result without the preview in the way.
The summaries
Without Ollama, or with llm.provider = none, the template writes them:
$ madelog summarize
week 1 2026-08-31 to 2026-09-06 (generated) heuristic 01a0b382-67ed-7328-a588-dc65588b0c1e
In the week of 2026-08-31 you made 9 commits over 4 days. Most of the changes landed in src/main.rs, src/matcher.rs and Cargo.toml.
You wrote down 2 decisions: chose SQLite over Postgres: one binary, no service to run; dropped the report command for now: the client only needs the matched list as CSV.
week 2 2026-09-07 to 2026-09-13 (generated) heuristic 01a0b382-67ed-7328-a588-dc66939bf940
In the week of 2026-09-07 you made 1 commit over 1 day. Most of the changes landed in README.md, src/import.rs and src/main.rs.
No decisions were written down that week, and the analysis found no patterns.
week 3 2026-09-14 to 2026-09-20 (generated) heuristic 01a0b382-67ed-7328-a588-dc677b1e2c0f
In the week of 2026-09-14 you made 3 commits over 3 days. Most of the changes landed in src/export.rs, src/main.rs and README.md.
You wrote down 1 decision: kept the export in the same binary: a second tool means a second install for the client.
The analysis found 4 patterns that week: a fix after an AI session (d366a14 reworked AI-written code in src/import.rs two hours after fb7eeec); repeated attempts at the same files (Three commits in 50 minutes reworked the same file); a revert (Reverted 2 files changed in ea23143 one hour earlier); a stall (After six days without commits, 72ddd54 changed 12 files (444 lines)).
edit any of them with `madelog summary edit <id>`The four patterns are listed under week 3 because madelog analyze ran in week 3; a pattern event carries the timestamp of the run that found it. Week 2's paragraph reads thin because one commit is all there was. This is the moment to rewrite what reads wrong, in your own words:
$ madelog summary edit 01a0b382-67ed-7328-a588-dc66939bf940Your text replaces the template's on the page, with no "generated" marker.
Review and publish
madelog publish --local renders the page without sending anything. Open .madelog/site/index.html and read it as the company will: the headline, the four figures, the timeline, the moments, the attribution bar (81 AI-proposed lines of 746, 11 %), the "Not yet published" badge. If a session should not be there, hide it now:
$ madelog log --json | grep -B4 '"kind": "ai_session"' | grep '"id"'
"id": "01a05d57-5a68-7075-b25a-15867fd58d96",
"id": "01a0a9fb-1aa8-7e72-a32c-06e6ee576225",
$ madelog hide 01a0a9fb-1aa8-7e72-a32c-06e6ee576225
hidden. The session stays in the chain; the page will say one session is hidden.Then publish. The preview opens first; Enter confirms it, q aborts and sends nothing.
$ madelog publish
...
page /Users/ana/projects/ledger/.madelog/site/index.html
verify https://madelog-server-production.up.railway.app/v1/verify/north-fable-4xt3
published https://madelog-server-production.up.railway.app/p/north-fable-4xt3
Send that link. `madelog unpublish` takes it down again.Send the link. The company needs no account and no software; the page is one file that works with JavaScript off, and "Check the root" on the badge opens the server's record.
After sending
Keep working. Every commit is still recorded. When the project moves on, madelog publish again replaces the page at the same address with a new root, and the server keeps both roots in its history. When you want the page gone, madelog unpublish; when you want everything gone from your machine, rm -r .madelog and the two hook lines, as described under Uninstall.
What to do more of: write a note whenever you choose between two things. The notes are the only part of the record in your voice, they anchor two of the three kinds of moment, and the summaries quote them.