Compare commits

...

23 Commits

Author SHA1 Message Date
Eric Wagoner
37c513adb4 Add image render hook to show alt text as tooltips
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 22:44:27 -05:00
Eric Wagoner
1633f977e8 Add weeknote for January 24-30, 2026
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 22:08:03 -05:00
Eric Wagoner
7835af3d00 Date corrections 2026-01-28 09:39:04 -05:00
Eric Wagoner
caf7e826ca Add weeknote for January 17-23, 2026
Week of Inuhele convention in Atlanta, swim meet, international food
exploration in Duluth, 3D printed cormorant pendant, and meeting
MeduSirena the fire-eating mermaid.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 01:35:00 -05:00
Eric Wagoner
3dd816e6a6 Fix image file extensions to match actual filenames
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 21:12:51 -05:00
Eric Wagoner
2f3ee7f3de Add weeknote for January 11-17, 2026
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 20:51:14 -05:00
Eric Wagoner
fc1f1c0c67 Wordsmithing and tweaking scripts 2026-01-12 15:31:05 -05:00
Eric Wagoner
1a5d864d9b Add weeknote for January 4-10, 2026 and fix list template excerpts
- New weeknote covering the week's shipped work, reading, gaming, cooking, and observations
- Fixed list templates to show description excerpts consistently across main index and weeknotes page
- Updated layouts/_default/list.html to check .Params.description before .Description
- Updated layouts/weeknotes/single.html to display full excerpts with reading time

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-10 14:42:55 -05:00
Eric Wagoner
ca05e826f2 Show full article in RSS 2026-01-08 16:26:45 -05:00
Eric Wagoner
44a49088fe Fixed date 2026-01-08 15:08:34 -05:00
Eric Wagoner
9af5c735e4 Publish post 2026-01-08 15:07:02 -05:00
Eric Wagoner
1963ca966d Fixed link to ii blog 2026-01-06 09:37:33 -05:00
Eric Wagoner
7c3f9213b4 Formatting and date tweaks 2026-01-06 09:24:39 -05:00
Eric Wagoner
c52dc603e1 Update resume with expanded role history and tech details
- Add detailed progression through Infinity Interactive roles (2016-present)
- Add Elasticsearch to database skills
- Update infrastructure certifications (AWS, Atlassian)
- Update cloud platforms (GitHub, Google Cloud)
- Refine job titles for clarity

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-05 21:49:03 -05:00
Eric Wagoner
87707aa61c Add resume page and publish "I Thought I Had 15 Minutes" post
- Add standalone resume at /resume with professional two-column layout
- Publish blog post about automating standup prep
- Update post draft status to false

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-05 19:43:12 -05:00
Eric Wagoner
047905c51e Add weeknotes for December 28, 2025–January 3, 2026
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-04 00:37:36 -05:00
Eric Wagoner
f4ba98acb5 Fix post date to January 1, 2026
Update the cake post date from December 30, 2025 to January 1, 2026
since it was written and published today. Also renamed the folder to
match the correct date.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 14:25:19 -05:00
Eric Wagoner
fb2803ea69 Update cake post to use figure shortcodes with centered captions
Convert all images in the Yule log post to use Hugo's figure shortcode,
which provides centered, italicized captions below each image. The
existing CSS styling already handles the visual presentation with
drop shadows and proper spacing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 14:19:23 -05:00
Eric Wagoner
98607f936d Add new blog post: Either Way, There'll Be Cake
A story about making a gluten-free Yule log cake for second Christmas
with the family, complete with sugared cranberries, meringue mushrooms,
and a cake that split into sections but came together anyway.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-01 13:58:41 -05:00
Eric Wagoner
70847b14fb Add custom 404 error page
- Create custom 404 page matching blog layout and Eric's voice
- Includes helpful navigation links to home, tags, weeknotes, search
- References blog migrations since 2001 in a characteristically honest way
- Server-side nginx config added to blog.kestrelsnest.social.d/custom_errors.conf

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-29 11:36:02 -05:00
Eric Wagoner
84e54b08de Add weeknotes system with first entry
- Add weeknotes landing page with auto-listing of all entries
- Create first weeknote: December 20–27, 2025
- Add Weeknotes to secondary menu alongside Now/Then/Future
- Create custom layout to display all weeknotes chronologically
- Update weeknotes command to use date ranges and current time
- Credit Genehack for weeknotes inspiration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-27 11:06:20 -05:00
Eric Wagoner
2b98d186ef Add weeknotes system with /weeknotes command
- Create weeknotes archetype for manual post creation
- Add /weeknotes slash command that prompts through each section
  interactively (shipped, read, played, cooked, noticed, thinking, next)
- Add /weeknotes landing page explaining the concept
- Update CLAUDE.md with weeknotes documentation and voice guidelines

Weeknotes are brief weekly reflections—lighter than full posts, more
personal journal than polished article.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 14:11:55 -05:00
Eric Wagoner
77d818a7f2 Add temporal pages maintenance reminder to CLAUDE.md
Adds a section reminding to check /now, /then, and /upcoming pages
for needed updates when doing other blog work. These three pages
form a temporal view that should stay in sync with blog content.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 14:01:42 -05:00
51 changed files with 1091 additions and 22 deletions

View File

@@ -0,0 +1,108 @@
---
description: Interactive weeknotes blog post generator - prompts through each section and creates the post
---
You are helping Eric create his weekly weeknotes blog post. Weeknotes are personal reflections on the week—what happened, what was made, what was noticed. They should feel like a genuine personal update, not a status report.
## Reference Material
Before starting, read these resources to understand Eric's current context:
- `/content/now.md` - what Eric is currently working on
- Recent posts in `/content/posts/` - for voice and recent activity context
## Gathering Information
Use the AskUserQuestion tool to prompt Eric for each section. Ask these one at a time, allowing him to skip any with "skip" or "-":
1. **Shipped**: "What did you ship, build, fix, or finish this week? (Projects, features, code, creative work, household accomplishments)"
2. **Read**: "What did you read this week? (Books, articles, documentation, interesting threads)"
3. **Played**: "What did you play this week? (Video games, board games, experiments, fun side projects)"
4. **Cooked**: "What did you cook this week? (New recipes, Random Recipe Project experiments, notable meals)"
5. **Noticed**: "What did you notice this week? (In the garden, neighborhood, weather, cats, life in general)"
6. **Thinking About**: "What's on your mind? (Ideas brewing, problems you're chewing on, topics you keep returning to)"
7. **What's Next**: "What's coming up? (Plans for next week, upcoming events, things you're looking forward to)"
8. **Vibe Check**: "In one sentence, what was the overall feel of this week?"
## Generating the Post
After gathering responses, create the weeknotes post:
1. **Calculate the filename**: Use today's date in format `YYYY-MM-DD-weeknotes.md`
2. **Generate frontmatter**:
```yaml
---
title: "Weeknotes: [Start date][End date], [Year]" (e.g., "December 2027, 2025")
date: [ISO 8601 datetime with -05:00 timezone, set to current time to avoid future-date issues]
draft: false
tags:
- weeknotes
---
```
3. **Write the opening**: Take the "vibe check" response and craft it into an italicized opening tagline that captures the week's essence.
4. **Write each section**: Only include sections where Eric provided content (skip empty ones). For each:
- Use `## Section Name` heading
- Transform bullet points into brief, punchy prose or keep as bullets depending on content
- Add relevant links where appropriate
- Keep Eric's voice: concrete, specific, honest
5. **Voice guidelines** (from CLAUDE.md):
- Concrete over abstract—real project names, actual numbers
- Brief sentences work well for weeknotes
- Honest about setbacks alongside wins
- Forward momentum at the end
## Creating the File
Save the post to `/Users/ericwagoner/Sites/blog/content/posts/[date]-weeknotes.md`
## After Creation
Show Eric the generated post content and ask:
- "Want me to start the Hugo dev server so you can preview it?"
- "Any sections you'd like me to revise?"
If he wants to preview, run `hugo server -D` in the blog directory.
## Example Output
```markdown
---
title: "Weeknotes: December 2027, 2025"
date: 2025-12-27T10:45:00-05:00
draft: false
tags:
- weeknotes
---
_A week of small wins and steady momentum._
## Shipped
Built a pantry inventory app in two hours with Claude Code. Simple PHP/HTML, deployed to YunoHost. Already used it at the grocery store.
## Read
Finished the first few chapters of *Service Model* by Adrian Tchaikovsky. The robot narrator's voice is delightful.
## Played
More Outer Worlds 2. The corporate dystopia hits different when you're on vacation.
## Noticed
The cats have claimed the heating vent by my desk. Territorial negotiations ongoing.
## What's Next
Inuhele prep is ramping up. Need to finalize my schedule and pack the tiki shirts.
```

View File

@@ -6,9 +6,18 @@
"Bash(cat:*)", "Bash(cat:*)",
"Read(//Users/ericwagoner/Downloads/**)", "Read(//Users/ericwagoner/Downloads/**)",
"Bash(mysql:*)", "Bash(mysql:*)",
"Read(//Users/ericwagoner/Sites/ericwagoner.com/**)" "Read(//Users/ericwagoner/Sites/ericwagoner.com/**)",
"Bash(curl:*)",
"Bash(ssh:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(./deploy)",
"Bash(mkdir:*)",
"Bash(chmod:*)",
"Bash(ls:*)",
"Bash(pkill:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []
} }
} }

View File

@@ -1 +1 @@
{} {"content":{"posts":{"2025-12-30-either-way-therell-be-cake":{}}}}

1
.vscode/ltex.dictionary.en-US.txt vendored Normal file
View File

@@ -0,0 +1 @@
standup

View File

@@ -11,5 +11,6 @@
"other": "off" "other": "off"
}, },
"editor.minimap.enabled": false "editor.minimap.enabled": false
} },
"frontMatter.panel.openOnSupportedFile": true
} }

View File

@@ -52,12 +52,34 @@ hugo new content-name.md
The blog uses the "m10c" theme but has two additional themes available (henry, kestrel). Theme switching is done via `config.toml`. The blog uses the "m10c" theme but has two additional themes available (henry, kestrel). Theme switching is done via `config.toml`.
### Content Organization ### Content Organization
- `/content/posts/` - Blog posts
- `/content/posts/` - Blog posts (including weeknotes)
- `/content/now.md` - "Now" page showing current activities - `/content/now.md` - "Now" page showing current activities
- `/content/then.md` - "Past" page with historical content - `/content/then.md` - "Past" page with historical content
- `/content/upcoming.md` - "Future" page with upcoming events - `/content/upcoming.md` - "Future" page with upcoming events
- `/content/weeknotes.md` - Weeknotes landing page
- `/content/mytweets.md` - Local tweet archive page - `/content/mytweets.md` - Local tweet archive page
### Weeknotes
Weeknotes are short weekly reflections on what Eric shipped, read, played, cooked, and noticed. They use a lighter voice than full blog posts—more personal journal than polished article.
**To create a weeknote**: Run `/weeknotes` to be prompted through each section interactively.
**Manual creation**: `hugo new --kind weeknotes posts/YYYY-MM-DD-weeknotes.md`
**Sections** (all optional—skip any that don't apply):
- Shipped — projects, features, fixes, accomplishments
- Read — books, articles, interesting finds
- Played — games, experiments, fun projects
- Cooked — recipes, Random Recipe Project work
- Noticed — observations from garden, neighborhood, life
- Thinking About — ideas brewing, problems being chewed on
- What's Next — upcoming plans and goals
**Voice for weeknotes**: Brief, punchy, concrete. Less polished than regular posts. Okay to be fragmentary. The goal is marking time and noticing patterns, not crafting essays.
### Menu Structure ### Menu Structure
The site has four menu groups configured in `config.toml`: The site has four menu groups configured in `config.toml`:
- **main**: Home and Tags navigation - **main**: Home and Tags navigation
@@ -77,6 +99,23 @@ The site has four menu groups configured in `config.toml`:
- Posts are created with draft status by default (controlled by archetype) - Posts are created with draft status by default (controlled by archetype)
- The site integrates with multiple social platforms and services in the Kestrel's Nest ecosystem - The site integrates with multiple social platforms and services in the Kestrel's Nest ecosystem
### Temporal Pages Maintenance
When doing any work on the blog, check if the following pages need updates:
- **`/content/now.md`** - Current activities, projects, reading, playing, upcoming events
- **`/content/then.md`** - Completed projects, finished books/games, past events
- **`/content/upcoming.md`** - Future plans, events, projects in the pipeline
These three pages form a temporal view of Eric's life. New blog posts often signal changes that should be reflected here:
- A new project post might mean something moved from `/upcoming` to `/now`
- A project completion post means moving from `/now` to `/then`
- Event announcements should appear in `/upcoming` with dates/venues
- After events pass, move them to `/then`
Each page includes a "last updated" date in the opening paragraph—update this when making changes.
## Eric's Writing Voice & Style Guide ## Eric's Writing Voice & Style Guide
When writing or editing blog posts, maintain Eric's distinctive voice and structural patterns: When writing or editing blog posts, maintain Eric's distinctive voice and structural patterns:

37
archetypes/weeknotes.md Normal file
View File

@@ -0,0 +1,37 @@
---
title: "Weeknotes: {{ dateFormat "January 2, 2006" .Date }}"
date: {{ .Date }}
draft: true
tags:
- weeknotes
---
_[One sentence capturing the week's vibe]_
## Shipped
-
## Read
-
## Played
-
## Cooked
-
## Noticed
-
## Thinking About
-
## What's Next
-

View File

@@ -97,6 +97,11 @@ theme = "m10c"
name = "Future" name = "Future"
url = "/upcoming/" url = "/upcoming/"
weight = 3 weight = 3
[[menu.secondary]]
identifier = "weeknotes"
name = "Weeknotes"
url = "/weeknotes/"
weight = 4
[[menu.tertiary]] [[menu.tertiary]]
identifier = "mytweets" identifier = "mytweets"
name = "Local Tweet Archive" name = "Local Tweet Archive"

View File

@@ -1,13 +1,13 @@
--- ---
title: I Thought I Had 15 Minutes title: I Thought I Had 15 Minutes
date: 2026-01-06T12:00:00-05:00 date: 2026-01-06T09:00:00-05:00
draft: true draft: false
tags: tags:
- Programming - Programming
- Neurodivergence - Neurodivergence
- Automation - Automation
- n8n - n8n
lastmod: 2025-12-24T21:23:29.536Z lastmod: 2026-01-06T14:37:21.515Z
description: I automated the five minutes before standup, and accidentally learned something about how my brain works. description: I automated the five minutes before standup, and accidentally learned something about how my brain works.
--- ---
@@ -71,4 +71,4 @@ Since building this, I've noticed more of those quiet friction points. Minor ann
The standup automation taught me to look for them. And it taught me something about my own brain in the process—about the hidden costs I was paying without realizing it, and the value of systems that do reconstruction work so I don't have to. The standup automation taught me to look for them. And it taught me something about my own brain in the process—about the hidden costs I was paying without realizing it, and the value of systems that do reconstruction work so I don't have to.
If you want the technical details (the workflow JSON, the setup, the quirks I discovered), I wrote that up for [Infinity Interactive's blog](https://www.iinteractive.com/notebook/2025/12/18/automating-standup-prep.html). This piece is the human context around it. Why a simple automation mattered more than it should have, and what it accidentally revealed about how I work. If you want the technical details (the workflow JSON, the setup, the quirks I discovered), I wrote that up for [Infinity Interactive's blog](https://iinteractive.com/resources/blog/how-i-automated-my-morning-standup-with-n8n-and-got-an-unexpected-morale-boost). This piece is the human context around it. Why a simple automation mattered more than it should have, and what it accidentally revealed about how I work.

View File

@@ -0,0 +1,43 @@
---
title: "Weeknotes: December 1926, 2025"
date: 2025-12-27T10:45:00-05:00
description: Slow, like the world was on pause. Everyone else off celebrating while I hung out in the quiet of home.
draft: false
tags:
- weeknotes
lastmod: 2026-01-06T04:04:15.067Z
---
_Slow, like the world was on pause. Everyone else off celebrating while I hung out in the quiet of home._
## Shipped
Built a pantry inventory app to track dry goods, herbs, and spices. It already proved useful when it reminded me about a bag of self-rising flour I needed to use up.
Also finished a five-video series of fairy-themed foods for CONpossible (this year's theme: "Through the Fairy Ring"). Each one runs about a minute, short promotional pieces that'll also go up on the Random Recipe Project channel.
## Read
Honestly, not much. I've been writing more than reading lately, and I'm making peace with that. Didn't come close to my already modest 2025 reading goal, but the words have been flowing in the other direction.
## Played
Had a great Gloomhaven session on Sunday. We're all nearing retirement for our third round of mercenaries and deep into the main storyline. The end is in sight, which makes every session feel weightier.
## Cooked
The only standalone butcher shop in town closed for good on Christmas Eve. I bought two full racks of spareribs from them as a send-off and smoked them for six hours on Wednesday. First time I'd fired up the smoker in two years. I ordered replacement parts so I can get back to using it regularly. Made a big southern squash casserole to go alongside.
That pantry app earned its keep when it surfaced a bag of self-rising flour, so I made buttermilk biscuits from scratch with sausage gravy. Also picked up some alcoholic eggnog for our morning coffees this week. A little somethin' somethin'.
## Noticed
Last week was bitter cold. This week bounced to nearly 80°F on Christmas Day. Georgia.
## Thinking About
Just starting a new project at work, a simple web app on a limited budget. The kind of thing I could do in my sleep. Times are slow and lean right now, though, and the temptation is to throw everyone and everything at it just to keep people busy. I'm pushing back. We need to know how to do small, lean projects repeatedly and in parallel. That seems to be where the industry is headed.
## What's Next
My kids were both gone this week, and my partner and I don't really celebrate Christmas, so it was genuinely quiet. Next week they'll both be here, including my eldest who's about to start their final semester of college. We'll do what we call "Second Christmas," running through the traditions on time delay. Works better for us.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@@ -0,0 +1,52 @@
---
title: Either Way, There'll Be Cake
date: 2026-01-01T12:00:00-05:00
draft: false
description: A gluten-free Yule log for second Christmas, held together by willpower and ganache.
preview: ""
tags:
- cooking
- family
- locallygrown
lastmod: 2026-01-01T19:12:22.889Z
---
My kids were home together this week for what we call "second Christmas"—the post-holiday stretch when everyone's schedules finally align. While planning the dinner menu, they made a request: a Yule log cake.
We used to get one every year from Linda Johnson of [Sylvan Falls Mill](https://northeastgeorgia.locallygrown.net/growers/1646), a miller and baker who sold at my farmers market. She made a gluten-free version, which mattered because my eldest is celiac. It was always a special treat, the kind of thing that becomes part of your family's holiday vocabulary without you noticing until it's gone.
With less than two days before dinner and a full menu to prepare, I told them it seemed really intimidating. I'd never made one. But I said I'd try.
I've baked their birthday cakes every single year, all their lives. They describe what they want and I try to make it happen. Some years are triumphs. Some years are laughable catastrophes that we still talk about. But every year there's cake. This felt like the same deal.
{{< figure src="cranberries.jpg" alt="Fresh cranberries and rosemary sprigs coated in sugar, drying on parchment paper." caption="Sugared cranberries and rosemary, made the night before." >}}
I started with a box of King Arthur's gluten-free chocolate cake mix—no shame in a good shortcut—but I needed to turn it into something that could roll without shattering. The technique I borrowed from [Sally's Baking Addiction](https://sallysbakingaddiction.com/buche-de-noel-yule-log/) calls for separating eggs, whipping the whites to stiff peaks, and folding everything together for an airy sponge. I added two extra eggs beyond what the box called for and crossed my fingers.
The cake looked great coming out of the oven. I rolled it while hot in a cocoa-dusted towel, let it cool for three hours, and felt cautiously optimistic.
Then I unrolled it.
The cake had split into sections a few inches wide. It had decided to become a kit.
{{< figure src="disaster.jpg" alt="Unrolled chocolate cake split into several vertical sections, with whipped cream filling visible in the cracks." caption="The kit." >}}
I stood there for a moment, weighing my options. Then I decided to act like nothing was wrong. I spread the whipped cream filling over the pieces, rolled the whole thing back up as tightly as I could manage, wrapped the towel around the outside, and put it in the fridge overnight to think about what it had done.
{{< figure src="mushrooms.jpg" alt="Small meringue mushrooms with piped stems and caps, dusted with cocoa powder, standing on a silicone baking mat." caption="Meringue mushrooms, dusted with cocoa." >}}
The next day, when it came time to cut the diagonal branch piece and assemble it on the board for ganache, the log barely held its shape. I worked fast. The ganache went on, I dragged a fork through it for bark texture, and suddenly it looked like an actual Yule log instead of a chocolate-flavored anxiety dream.
{{< figure src="bark.jpg" alt="Chocolate yule log covered in ganache with fork-dragged bark texture, before decorations, showing the spiral of cake and cream at the cut end." caption="Bark texture achieved. Now it just needs a forest." >}}
The garnishes helped. I'd made sugared cranberries and rosemary the night before—just a simple syrup soak and a tumble in sugar, but they sparkle like little frozen gems. The meringue mushrooms took longer than expected (piping stems and caps separately, baking low and slow, gluing them together with melted chocolate) but they're the detail that makes the whole thing feel like a forest floor instead of just a frosted cake.
{{< figure src="forest-floor.jpg" alt="Close-up of decorated yule log with meringue mushrooms, sugared cranberries, and rosemary sprigs on chocolate ganache bark." caption="The forest floor." >}}
When I brought it to the table, my kids lit up. It held together when sliced—somehow—and they said it reminded them of the Sylvan Falls version while being its own thing. The almond flour base from the market version was different, but this worked.
Linda still sells at another market these days, up in Northeast Georgia. Still using my LocallyGrown software, which makes me unreasonably happy. The web of connections from that market keeps surprising me—people I haven't seen in years, still linked by the tools we built together.
I'd make this again. Maybe it'll be a new tradition. Next time might be a perfect specimen, or I might have to pivot to calling it "a decaying log on the forest floor." Either way, there'll be cake.
{{< figure src="finished.jpg" alt="Overhead view of completed yule log cake decorated with meringue mushrooms, sugared cranberries, and sugared rosemary on a wooden cutting board." caption="Second Christmas, 2025." >}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

@@ -0,0 +1,51 @@
---
title: "Weeknotes: December 27January 2, 2026"
date: 2026-01-03T12:00:00-05:00
description: Our time-shifted Christmas week was really peaceful. A couple more days before going back to work on Monday, and I'm trying to make the most of it.
draft: false
tags:
- weeknotes
lastmod: 2026-01-06T04:04:40.233Z
---
_Our time-shifted Christmas week was really peaceful. A couple more days before going back to work on Monday, and I'm trying to make the most of it._
## Shipped
Took most of the week off for the holidays with both kids here. Still managed to nearly complete a new client project we'd budgeted the entire month of January for, in about ten hours of work. Our first status call isn't until Tuesday and I've already got something over 90% of the way there. Sometimes things just come together in a near-perfect way, and I live for those moments.
On the other side, I spun down a SaaS product that never really came to fruition. There were many reasons why it didn't succeed, but it was still sad to turn off those lights.
## Read
Nothing this week, but something jumped right to the top of my to-read pile: _Automatic Noodle_ by Annalee Newitz. Deactivated robots come back online in an abandoned ghost kitchen and decide to make their own way doing what they know: hand-pulled noodles for the humans of San Francisco, who are recovering from a devastating war. Robots, food, post-apocalyptic city life? Right up my alley. I might shelve _Service Model_ temporarily so I can devour this one.
## Played
My Gloomhaven group won't be able to meet for a while, but the digital edition was on sale on Xbox for $20, complete edition. I put almost twenty hours into it this week and have only beaten two scenarios in all that time.
I know how to play the game really well, but the UI of the digital edition is beyond frustrating. So many things are undocumented, and I'm still figuring out how to do simple things like see the map while planning my round. My biggest gripe is that there's no undo function, and it's trivially easy to ruin a thought-out plan with one wrong button press. The closest they have is "restart round," which can mean losing half an hour of progress.
## Cooked
We had our Christmas meal this week. The kids chose ham, so I grabbed a big bone-in one on an after-Christmas sale (one of the benefits of Second Christmas) and used the included cherry vanilla cola glaze instead of my usual approach. Not terrible. We're still eating it several days later, but it's mostly gone. I also made baked potatoes, a big fruit salad, and a garlic-ginger stir-fried broccoli that turned out fantastic as a baked potato topper. Oh, and gluten-free cornbread.
The showstopper was the gluten-free yule log cake I largely winged and [documented on the blog](https://blog.kestrelsnest.social/posts/2026-01-01-either-way-therell-be-cake/).
The following night I set up an omelette station for dinner, which reminded me of one of my many college jobs in the campus cafeteria, where I often got to run the omelette station.
## Noticed
Cold and a little rainy, which made for good cozy time inside gaming and cooking.
## Thinking About
I'm on staff for two conventions in the next six weeks. The first is a cakewalk: sole technical troubleshooter for presenters all weekend at a tiki culture convention. I can do that work in my sleep or, as is the case here, with a different rum-based drink in each hand.
The other one is a steampunk-adjacent convention where I serve as costuming track director, and I'm really feeling the crunch on that one.
The five fairy food videos I made for CONpossible have been going live every other day and have been well received. YouTube is inscrutable as ever, but they've netted me several thousand views and a bunch of new subscribers. The con's social media team will be posting their versions in the coming weeks.
## What's Next
My youngest starts back to school Tuesday, beginning the second semester of sophomore year with a new slate of classes. She turns 16 in a month, so I need to start thinking about that. My eldest returns to college this weekend, so there's lots of coordinating to manage over the next few days.

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 KiB

View File

@@ -0,0 +1,60 @@
---
title: "Weeknotes: January 309, 2026"
date: 2026-01-10T09:00:00-05:00
description: The chair arrived. Buddhist monks walked through town. Fried chicken achieved maximum cronch.
draft: false
tags:
- weeknotes
- cooking
- conventions
---
The chair arrived.
![A reclining chair with gray upholstery and a bentwood frame, paired with a dark desk surface with pegboard holes for accessories](chair.jpg)
I backed a Kickstarter back in April, maybe, from a Ukrainian woodworker for a reclining chair and desk combo. A reward for finishing the LocallyGrown conversion, I told myself. I work almost exclusively at a standing desk these days, but sometimes you need to sit for reading, ketamine treatments, or experimenting with multiple giant monitors in VR. The chair finally showed up this week, assembled without drama, and it's exactly as comfortable as I'd hoped. Quality time was had.
---
## Shipped
It was back to work this week after the holidays. Things are uncomfortably slow in general, but my role has me touching nearly every project and potential project we're engaged with. There's been lots of context switching, lots of architecture decisions, and lots of opportunities to put new dev tools through their paces. The context switching suits my brain, honestly. It's the *unexpected* interruptions that wreck me, not the deliberate pivots.
## Read
I started *Automatic Noodle* this week. The real world is on fire and this was exactly the respite I needed, a few delightful minutes at a time.
## Played
I didn't do much gaming this week. I did pick up [A Gentle Rain](https://dryad-games.com/shop/a-gentle-rain-bloom-edition/), a meditative tile-placement game where you arrange lotus blooms on a pond. It takes about fifteen minutes, there's no competition, and it's pure pattern-making. It should be a good mental reset between tasks.
## Cooked
It was mostly a week of working through holiday leftovers, but I made one big production: a giant pile of fried chicken using Babish's "Ultimate Fried Chicken" recipe. The process involves a dry brine, a tempura-ish batter, and a double fry. He specifies a particular flour blend for maximum crunch, but I needed these gluten-free, so I improvised my own mix.
![Close-up of golden fried chicken pieces with a craggy, textured crust resting on a wire rack](fried-chicken.jpg)
I achieved plenty of cronch. I'd make these again when I'm feeling ambitious. They're more involved than my usual southern style, but worth it.
## Noticed
It was hot and muggy this week, which feels wrong for January. That'll flip hard next week; the highs won't reach this week's lows. Our youngest cat has some Maine Coon in him and his winter coat has fully arrived. He's more fur than flesh at this point, which will serve him well come the cold snap.
The bigger thing I noticed this week: Buddhist monks from the Walk for Peace pilgrimage passed through Lexington, Georgia, on their 2,300-mile journey from Fort Worth to Washington, D.C.
![Monks in saffron and maroon robes walk down a rural road, led by a monk with a tall walking staff. Aloka the rescue Peace Dog trots alongside. Community members line both sides of the road, many with palms pressed together in greeting, as a police vehicle with blue lights escorts the procession.](peace-walk.jpg)
My own philosophies lean more Taoist than Buddhist, but there's considerable overlap. It was a wonderful opportunity to be mindful and let them lead by practical example. I'm glad my youngest daughter and I could share a meal with these monks as they walked through our part of the country.
## Thinking About
I've written quite a bit lately, here and on the company blog, about using AI-powered dev tools with thought and intentionality. For various reasons I've felt the need to articulate the philosophy and ethics behind how I use them, not just demonstrate the workflows. Having it down in black and white creates accountability. It's harder to quietly drift when you've already said where you stand.
## What's Next
Inuhele, the tiki convention I help with, is in two weeks. CONpossible, the steampunk convention I help with, is in four. I have so much to do before then.
---
The vibe this week: I need the coming weeks to run well above my usual productivity, and my usual has been solid. I have a suspicion this is only going to ramp up from there. It's a good thing I have a comfortable chair for the occasional sit-down.

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View File

@@ -0,0 +1,76 @@
---
title: "AI as Tool, Not Creator: How I Learned to Stop Worrying and Front-Load the Thinking"
date: 2026-01-09T00:00:00-05:00
description: The craft is in the decisions. The tool just handles the transcription.
draft: false
tags:
- AI
- Writing
- Technology
- Philosophy
lastmod: 2026-01-12T20:30:45.342Z
---
_The craft is in the decisions. The tool just handles the transcription._
I use AI tools almost every day. I also have serious concerns about AI as an industry. These positions might seem contradictory, but I don't think they are.
I want to be clear up front: this is a personal statement about where I've landed after a couple of years of thinking about this while actually using the tools. Other people have landed elsewhere, and I respect that. The ethics here are genuinely unsettled, and anyone who tells you they have it all figured out is selling something.
---
The loudest voices in the AI conversation tend toward extremes. On one side: breathless enthusiasm, AI will write all our code and our novels and our grocery lists, resistance is futile and also why would you resist? On the other side: principled rejection, the entire enterprise is built on theft, using these tools makes you complicit, real creators don't need them.
I find myself in neither camp, which is uncomfortable. Camps are comfortable. You know who your people are. You know what to think when a new development hits the news.
But neither position survives contact with the details, at least for me.
---
The theft question is real and I won't pretend otherwise.
AI models learn by consuming enormous amounts of human-created work. So do humans—I learned to write by reading thousands of books, learned to code by studying other people's code. But human learning mostly happens inside systems of payment, consent, and attribution. I (or someone on my behalf) paid for those books. The authors got a cut. AI companies trained on the same material and in many cases paid nothing. Some of them scraped content that was never intended to be freely available. It's all been documented by the scrapers themselves.
Anthropic, whose tools I use almost exclusively, admitted to using pirated source material in their training data. To their credit, they've acknowledged it and are paying a settlement to affected authors. (Yes, I know the lawyers say they're not admitting guilt and they had the right to do what they did, but the legal system demands that. What's important is they stopped fighting and started paying.) Other companies are still fighting in court to avoid facing consequences for doing the same thing. That matters to me. It's not the only thing that matters, but it's not nothing.
The even more egregious form of theft is when models reproduce training material verbatim. No synthesis, no transformation, just copying. When an image generator spits out something that's clearly a specific artist's work with the signature smudged out, that's infringement. When a code assistant regurgitates a chunk of GPL-licensed code into your proprietary project, that's a problem. There's no learning happening there, just memorization and reproduction.
I haven't encountered that with Claude, though I want to be honest: that might be because of how I use it rather than because it never happens. I don't ask it to generate from whole cloth. I don't say "write me a short story in the style of Ursula K. Le Guin" or "create an authentication system." My usage pattern might simply avoid the places where the cracks show.
---
Here's what my actual workflow looks like.
This post you're reading started as a conversation with Claude. But look at what that conversation actually contained: I described what I wanted to write about. I explained my position on the ethics in my own words, working through the nuances as I typed. I gave detailed direction about voice, structure, what to include and what to leave out. I answered questions that pushed me to clarify my thinking. Sometimes I spoke aloud and dictated my thoughts. What you see printed here is already long, but the words I put down were many times longer still, eventually distilled, reorganized, and drafted into a cohesive essay.
By the time Claude produced a draft I felt was ready for editing, the creative work was done. The ideas, the positions, the voice—all mine, drawn from all my notes on this topic I put down over the last few days and then referenced with years of other writing I'd fed into the project to keep Claude from interjecting its training material into my words. What remained was assembly: taking the cloud of my words and editing them into a coherent shape.
That's what I mean when I say I use AI as a tool rather than a creator. My line: if I haven't already decided what to say, the AI doesn't get to decide for me.
My coding workflow follows the same pattern. I don't hand over big problems and wait for solutions. I think through the architecture myself. I work out the exact behavior I want. I break the work into pieces small enough that implementing each one is mechanical. Then I describe those small pieces in enough detail that all Claude Code has to do is transcribe my description into working syntax.
I've tried to structure my workflow so there's little opportunity to plagiarize, because the decisions that matter, the creative decisions, have already been made before the tool gets involved.
---
I still feel like a writer when I work this way. That surprised me at first, because I expected to feel like I was cheating somehow. But the feeling never came, and eventually I understood why.
The physical act of putting words on a page is necessary, but it's not where the writing happens. For me, writing happens in my head, in the false starts and reconsidered angles and sudden moments of clarity that I chase through the fog of a draft. All of that still happens. I'm doing it right now, choosing this word instead of that one, cutting a tangent that doesn't serve the piece, or noticing when a sentence lands wrong and figuring out why. Claude can help me move faster through the mechanical parts, but it can't do that noticing for me.
The same is true when I'm writing code. The craft is understanding the problem, designing a solution that will hold up over time, making tradeoffs that serve the humans who will use and maintain what you build. Typing the syntax is just how the decisions become real.
---
I've chosen to work almost exclusively with Anthropic's tools, and that's a deliberate choice rather than a default. Some of it is how the tools behave. Claude feels more like an extension of my thoughts than a magic box (and I understand how much what I wrote sounds like it is indeed a magic box), which matches how I want to work. Some of it is that Anthropic has been more thoughtful, or at least more transparent, about the ethical tangles than other players in this space. The settlement I mentioned earlier is an example. Acknowledging harm and making it right isn't nothing, even if it doesn't resolve every concern.
I'm not naive enough to think my choice of vendor solves the larger problems. The training data issues are industry-wide. The questions about what these tools will do to creative labor markets are real and unresolved. I've just decided that using the tools carefully and intentionally is a more honest position, for me, than either pretending there are no problems or refusing to engage at all. I've also decided not to passively hold this position. By being vocal about my choices—here, on social media, in conversations with other developers—maybe I can help lead others to make thoughtful choices of their own and collectively be the "market forces" that drive the technology in a beneficial direction instead of where megalomaniacal billionaires want it to go.
---
So that's where I've landed. AI as tool, not creator. Front-load the thinking, hand off the transcription. Stay alert to where the ethical lines are, even when they're blurry.
New tools have always created disruption, this I know. But if the balance shifts in ways I haven't anticipated, if my careful approach turns out to violate ethical lines I thought I was respecting, I'll have to reconsider. I'm not attached to being right about this. I'm attached to doing less harm than I would by ignoring the question entirely.
Other people will draw the lines differently, and I'm not here to tell them they're wrong. The technology is genuinely new, the implications are genuinely uncertain, and reasonable people can look at the same situation and come to different conclusions.
This is just where I am, for now, trying to thread a needle that keeps moving.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

View File

@@ -0,0 +1,57 @@
---
title: "Weeknotes: January 1016, 2026"
date: 2026-01-17T10:00:00-05:00
draft: false
description: Everything around me seems to be in motion this week. Kids moving through milestones, colleagues moving on to new things, seasons shifting. Even the birds are starting to come back.
tags:
- weeknotes
- cooking
- family
lastmod: 2026-01-18T01:46:29.567Z
---
Everything around me seems to be in motion this week. Kids moving through milestones, colleagues moving on to new things, seasons shifting. Even the birds are starting to come back.
## Shipped
Saturday I attended a UGA swim meet with my youngest, who's on her high school team. She's lucky enough to practice at the UGA natatorium, a genuinely world-class facility, and it was fun to watch the collegiate teams compete, including several nationally ranked swimmers.
![The UGA Gabrielsen Natatorium, showing the diving well, competition pool, and championship banners under the massive steel truss ceiling](natatorium.JPG)
There's something satisfying about watching people who are really, really good at something do that thing at full speed.
Sunday we took the eldest back to college for their final semester. They're packed with senior-level classes to finish out a degree in computer game design come May. On the way we explored Little Five Points, one of Atlanta's iconic neighborhoods. It felt appropriate: a neighborhood that's survived by constantly reinventing itself, visited on the cusp of a big transition.
Tuesday we went out for dinner, an extreme rarity for us. Half-price oysters and creole enchiladas. Both delicious.
Wednesday was our monthly virtual happy hour at work, where we bid farewell to an amazing co-worker who found much greener pastures elsewhere. He came to us right out of boot camp several years ago, and it's been a joy to watch him grow into a developer as capable as any we have. Bittersweet, but the right kind. The kind where you're genuinely happy for someone even as you'll miss them.
## Read
I found time for a few more chapters of *Automatic Noodles*, which remains a fun and interesting read. Also had to dive into documentation for Shibboleth, a single sign-on authentication system I'll need to integrate soon. The name is appropriately intimidating for an auth system. A word you have to pronounce correctly or be identified as an outsider.
## Played
Not much play this week, other than with the cats. I did start cleaning the craft area, something I should have done months ago, so I can get a few things done for the rapidly approaching steampunk convention. "Start" is doing a lot of work in that sentence.
## Cooked
On a friend's strong recommendation I picked up the River Cottage *Much More Veg* book and made the recipe she'd been raving about: a red cabbage biryani.
![Red cabbage biryani in the pan, showing the braised purple cabbage ribbons and turmeric-stained cashews](biryani-cooking.JPG)
I've never made a biryani before, much less a vegan one, and it was fantastic. I still have some cabbage left and will absolutely make it again. Tonight, even.
![The finished biryani plated with fresh cilantro and sliced red pepper](biryani-plated.JPG)
## Noticed
The songbirds are starting to return, which means I need to disinfect and refill the bird feeders and bath. They have cameras in them, and I love getting little video postcards throughout day. One of those small technological pleasures that actually delivers on its promise.
## Thinking About
Trying not to panic about all the stuff I wanted to do for the steampunk con that I haven't done. I wanted to have more done by now, but here we are.
## What's Next
It's a short work week for me so I can go help with Inuhele, Atlanta's tiki weekend. I can't wait. After a week of watching other people's transitions, I'm ready for three days of escapism and terrible puns about rum.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

View File

@@ -0,0 +1,68 @@
---
title: "Weeknotes: January 1723, 2026"
date: 2026-01-24T09:00:00-05:00
draft: false
description: The week started with chlorine and ended with rum. In between, international grocery exploration, storm anxiety, and a fire-eating mermaid who made me want to do more with my life.
tags:
- weeknotes
- Inuhele
- CONpossible
- 3d-printing
- family
---
The week started with chlorine and ended with rum. In between: international grocery exploration, storm anxiety, and a fire-eating mermaid who made me want to do more with my life.
---
Saturday I spent at UGA's competition pool watching Juniper swim her way through another big high school meet. She's a sophomore, solidly JV, but this was a personal-records kind of day—first place heat finishes, times dropping, the whole arc of improvement visible in a single afternoon. The older kids will graduate. She'll be ready.
Sunday took me to Duluth for the last in-person CONpossible staff meeting before the convention. But the real adventure was the food. Before the meeting I wandered through a Middle Eastern grocery store down the street from the hotel. Afterward I crossed to an enormous Vietnamese shopping center, which culminated in a truly excellent bánh mì eaten in the parking lot before the drive home. Duluth is a treasure trove of international markets and I've made it a habit to explore a new one each visit. I may never run out.
Monday was MLK Day—a work holiday. Some years I join one of the local service projects, but this year I put the 3D printer to work on items for CONpossible and one beautiful cormorant pendant for Inuhele.
![Close-up of a 3D printed cormorant pendant, hand-painted in black and silver with blue and gold accents, hanging on a black cord against a red shirt](cormorant-pendant.jpg)
The cormorant isn't Inuhele's mascot, but it's a tropical, oceanic bird—adjacent to the traditional tiki imagery but my own. I wanted something that felt both handmade and a little fancy. A few hours of printing, a few more of careful painting, and I had something I was genuinely proud to wear.
Tuesday and Wednesday were my only work days this week, and by Wednesday evening the weather forecast had solidified into something alarming: a potentially catastrophic ice storm arriving over the weekend, right when we'd be in Atlanta at Inuhele. I split my attention between actual work and storm preparation—weatherproofing the house, arranging extra care for the cats, packing for what might become a longer stay than planned. Tuesday night I managed dinner and drinks with a dear friend I hadn't seen in far too long. She's been traveling internationally and in-person sightings have been rare. It was good medicine before the anxious Wednesday that followed.
---
Thursday morning I finished freeze-proofing the house, then we drove to Atlanta for [Inuhele](https://inuhele.com) setup day. This is one of my favorite parts of being on staff: the transformation. You arrive at a generic hotel conference space and leave behind a tropical, kitschy paradise.
![Person standing next to a large Creature from the Black Lagoon statue in a hotel hallway](creature-greeting.jpg)
![Golden skeleton wearing a hat and lei, seated on a wooden barrel surrounded by ropes and nautical decor](skeleton-on-barrel.jpg)
![Floral arch with tropical flowers at the entrance to the convention space](floral-arch-entrance.jpg)
![Main Inuhele stage with thatched roof, tapa cloth backdrop, and peacock chairs under string lights](main-stage-setup.jpg)
By Thursday night the space had become something else entirely.
---
Friday was the first full day of the convention. I'm the A/V and general tech support person for Inuhele, but my workload this year was genuinely light. Light enough that I could do it with a drink—or two—always in hand.
![Evening scene at Inuhele with string lights, colorful lanterns, and attendees in Hawaiian shirts mingling](evening-atmosphere.jpg)
![Mirror selfie showing Eric in tiki toga party attire: blue embroidered fez, purple sash draped as a toga over a tropical shirt, and the cormorant pendant](friday-outfit.jpg)
![Two people in matching silver space suits at a mobile bar cart](space-couple-bar.jpg)
![Hand holding a cocktail garnished with a lime wheel, cherry, ti leaf, and small hibiscus pick in an Inuhele-branded cup](inuhele-cocktail.jpg)
I love this convention and the people who come to it. The creativity and silliness seem boundless. People show up in elaborate costumes, build themed room parties, treat the whole weekend as collaborative performance art.
My favorite new person was [MeduSirena](https://www.instagram.com/fireeatingmermaid.medusirena/), billed as "the fire-eating mermaid." Her approach to art and performance mirrors my own sensibilities so closely—but she actually goes out and *does* it, full time. I only dabble. Watching her made me want to do more. Not necessarily fire-eating or mermaid-ing, but *something*. She's the kind of inspiration that sticks with you after the convention ends.
---
**Shipped:** One hand-painted cormorant pendant. The CONpossible prints are still on the printer, waiting for paint.
**Noticed:** Duluth's international food scene keeps rewarding exploration. And MeduSirena reminded me that "dabbling" is a choice, not a constraint.
**What's Next:** An ice storm was bearing down on Georgia as Friday ended. We were safely in Atlanta with the cats cared for at home, but the forecast looked bad. More on that next week. CONpossible prep continues—those prints need painting.
**Vibe Check:** A week that built from routine through anxiety and released into something joyful.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 MiB

View File

@@ -0,0 +1,63 @@
---
title: "Weeknotes: January 2430, 2026"
date: 2026-01-31T09:00:00-05:00
draft: false
description: One day you're watching fire dancers in a hotel ballroom transformed into a Polynesian paradise. Three days later you're on back-to-back video calls while ice encases everything outside your window.
tags:
- weeknotes
- Inuhele
- swimming
- ice-storm
- work
lastmod: 2026-02-04T03:01:17.216Z
---
One day you're watching fire dancers in a hotel ballroom transformed into a Polynesian paradise. Three days later you're on back-to-back video calls while ice encases everything outside your window. Convention weeks do that to you.
---
Saturday was the last full day of Inuhele, and it delivered. Panels all day, then a spectacular evening show where MeduSirena and her husband once again demonstrated why they're worth traveling to see: wit, creativity, and genuine mastery over their art form. After that, the room parties. If you've never been to a tiki convention, you might expect grass skirts and plastic leis. You'd be wrong. One room transported us to Victorian-era Coney Island. The attention to detail in these transformations is staggering.
!["Let Them Drink Rum." Tiki Marie Antoinette watches carnival jugglers in the atrium. Just another Saturday night.](atrium-saturday-night.jpg)
The reverie continued well into the early morning hours.
Sunday is usually a half day, but the incoming ice storm had other plans. Most attendees fled before noon, which meant those of us on crew got an early start on breakdown. Returning an immersive tropical paradise back into boring hotel conference space is its own kind of work: slower than setup, and a little melancholy. A dedicated crew stayed until after dark, loading everything onto trucks and depositing it safely back in the warehouse. A few of us closed out the weekend with dinner at the hotel bar, tired and satisfied.
![Monday morning, from the hotel coffee shop. We slept in and waited for things to warm up before making our escape.](ice-storm-monday.jpg)
The ice arrived overnight, though not as badly as feared. Northern Alabama got crippled; large swaths north and west of Atlanta were hit hard. We got a late checkout and made our careful escape back to Athens in the afternoon. The roads were fine even as the ice on the trees grew thicker the closer we got to home. Good thing we didn't wait much longer. Everything froze over again at sunset and stayed that way for two days.
---
One downside to being in charge of so many things: when I take time away, the work just waits. Tuesday was a full day of meetings, catching up on everything that had queued while I was hauling tiki bars and dodging ice. The town was still frozen over, but our power held, and I powered through.
Wednesday and Thursday I wrapped up a project I'd been sprinting on for five weeks: a community engagement portal for a university client. The final push involved rebuilding several major components after discovering, three days before deadline, that we'd been working from outdated brand guidelines. We still shipped on time. I wrote up the story for the [Infinity blog](https://iinteractive.com/resources/blog/why-we-build-the-runway-before-we-need-it). The short version is good infrastructure, centralized design tokens, and a tireless AI collaborator named Ray turned what could have been a crisis into just a hard few days.
But the technical save wasn't the satisfying part. It was the client's reaction when she saw her years-long vision finally realized. That kind of joy is why I do this work.
---
Friday was the final swim meet of the season: a local championship at the UGA pool with several area high schools competing. Juniper set more personal bests, continuing her trend of steady improvement all year. Swim season is brutal for everyone involved: near-daily evening practices stacked on top of a heavy class load. It was certainly a challenge this year. Good to have it behind us and settle into a more relaxed spring schedule.
---
**Shipped:** The university portal, after a four-week solo sprint and a three-day scramble at the end. One of the more satisfying deliveries I've had in a while.
**Read:** Honestly? Nothing. Convention weeks don't leave much room for reading.
**Played:** Also nothing. See above.
**Cooked:** Survival mode. Whatever was in the fridge that hadn't gone bad while we were gone.
**Noticed:** The strange beauty of ice-coated trees against gray skies. The whiplash of going from tropical escapism to frozen reality in 48 hours. And once the thaw finally came, Piglet and Wil'em reclaimed the sunny windowsill like nothing had ever happened.
![They do not care about your deadlines or your ice storms. They found the sun.](piglet-sunbathing.jpg)
![They do not care about your deadlines or your ice storms. They found the sun.](wilem-sunbathing.jpg)
**Thinking about:** How conventions create these intense temporary communities, then disperse. How the breakdown is part of the ritual—you can't just leave the magic standing. Also thinking about what happens after you ship something hard: the scramble, then the relief, then the quiet satisfaction once it's done.
**What's Next:** CONpossible is at the end of next week. Am I ready? Not even a little bit.
**Vibe Check:** Coming down from the high, digging back into the work,

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

10
content/weeknotes.md Normal file
View File

@@ -0,0 +1,10 @@
---
title: Weeknotes
type: weeknotes
aliases:
- /weeknotes/
---
Weeknotes are short, personal reflections on the week—what I shipped, read, played, cooked, noticed, and thought about. They're a way to mark time and notice patterns.
The format comes from the [weeknotes movement](https://indieweb.org/weeknotes), which grew out of the UK digital government community and spread through personal blogs. [Giles Turnbull's guide](https://doingweeknotes.com/) and [Tracy Durnell's reflections](https://tracydurnell.com/2024/07/30/using-personal-weeknotes-as-a-tool-for-attention/) shaped my approach. My friend [Genehack](https://genehack.blog/archives/) introduced me to weeknotes and inspired me to start my own after he'd been doing them for well over a year.

4
deploy
View File

@@ -3,6 +3,10 @@ USER=admin
HOST=social HOST=social
DIR=../../var/www/blog/www # the directory where your web site files should go DIR=../../var/www/blog/www # the directory where your web site files should go
# Clean build directories to force full regeneration
rm -rf public resources
# Build site and index, then deploy
hugo && pagefind --site public && rsync -avz --no-t --no-p --delete public/ ${HOST}:~/${DIR} # this will delete everything on the server that's not in the local public folder hugo && pagefind --site public && rsync -avz --no-t --no-p --delete public/ ${HOST}:~/${DIR} # this will delete everything on the server that's not in the local public folder
exit 0 exit 0

View File

@@ -62,5 +62,8 @@
"frontMatter.taxonomy.categories": [], "frontMatter.taxonomy.categories": [],
"frontMatter.content.autoUpdateDate": true, "frontMatter.content.autoUpdateDate": true,
"frontMatter.dashboard.openOnStart": true, "frontMatter.dashboard.openOnStart": true,
"frontMatter.preview.host": "http://localhost:1313/" "frontMatter.preview.host": "http://localhost:1313/",
"frontMatter.website.host": "https://blog.kestrelsnest.social",
"frontMatter.framework.startCommand": "hugo server -D -F",
"frontMatter.git.enabled": true
} }

24
layouts/404.html Normal file
View File

@@ -0,0 +1,24 @@
{{ define "main" }}
<article class="post">
<header class="post-header">
<h1 class="post-title">404: Page Not Found</h1>
</header>
<div class="post-content">
<p>Well, this is awkward.</p>
<p>The page you're looking for isn't here. Maybe it never was, or maybe it got lost in one of the many migrations this blog has been through since 2001.</p>
<p>Here are some places you might want to try:</p>
<ul>
<li><a href="/">Home</a> — Recent posts</li>
<li><a href="/tags/">Tags</a> — Browse by topic</li>
<li><a href="/weeknotes/">Weeknotes</a> — Weekly updates</li>
<li><a href="/search/">Search</a> — Find what you're looking for</li>
</ul>
<p>Or just <a href="mailto:eric@ericwagoner.com?subject=Broken link on blog">let me know</a> if you think something should be here.</p>
</div>
</article>
{{ end }}

View File

@@ -0,0 +1 @@
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}"{{ with .Title }} title="{{ . }}"{{ else }} title="{{ $.Text }}"{{ end }} />

View File

@@ -11,7 +11,7 @@
{{- $pages = $pages | first $limit -}} {{- $pages = $pages | first $limit -}}
{{- end -}} {{- end -}}
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }} {{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"> <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel> <channel>
<title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title> <title>{{ if eq .Title .Site.Title }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{.}} on {{ end }}{{ .Site.Title }}{{ end }}</title>
<link>{{ .Permalink }}</link> <link>{{ .Permalink }}</link>
@@ -32,17 +32,8 @@
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate> <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}} {{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
<guid>{{ .Permalink }}</guid> <guid>{{ .Permalink }}</guid>
<description> <description>{{ .Summary | html }}</description>
{{- $content := .Content -}} <content:encoded>{{ printf "<![CDATA[%s]]>" .Content | safeHTML }}</content:encoded>
{{- if .Params.summary -}}
{{- $content = .Params.summary -}}
{{- else if .Truncated -}}
{{- $content = .Description -}}
{{- else -}}
{{- $content = .Plain | truncate 200 -}}
{{- end -}}
{{ $content | html }}
</description>
</item> </item>
{{ end }} {{ end }}
</channel> </channel>

View File

@@ -17,6 +17,8 @@
<div> <div>
{{ if .Params.preview }} {{ if .Params.preview }}
<br />{{ .Params.preview }}<br />(more inside)<br /><br /> <br />{{ .Params.preview }}<br />(more inside)<br /><br />
{{ else if .Params.description }}
<br />{{ .Params.description }}<br />(more inside)<br /><br />
{{ else if .Description }} {{ else if .Description }}
<br />{{ .Description }}<br />(more inside)<br /><br /> <br />{{ .Description }}<br />(more inside)<br /><br />
{{ else }} {{ else }}

View File

@@ -0,0 +1,40 @@
{{ define "main" }}
<article class="post">
<header class="post-header">
<h1 class="post-title">{{ .Title }}</h1>
</header>
<div class="post-content">
{{ .Content }}
</div>
<h2>All Weeknotes</h2>
<ul class="posts-list">
{{ range (where .Site.RegularPages "Params.tags" "intersect" (slice "weeknotes")).ByDate.Reverse }}
<li class="posts-list-item">
<a class="posts-list-item-title" href="{{ .Permalink }}">{{ .Title }}</a>
<span class="posts-list-item-description">
<div>
{{ if .Params.preview }}
<br />{{ .Params.preview }}<br />(more inside)<br /><br />
{{ else if .Params.description }}
<br />{{ .Params.description }}<br />(more inside)<br /><br />
{{ else if .Description }}
<br />{{ .Description }}<br />(more inside)<br /><br />
{{ else }}
{{ .Summary }}
{{ end }}
</div>
</span>
<span class="posts-list-item-description">
{{ partial "icon.html" (dict "ctx" $ "name" "calendar") }}
{{ .PublishDate.Format "Jan 2, 2006" }}
<span class="posts-list-item-separator">-</span>
{{ partial "icon.html" (dict "ctx" $ "name" "clock") }}
{{ .ReadingTime }} min read
</span>
</li>
{{ end }}
</ul>
</article>
{{ end }}

324
static/resume/index.html Normal file
View File

@@ -0,0 +1,324 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Eric Wagoner - Resume</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 11pt;
line-height: 1.5;
color: #333;
background: #f5f5f5;
}
.page {
width: 8.5in;
min-height: 11in;
margin: 0 auto;
background: white;
display: grid;
grid-template-columns: 2.4in 1fr;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
}
.sidebar {
background: #1a365d;
color: white;
padding: 0.5in 0.3in;
}
.sidebar h1 {
font-size: 24pt;
font-weight: 600;
margin-bottom: 0.1in;
line-height: 1.2;
}
.sidebar .tagline {
font-size: 9pt;
opacity: 0.85;
margin-bottom: 0.35in;
line-height: 1.4;
}
.sidebar h2 {
font-size: 10pt;
text-transform: uppercase;
letter-spacing: 1px;
margin-bottom: 0.12in;
padding-bottom: 0.06in;
border-bottom: 1px solid rgba(255,255,255,0.3);
}
.sidebar section {
margin-bottom: 0.3in;
}
.sidebar p, .sidebar li {
font-size: 9pt;
opacity: 0.9;
}
.sidebar ul {
list-style: none;
}
.sidebar li {
margin-bottom: 0.04in;
}
.contact-item {
margin-bottom: 0.08in;
font-size: 9pt;
}
.main {
padding: 0.4in 0.4in 0.4in 0.35in;
}
.main h2 {
font-size: 12pt;
text-transform: uppercase;
letter-spacing: 1px;
color: #1a365d;
margin-bottom: 0.12in;
padding-bottom: 0.06in;
border-bottom: 2px solid #1a365d;
}
.main section {
margin-bottom: 0.25in;
}
.summary {
font-size: 10pt;
line-height: 1.5;
color: #444;
}
.job {
margin-bottom: 0.2in;
}
.job-header {
display: flex;
justify-content: space-between;
align-items: baseline;
margin-bottom: 0.04in;
}
.job-title {
font-weight: 600;
font-size: 11pt;
}
.job-dates {
font-size: 9pt;
color: #666;
}
.job-company {
font-size: 10pt;
color: #555;
margin-bottom: 0.08in;
}
.job ul {
margin-left: 0.15in;
font-size: 9.5pt;
}
.job li {
margin-bottom: 0.04in;
}
.early-exp {
font-size: 9.5pt;
color: #444;
}
.early-exp p {
margin-bottom: 0.06in;
}
.recognition li, .education p {
font-size: 9.5pt;
margin-bottom: 0.04in;
}
.ai-statement {
font-size: 9.5pt;
line-height: 1.5;
}
.ai-statement p {
margin-bottom: 0.1in;
}
@media print {
body { background: white; }
.page { box-shadow: none; }
}
</style>
</head>
<body>
<div class="page">
<aside class="sidebar">
<h1>Eric Wagoner</h1>
<p class="tagline">VP of Technology<br>Full-Stack Developer<br>Agricultural Technology Innovator</p>
<section>
<h2>Contact</h2>
<div class="contact-item">Athens, GA</div>
<div class="contact-item">eric@ericwagoner.com</div>
<div class="contact-item">linkedin.com/in/wagonereric</div>
<div class="contact-item">ericwagoner.com</div>
</section>
<section>
<h2>Languages & Frameworks</h2>
<ul>
<li>JavaScript/TypeScript</li>
<li>Node.js, Python, Java</li>
<li>Ruby, React, SvelteKit</li>
</ul>
</section>
<section>
<h2>Databases</h2>
<ul>
<li>MySQL, PostgreSQL</li>
<li>Elasticsearch</li>
<li>Database architecture</li>
<li>Migration strategies</li>
<li>Query optimization</li>
</ul>
</section>
<section>
<h2>Infrastructure</h2>
<ul>
<li>AWS, Atlassian (certified)</li>
<li>Docker, Linux</li>
<li>CI/CD pipelines</li>
<li>Github, Google Cloud</li>
</ul>
</section>
<section>
<h2>Practices</h2>
<ul>
<li>Test-driven development</li>
<li>Automated testing</li>
<li>Agile methodologies</li>
<li>System architecture</li>
<li>Legacy modernization</li>
</ul>
</section>
<section>
<h2>Education</h2>
<p>B.S. Astrophysics with Honors</p>
<p style="font-size: 8pt; opacity: 0.8;">New Mexico Tech, 1994</p>
<p style="margin-top: 0.1in; font-size: 8pt;">Sigma Pi Sigma Honor Society</p>
</section>
</aside>
<main class="main">
<section>
<h2>Professional Summary</h2>
<p class="summary">Technology leader with 30+ years building mission-critical software systems for biotech and research environments. Currently VP of Technology at Infinity Interactive, where I've designed web platforms for LIMS supporting genome engineering workflows, built software for liquid handling robotics used in NGS, PCR, and nucleic acid extraction, and served as senior technical advisor to biotech engineering teams. Scientific background (BS in Astrophysics, early career processing astronomical data at NRAO) provides foundation for working in research-driven, data-intensive environments. Equally skilled at designing greenfield applications and modernizing legacy systems; most recently completed a solo migration of a 19-year production platform to modern architecture with zero data loss.</p>
</section>
<section>
<h2>Professional Experience</h2>
<div class="job">
<div class="job-header">
<span class="job-title">VP of Technology</span>
<span class="job-dates">Jun 2023 Present</span>
</div>
<div class="job-header">
<span class="job-title">Manager of Software Delivery</span>
<span class="job-dates">Aug 2021 Jun 2023</span>
</div>
<div class="job-header">
<span class="job-title">Team Lead</span>
<span class="job-dates">May 2017 Aug 2021</span>
</div>
<div class="job-header">
<span class="job-title">Sr. Developer</span>
<span class="job-dates">Jan 2016 May 2017</span>
</div>
<div class="job-company">Infinity Interactive, Remote</div>
<ul>
<li>Lead technical strategy and delivery for a distributed team serving clients in biotech, healthcare, finance, and legal sectors</li>
<li>Designed and built web platforms for laboratory information management systems (LIMS) supporting genome engineering workflows: sample tracking interfaces, protocol management, and research data pipelines</li>
<li>Built software interfaces for liquid handling robotics platforms used in NGS library prep, PCR setup, and nucleic acid extraction: touchscreen UIs, protocol execution engines, and instrument integration layers</li>
<li>Developed data-intensive applications requiring high accuracy: tax filing systems, legal research portals, document management platforms</li>
<li>Selected and deployed optimal technology stacks for each engagement, balancing performance, team capabilities, and maintainability</li>
</ul>
</div>
<div class="job">
<div class="job-header">
<span class="job-title">Founder & Solo Developer</span>
<span class="job-dates">Jan 2005 Present</span>
</div>
<div class="job-company">LocallyGrown.net, Athens, GA</div>
<ul>
<li>Built and maintain a production platform serving hundreds of markets; processed over $16 million in transactions requiring financial accuracy and data integrity</li>
<li>Designed multi-tenant architecture with shared database supporting cross-market inventory synchronization</li>
<li>Completed a 6-month solo migration from legacy Rails to modern SvelteKit: 23 data models, comprehensive test coverage, zero data loss</li>
<li>Manage full lifecycle as sole developer: architecture, development, database administration, operations, support</li>
</ul>
</div>
<div class="job">
<div class="job-header">
<span class="job-title">Head of Testing / "Utility Infielder" Senior Dev</span>
<span class="job-dates">Jul 1997 Oct 2015</span>
</div>
<div class="job-company">Partner Software, Athens, GA</div>
<ul>
<li>Joined months after founding; grew with the company through every phase of the startup lifecycle</li>
<li>Developed web-based system configuration tools and workflow management systems for enterprise networks</li>
<li>Built an extensible data-to-PDF reporting system using XSL/FOP and later iText</li>
</ul>
</div>
</section>
<section>
<h2>Earlier Experience</h2>
<div class="early-exp">
<p><strong>Socorro Electric Cooperative</strong>, Engineering Technician (19941997): Managed GIS systems, oversaw enterprise software conversions.</p>
<p><strong>National Radio Astronomy Observatory</strong>, Student Employee (19921994): Developed scientific data processing tools in UNIX/Solaris; converted raw radio telescope data from India into a searchable graphical sky map with spatial indexing.</p>
</div>
</section>
<section>
<h2>Recognition</h2>
<ul class="recognition">
<li><strong>Barbara Petit Pollinator Award</strong> (Georgia Organics, 2015) Recognized for creating "a national model for connecting growers to consumers."</li>
<li><strong>Alec Little Environmental Award</strong> (UGA Odum School of Ecology, 2012) Honored for environmental responsibility and sustainable agriculture work.</li>
</ul>
</section>
<section>
<h2>Statement on the Use of AI</h2>
<div class="ai-statement">
<p>I use AI-assisted development tools extensively, and I've been deliberate about how.</p>
<p>The hype around AI makes it trivial to abdicate responsibility. Developers generate prodigious amounts of unmaintainable code that technically works for the happy path, call it productivity, and move on. I find that approach corrosive to the craft.</p>
<p>What I embrace is assistive AI: tools that amplify the skills I've spent forty years developing. They remove mechanical friction (transcription, syntax lookup, boilerplate) so I can focus on architecture, problem-solving, and building software that serves real humans. The thinking is mine. The decisions are mine. The responsibility is mine.</p>
<p>I name my AI coding agents after people who inspire me: George Washington Carver, Ray Eames, Ada Lovelace. The tools don't have personalities, but the names remind me who the work is for. They're lenses that focus intent, not collaborators with agency.</p>
<p>I've written extensively about this philosophy and regularly teach other developers how a more thoughtful approach can work, whether they've given in to abdication or been revulsed by it.</p>
</div>
</section>
</main>
</div>
</body>
</html>