Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ canonicalUrl: string

**Publishing**: Raise a PR and review it. Then, per surface:
- `data/blog/` - stop at review. Never merge, never enable automerge. A human publishes blog posts.
- `data/devlog/` - review and merge. The `4h devlog sweep` schedule owns this surface and merges its own PRs.
- `data/devlog/` - review and merge. Follow the editorial standards in `NOTES.md`.
- Anything else - stop at review.

**Styling**: Minimal industrial design system (flat hairlines, sharp corners, IBM Plex Mono labels). Follow the conventions in `.agents/skills/site-conventions/SKILL.md` for any page or component work.
Expand All @@ -117,4 +117,4 @@ canonicalUrl: string
- **Analytics**: Umami (configured in siteMetadata.js)
- **Search**: kbar with local search index
- **Discord**: Real-time presence via react-use-lanyard
- **GitHub**: Calendar integration via react-activity-calendar
- **GitHub**: Calendar integration via react-activity-calendar
25 changes: 18 additions & 7 deletions NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Notes
# Devlog

The bar for `data/notes/`, the second content surface on this site. Longer first-person
The bar for `data/devlog/`, the second content surface on this site. Longer first-person
opinion pieces live in `data/blog/`; see `AGENTS.md` and
`.agents/skills/site-conventions/SKILL.md` for the shared formatting rules.

Expand All @@ -9,33 +9,44 @@ opinion pieces live in `data/blog/`; see `AGENTS.md` and
A note earns its place here if **a reader could act on it, or would otherwise have to
rediscover the thing themselves.** That is the whole test.

Write about a specific day's work or learning in the author's voice. Make the
project, question or activity recognisable in the opening. Ground claims in
evidence from that work or learning. Distinguish documented behaviour from direct
experience, experiments from tested fixes, and proposed changes from shipped work.
Do not imply the author encountered or fixed something without support.

Write one if:

- You hit a specific failure and worked out the cause and the fix.
- There is a behaviour of a tool that surprised you and you verified why.
- You found a pattern in a system that generalises past the one system.
- You investigated a concrete research question and can explain what the evidence
established, without presenting documented behaviour as a local reproduction.

Do not write one if:

- It is a report of what you shipped. That is a work log, not a note.
- It is a list of shipped changes with no useful observation or explanation.
- It is an opinion piece you could expand into a blog post. Put it in `data/blog/`.
- It only makes sense to people who already know your context.
- You could not state the symptom precisely.
- It only repeats a release announcement or another write-up without adding a
supported, useful lesson.

## Shape

- Frontmatter: `title`, `summary`, `date`, `tags`, `draft`, `icon`.
- `icon` must already be registered in `lib/post-icons.ts` (lucide icon names). The
navbar, index rows and detail header all resolve from that one map.
- `date` is the date the note was written, not the date you fixed the thing.
- `date` identifies the day being described. When backfilling, use the verified
work or learning date; use a date without a time when the time is unknown.
- Keep it short. If it runs past a few hundred lines, it is a blog post.
- Footnotes (`[^1]`) for citations, never a `## References` heading.
- No em dashes. No bold-as-speech. No AI slop openers or endings.
- Link to the primary source when there is one. A note that cites a GitHub doc is
worth ten notes that cite a forum.

## Notes are draft-free
## Drafts

`draft: true` still works and hides the note from the index, the feed and the
static params. The seed notes are published. Use `draft` while a note is still
rough.
static params. Keep an entry in draft while it is rough or its claims remain
unverified. Correct and verify withdrawn entries before republishing them.
38 changes: 0 additions & 38 deletions data/devlog/app-bundled-clis-are-missing-from-daemon-path.mdx

This file was deleted.

41 changes: 41 additions & 0 deletions data/devlog/betterfit-cold-simulator-ci.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: Getting BetterFit Through a Cold Simulator Start
summary: |
BetterFit's new iOS CI jobs were failing before the simulator fallback could run. I warmed CoreSimulator first, made selection failures recoverable and separated first-launch time from the test's total budget.
date: '2026-10-03 11:28:38 +1000'
tags:
- BetterFit
- iOS
- CI/CD
draft: false
icon: Bug
---

The new BetterFit iOS CI jobs exposed a difference between my warm local setup
and a fresh GitHub runner. The first `simctl` query could spend long enough
starting CoreSimulatorService to exceed the selection script's fifteen-second
timeout.[^fix]

The fallback was there, but the failed pick exited before it could run.

I changed the task to warm the daemon before querying, gave the pick sixty
seconds and let an empty or failed selection reach the any-iPhone fallback.
That addressed the setup path rather than just increasing the timeout around
the whole CI job.

## First launch has its own cost

There was a second budget problem after selection. The app-launch poll allowed
twenty seconds, and each test had a sixty-second wall that also included
`resetAndLaunch`. A fresh install on a loaded runner could consume most of that
before the assertions got going.

The launch poll moved to sixty seconds and the per-test budget to 120. The local
e2e run passed four tests in 58 seconds after the fixes. The PR records the
cold-start and forced-empty-selection checks separately from the earlier CI run,
which had passed UI tests and coverage but hit the e2e time limit.

The fix merged with the warm-machine path unchanged. It was a useful reminder
that a fallback is only real if the error path can actually reach it.

[^fix]: [BetterFit's cold-runner and e2e timing fix](https://github.com/echohello-dev/betterfit/pull/26).
39 changes: 39 additions & 0 deletions data/devlog/betterfit-figma-to-ios.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: Bringing BetterFit's Figma Work Into the App
summary: |
BetterFit's Figma direction and iOS code had drifted apart. I brought the electric-yellow identity, ledger components and rebuilt workout screens into the app, with the remaining lint debt called out separately.
date: '2026-09-28 17:30:29 +1000'
tags:
- BetterFit
- iOS
- Design Systems
draft: false
icon: Package
---

The BetterFit design work had moved on, but the iOS app was still carrying the
old ember-orange palette and earlier screen layouts. I used this pass to bring
the app back into agreement with the Figma direction.[^change]

The identity is now electric yellow, black ink and neutral structure. Instead of
giving every status another colour, the yellow ladder uses brightness alongside
words. Glass is reserved for floating chrome, and yellow text on light surfaces
has its own darker token.

I also added the `BFLedger` primitives: section rules, readouts, rows, quick actions
and the other pieces needed to make the screens feel like one app. WorkoutHome
and ActiveSession moved onto those components, alongside the profile, recovery,
sign-in and settings surfaces.

## More than a palette swap

The workout plan now has inline weight and reps editing, superset pairing and
equipment swapping. The active session carries the same direction through set
logging, ordering and the rest bar.

This was the app-screens-to-code pass, not proof that every part of BetterFit was
finished. The PR also called out twelve pre-existing serious SwiftLint violations
in untouched files. Keeping that distinction visible was more useful than making
a design sync sound like a clean bill of health for the whole codebase.

[^change]: [BetterFit's design-system and iOS screen sync](https://github.com/echohello-dev/betterfit/pull/23).
37 changes: 0 additions & 37 deletions data/devlog/bun-websockets-are-missing-pause-and-resume.mdx

This file was deleted.

43 changes: 0 additions & 43 deletions data/devlog/case-insensitive-disks-collapse-path-aliases.mdx

This file was deleted.

40 changes: 0 additions & 40 deletions data/devlog/claude-app-skills-leak-into-other-providers.mdx

This file was deleted.

26 changes: 0 additions & 26 deletions data/devlog/cleanup-timestamps-advance-before-the-work.mdx

This file was deleted.

Loading