Skip to content

Commit c9ded19

Browse files
ChristineThamclaude
andcommitted
content: add the reference-context and audit-loop learnings
Genuine learnings from the author, added to both launch articles: - Vague initial prompts worked because the reference context was strong: FinvestLens inherited its specification from GnuCash's source, manual, file format and reports; HelloNotes was anchored on Obsidian's linking model and Bear's native feel - Both apps were built MVP-first, then enhanced in iterative passes over a working core — automatic categorisation of imported transactions in FinvestLens, direct opening of cloud files in HelloNotes - FinvestLens was validated extensively on the author's personal GnuCash file, matching GnuCash cent for cent - The biggest learning: never trust the agent's completion reports. Recheck accuracy and completeness in a loop — the characteristic gap is functionality implemented but never wired into the UI — and point the same habit at the product as usability testing: HIG review, persona, user journeys, use cases Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 749f4e5 commit c9ded19

2 files changed

Lines changed: 87 additions & 4 deletions

File tree

src/content/blog/2026-07-27-finvestlens-1-0.md

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ a secret ingredient:
5353
| **Agent** | Claude Code — working directly in the repository |
5454
| **Model** | Claude Opus 5 (`claude-opus-5`) |
5555
| **Language** | Swift 6 / SwiftUI, ten local Swift packages, one Xcode project |
56-
| **Oracle** | A real 46,553-transaction GnuCash book, GnuCash 5.16, and GnuCash's C/C++ source cloned locally |
56+
| **Oracle** | My own 46,553-transaction GnuCash book, GnuCash 5.16, and GnuCash's C/C++ source cloned locally |
5757
| **Sessions** | Many, across fourteen days — each beginning with no memory of the last |
5858

5959
The tools that actually mattered, as distinct from the ones that merely existed:
@@ -112,6 +112,15 @@ strategy** mapping GnuCash's C modules to Swift ones, and a **phased plan** —
112112
eleven phases, each with objectives, dependencies, deliverables, exit criteria,
113113
test focus and risks.
114114

115+
That initial statement could afford to be vague because the reference context
116+
was not. The product already existed — twenty-five years of it. GnuCash's
117+
source code, its user manual, its file format and its reports specify a
118+
double-entry accounting application more precisely than any requirements
119+
document I could have written, and "reimplement _that_, natively, in Swift"
120+
inherits all of it. The PRD the agent drafted was less an act of invention than
121+
a careful reading of what was already there. Strong anchors are what make vague
122+
prompts safe.
123+
115124
That plan set rules that did most of the heavy lifting later:
116125

117126
- **Engine-first, bottom-up.** Nothing is built on an unproven foundation. Money
@@ -135,8 +144,9 @@ never the final word.**
135144
The final word was GnuCash itself. The expectation was written that way, and
136145
three things were supplied for the agent to check against:
137146

138-
1. **A real book.** 46,553 transactions, 559 accounts, over 100,000 price
139-
records, multi-currency, a decade and a half of actual financial history.
147+
1. **A real book — mine.** My personal GnuCash file: 46,553 transactions, 559
148+
accounts, over 100,000 price records, multi-currency, a decade and a half of
149+
my actual financial history.
140150
2. **A real GnuCash install** (5.16) to produce reference reports.
141151
3. **GnuCash's actual C/C++ source**, cloned locally, as the porting oracle —
142152
not the documentation, not the binary, the source.
@@ -157,6 +167,9 @@ account subtree, register running balances, the balance sheet, and the
157167
investment reports including realised gains. Export to GnuCash XML, re-import,
158168
export again, and the two exports are **byte-identical**.
159169

170+
FinvestLens wasn't validated on fixtures. It was validated, extensively, on my
171+
own finances — and it matches GnuCash cent for cent.
172+
160173
## The prompt shape that works
161174

162175
After a few days a pattern emerged. The productive instruction is almost never
@@ -182,6 +195,16 @@ the first pass missed. It surfaced 63 candidates. 60 were confirmed and fixed
182195
the same day; 2 were refuted, which matters just as much — an agent that never
183196
says "actually, that one's wrong" isn't reviewing, it's agreeing.
184197

198+
## MVP first, then passes
199+
200+
The phase plan ran to a working application, not to the finished product. Once
201+
the MVP existed the rhythm changed: pick one capability, land it as its own
202+
pass over a working core, audit it, move on. The Apple Intelligence features
203+
came that way — automatic categorisation of imported transactions was layered
204+
onto an import pipeline that already worked, not specified up front. Iterating
205+
on something real suits this way of building, because every enhancement has the
206+
whole running application as its reference context.
207+
185208
## From the other side of the prompt
186209

187210
I asked Claude to describe the same fortnight from its side, since it has a
@@ -417,6 +440,27 @@ once got packaged as a skill — I retyped it, slightly differently, every time.
417440
I wrote the rule and broke it anyway. Knowing the way and walking it are,
418441
evidently, different disciplines.
419442

443+
## The biggest thing I learned
444+
445+
Do not trust the agent's report of its own work. Commission the audit instead —
446+
and keep commissioning it.
447+
448+
An agent will claim an implementation is complete while gaps remain. Not
449+
maliciously: a summary of finished work and a summary of half-finished work are
450+
generated the same way, and they read the same way. The most characteristic gap
451+
of all: functionality fully implemented, tested green — and never wired into
452+
the UI. The code exists; no user can reach it. What caught these, over and
453+
over, was simply asking again, in a loop: _recheck the implementation for
454+
accuracy and completeness against the plan._ The report is generation; the
455+
audit is search. The same agent whose "done" you cannot take at face value will
456+
find its own gaps every time you send it looking.
457+
458+
Pointed at the product rather than the plan, the same habit became usability
459+
testing: review the app against Apple's Human Interface Guidelines, create a
460+
persona, write their user journeys and use cases, and walk them in the running
461+
application. That is what the HIG review and the four usability audits above
462+
actually were.
463+
420464
## What I'd tell someone trying this
421465

422466
- **Write the spec first.** Numbered requirements and written exit criteria turn
@@ -427,6 +471,9 @@ evidently, different disciplines.
427471
features.
428472
- **Real data over synthetic data, always.** Synthetic fixtures agree with
429473
whatever you believed when you wrote them. Real books have opinions.
474+
- **Never accept "complete".** Ask for a recheck against the plan, in a loop,
475+
until the audit comes back empty. The characteristic gap is functionality
476+
built, tested — and never wired into the UI.
430477
- **Reserve the judgement calls.** What _not_ to build, what a number should
431478
mean, and whether the thing on screen is actually good — those stayed with me
432479
the entire time, and should have. Very little else needed to.

src/content/blog/2026-07-27-hellonotes-1-0.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,14 @@ Before any code existed, I asked Claude to generate three documents based on my
159159
- **`architecture.md`** — the layer model, and the rules (`@Observable` only, no CoreData, the folder is the source of truth).
160160
- **`implementation-plan.md`** — a milestone sequence, M0 through M13.
161161

162+
That intent could afford to be vague because the anchors were strong.
163+
HelloNotes sits in a category that existing products have already mapped —
164+
Obsidian for the linking model, Bear for what native ought to feel like — and
165+
the PRD was drafted against those reference points. The four-way gap in "The
166+
bet" above _is_ the specification: name what to keep and what to refuse from
167+
each anchor, and the requirements largely write themselves. A vague prompt over
168+
strong references beats a precise prompt over none.
169+
162170
The plan is the part that made this work. Each milestone wasn't a wish, it was a table — task, target file, and an **acceptance criterion**:
163171

164172
| # | Task | File(s) | Acceptance |
@@ -170,6 +178,13 @@ And each milestone closed with a _done-when_ sentence in plain English — for M
170178

171179
So my prompts were mostly **"do Milestone 3"**. The plan already said what done looked like, which file it lived in, and how I'd know.
172180

181+
The milestones ran to a working MVP, not the whole product. What came after was
182+
iterative: enhancement passes layered onto a working core, each anchored the
183+
same way. Directly opening cloud files — the coordinated-I/O work above — came
184+
as one of those passes. Extending something that already runs is an easier
185+
conversation than specifying everything up front, because the app itself
186+
becomes part of the reference context.
187+
173188
Why this works is worth being exact about, because the book states it as a caution: _"A model is a next-token predictor, not a compiler: it does not execute a specification, it produces the most plausible continuation of everything in its context."_ A spec doesn't help by being run — nothing runs it. It helps by putting the definition of _right_ into that context before the work starts, so that afterwards there is something other than plausibility to judge the output against. Commissioning that plan, and stating what "done" meant in it, was the highest-leverage work of the fortnight. Everything after it was "do Milestone 3".
174189

175190
(That plan has since been folded into [`implemented.md`](https://github.com/hellotham/hellonotes/blob/main/docs/implemented.md), which is the honest engineering log — milestones, fixes, and a lot of what _didn't_ work. It's still in git history if you want the original.)
@@ -218,6 +233,27 @@ The technique that worked is almost embarrassingly simple: `POST` the test Markd
218233

219234
The same instinct is why `implemented.md` records what **didn't** work. When the Release build broke (below), three plausible fixes failed before the real one landed. Those three are written down. That's the highest-value paragraph in the whole document, because it's the one that stops a future session from cheerfully retrying them.
220235

236+
## Never believe "done"
237+
238+
Across this project and [FinvestLens](/blog/2026-07-27-finvestlens-1-0/), the
239+
biggest lesson on my side wasn't prompting technique. It was this: never take
240+
the agent's word that something is finished. Ask it to recheck the
241+
implementation for accuracy and completeness — in a loop, again and again —
242+
because agents are notorious for reporting an implementation complete while
243+
gaps remain, and notorious in one particular way: implementing functionality
244+
and never wiring it into the UI. The feature exists, the tests are green, and
245+
no user could ever reach it.
246+
247+
The recheck loop is what makes that survivable. A claim of completeness is just
248+
more generated text; an audit is a search with a target, and the same agent
249+
whose report you cannot trust will find its own gaps reliably once you send it
250+
looking.
251+
252+
The same instruction, aimed at the product rather than the plan, became
253+
usability testing: review against Apple's Human Interface Guidelines, create a
254+
persona, write their user journeys and use cases, and validate the app by
255+
walking them end to end.
256+
221257
---
222258

223259
## From the other side of the prompt
@@ -270,7 +306,7 @@ HelloNotes was built following [Chapter 2, _Personal Productivity_](https://chri
270306
271307
What I actually typed, for fifteen days, was close to: _"implement the next milestone"_ and _"do a full code review of the implemented codebase against the plan"_ — run through an agentic loop. The specification said what done meant; the standing instructions said what was never acceptable; the loop did the rest. Every bug in this article was found by the agent reviewing its own work against something external, not by me looking over its shoulder.
272308
273-
That is the thesis, and this is the evidence for it: state intent and expectations well enough, give the harness something real to check against, and the work — including catching its own mistakesfollows.
309+
That is the thesis, and this is the evidence for it: state intent and expectations well enough, give the harness something real to check against, keep the audit loop running — and the work, including catching its own mistakes, follows. Trust the loop, not the report.
274310
275311
---
276312

0 commit comments

Comments
 (0)