All posts by Dave


This recipe is for one round-shaped sourdough loaf. You can adapt it to other forms, and I encourage you to experiment with different mixes of flours. The key thing that I’ve learned with wrangling sourdough breads it that there is a lot of room for experimentation, and failure often looks ugly but ends up tasting pretty good anyway.

If you don’t already have a sourdough starter, here are instructions for starting one.

I’m sharing this under CC BY 3.0. If you would like to repost the content of this recipe elsewhere, I would just ask for a link back to this page at

I’m writing this post from Olympia, Washington, with easy access to artesian well water which seems to make my sourdough culture (“yeast baby”) very happy. If you have access to a natural spring or decent well water, congrats! You’re extremely lucky. If not, you may want to try filtering your tap water and de-chlorinating it. I have resorted to bottled spring water in the past but its environmental effects are hard to justify.

Required hardware:

  • Kitchen scale that measures grams
  • Mixing bowl
  • Whisk
  • Knife (regular dinner table one, not a blade), spatula, or wooden spoon for mixing dough
  • Baking stone or cast iron pan
  • Baking tray/pan for holding water that adds moisture to the oven baking environment
  • Banneton (basket), or medium sized bowl and clean dish towel (not a fuzzy one) for final shaping
  • Bread knife (long knife with serrated blade)

Optional hardware:

  • Dough scraper (makes working with sticky dough easier)
  • Plate to cover the mixing bowl (to avoid plastic wrap)


White bread:

  • 500g bread flour (I use Giusto’s Organic Ultimate Performer Unbleached Flour when I can find it)
  • 345g water
  • 120g fed sourdough starter
  • 10g salt mixed into 15g water
  • Corn meal for dusting the baking stone

Whole wheat rye:

  • 250g white bread flour
  • 200g whole wheat flour
  • 50g rye flour
  • 355g water
  • 120g fed sourdough starter
  • 10g salt mixed into 15g water
  • Corn meal for dusting the baking stone
  • A separate mixing bowl to mix the different flours together


Pour the water into the mixing bowl (just the plain water, not the salt water that we’ll add later).

Mix the sourdough starter into the water with a whisk.

If you are using a mix of flours, first mix them together in a separate bowl from the water/sourdough mix.

Gradually add the flour into the sourdough/water mix. I like to use a knife for this part but you can use a wooden spoon or a spatula if you prefer that.

Once all of the flour is mixed in and the consistency is relatively even, let it sit for 5 minutes.

Start kneading the dough. Which method you use is entirely down to preference. Check out some youtube videos if you’d like some options. I prefer using a dough scraper at the beginning when the dough is most sticky, then letting it rest for a minute or two, and finishing kneading with my hands.

Turn (knead) the dough until it passes the window pane test.

Dump the salt water mixture on top of the dough and cover the mixing bowl. I use a plate that covers my mixing bowl nicely to avoid using plastic wrap. Let the dough sit covered until it has risen visibly (but not doubled). If we mixed in the salt at this point it would inhibit the yeast.

This stage is called “bulk fermentation”. If the ambient air temperature is warm (65°F+), opt for a shorter time. If the humidity is very low (dry air), you may want to sprinkle some extra water on top of the dough to prevent it from drying out and developing a skin (if it does develop a skin, it’s not the end of the world, but there may be little flaky or chunky bits in the final product — although sometimes they disappear after being mixed in and sitting for long enough).

After it has risen a bit, but not doubled, mix the dough by hand just enough to evenly distribute the salty water that we dumped on top.

Cover the dough again and let it sit for another hour to few hours (depending on ambient air temperature).

Check back on the dough and do the poke test.

Once the dough has passed the poke test, put it directly into the coldest part of your refrigerator — usually towards the back of the bottom shelf. If it looks very dry on top, sprinkle some water on top of it to prevent it developing a skin.

Let it sit there and slowly cold ferment for 12 to 48 hours. Longer than 48 hours can work if you have a very cold fridge (closer to but not quite freezing) and want a super tangy bread. Otherwise the dough may start to develop a layer of alcohol on the surface which indicates that the yeast is starting to become spent. You will have to experiment with how long of a cold fermentation you prefer based on baking qualities and taste. Generally the longer the fermentation, the more sour and tangy it will taste, up until a point where the dough is over-fermented and won’t rise nicely anymore in the oven.

Once you have finished cold fermenting your dough, pull it out of the mixing bowl and shape it roughly into a ball. It may need to rest a bit at room temperature in order to become pliable enough to shape. If you are using a banneton, lightly dust it with flour to prevent sticking and plop the dough ball into it. If you don’t have a banneton, take a clean dish towel (one without furry fibers) and lay it inside the bowl. Lightly dust it with flour and plop the dough ball inside the bowl. Then lightly dust the top and edges of the dough ball and wrap the sides of the dish towel over it. Make sure there is some dusting of flour covering all of the contact points with the towel so that it doesn’t stick when you’re trying to transfer it to the oven.

Let the dough sit in the banneton or bowl for about an hour at room temperature, or preferably longer and in the fridge, to take its final shape.

Place your baking stone or cast iron in the middle rack of the oven and preheat the oven to 430°F. Make sure there is enough room for the bread to rise between racks, so take out the top rack or move it out of the way.

After the oven has reached temperature, boil enough water to cover 1/4″-1/2″ of your baking sheet.

Place the baking sheet on the lower rack and pour the boiling water into it.

Dust the center of the baking stone (or cast iron) with corn meal to prevent the bread from sticking. If you really don’t like corn meal you can skip this part at the risk of your bread sticking or having a split bottom. I personally detest corn meal on my pizza but don’t mind it on the bottom of a loaf.

Take the dough ball out of its container upside down so that the wide part is on the bottom, and plop it dead center of the baking stone. The advantage of a banneton here is that you can transfer it directly from the basket onto the baking stone. With a bowl and towel I often have to catch the dough ball in my hands for a few seconds before placing it on the stone to avoid scorching the towel.

Score the top of the bread with a knife. I use a cross pattern (like a + sign) and tend to do a deep slash (about 1/2″) across the entire top. That way it avoids the loaf splitting during oven spring by defining channels for gas and moisture to escape from the dough while it bakes. You can experiment with your own patterns and depth. If your loaf still splits or has weird puffs, it could be due to under-proofing at some stage — not letting it sit long enough for bulk fermentation, or it may not have had enough time for final shaping in the bowl/banneton. It could also be that your sourdough starter is extremely potent, and you can try using less the next time around.

Let the bread bake for 30 minutes — or a little less if you have a convection oven. If you don’t have a convection oven, halfway through this initial baking period you may want to turn the bread around 180° to bake it evenly on the other side.

After 30 minutes, pull the pan of water out. Decrease the oven temperature to 350°F.

Bake for at least another 10 minutes. If you want a crisper and thicker crust, bake longer, up to 20 minutes or until the crust looks like the color you want, possibly with a reduced temperature, down to 275°F.

Turn the oven off when you think the crust is to your liking.

If you want a very moist crust, put the pan of water back into the oven and let it sit for a few minutes. Then as you take the warm bread out of the oven wrap it in a dish towel to prevent some of the moisture from escaping.

If you want to preserve a very crispy crust, pull the bread out and put it onto a cooling rack immediately; or if you don’t have a cooling rack, leave it in the oven with the door open until it cools off, at the risk of over-baking the bread a bit. Let it cool completely before slicing into it.

I hope you end up with the good results that I do. If not, yell at me in the comments. I’ll probably blame it on your sourdough culture though. 😉

Apple pwnz u

In order to delete an Apple ID, you first must have access to the device that is associated with it. Then you have to get an activation code through Apple’s website from that device through the network, and submit a form and wait up to 7 days, during which time they retain the right to refuse your deletion request based on no particularly detailed policy. Once you have verified that your account is deleted from the device, you may no longer log in with your Apple ID to wipe the device. Catch 22. Apple pwnz u.

Moral of the story: remove your device from the account before requesting account deletion, then log out of your Apple device and “trust” Apple to delete your account.

Vue.js and self-closing tags

Self-closing tags don’t (usually) work in DOM-based (in-browser) Vue template code, but they do work from single-file (.vue file) templates that are run through a preprocessor. Some documentation assumes the use of .vue files and provide self-closing tags in their example code. If you copy and paste self-closing tags from documentation examples into browser-based code they may not work as expected. The solution is to add a separate closing tag for each element.

I recently ran into this problem while trying out bootstrap-vue tables. Using the example code, the b-btn (clear button) in the b-input-group-append would not exist until I closed the preceding b-form-input tag.

Here’s the relevant section from the Vue style guide:
Self-closing components

Explicitly allowing a third-party deb repo to change its origin name

I went to pray to the dist-upgrade gods today and must have angered them:
Reading package lists... Done
E: Repository ' stable Release' changed its 'Origin' value from 'Google, Inc.' to 'Google LLC'
N: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.

I read the apt-secure manpage; it has many grammatical errors but absolutely no information about how to explicitly accept this change of origin name.

The solution is found in the apt-get manpage:

           Allow the update command to continue downloading data from a repository which changed its information of the release contained in the repository indicating e.g a new major release. APT will fail at the update command for such repositories until the change is confirmed to ensure the user is prepared for the change. See also apt-secure(8) for details on the concept and configuration.

           Specialist options (--allow-releaseinfo-change-field) exist to allow changes only for certain fields like origin, label, codename, suite, version and defaultpin. See also apt_preferences(5). Configuration Item: Acquire::AllowReleaseInfoChange.

TL;DR: the solution is simple:
apt-get --allow-releaseinfo-change-origin update

Dave’s Chai Recipe

Single (coffee mug/1.5cup/~426ml) serving of Dave’s Chai

Required hardware:
Microplane/zester/cheese grater (for grating whole nutmeg)
Kitchen scale for following exact weights (optional)

Spice ingredients:
3-4 cardamom pods (1g)
2 big allspice berries or 3-4 smaller berries (0.3-0.4g)
3 whole cloves (0.2g)
1 star anise pod broken up into bits (1.5g)
4 white peppercorns (0.1-0.2g)
4 black peppercorns (0.1-0.2g)
1 inch/2.5cm piece of ceylon cinnamon stick (preferably, looks kind of like a cigar on the inside) or cassia stick (roughly 1g-1.5g or 1/2 a typical stick)
1-2 juniper berries (0.2g)
1/8tsp (.5ml) ground ginger or slice of fresh ginger (1.5g)
1/8tsp (.5ml) fennel seed (0.1-0.2g)
Whole nutmeg (for grating on top at the very end)

Other ingredients:
1.5 cup (~426ml) filtered water
1tbsp (15ml/4g) ceylon black tea
1tsp (5ml/10g) organic sugar
1tbsp (15ml) organic unsweetened soy milk

1.) Crush spices except for ginger and whole nutmeg with the botom of a heavy glass in a small sauce pot

2.) Heat the sauce pot to medium-low heat for a couple of minutes until the spices become fragrant, shaking a few times

3.) Add 1.5 cup of filtered water, add ginger, cover and bring to a boil

4.) Reduce to a simmer for 3 minutes, covered

5.) Bring back to a rolling boil, covered

6.) Once boiling, remove from heat and add 1tbsp (4g) of ceylon black tea

7.) Stir and let steep for 4 minutes, covered

8.) Add 2 level tsp (10g) organic sugar and stir

9.) Add 1tbsp (15ml) unsweetened plain soy milk and stir

10.) Filter over a sieve and pour through a funnel into your cup

11.) Grate a bit of whole nutmeg over the top with a fine microplane/zester


MediaWiki error Fatal exception of type “Wikimedia\Rdbms\DBQueryError”

It’s been quite some time since I used my local MediaWiki installation. I went to log in today to my wiki and was greeted with a strange error:
Fatal exception of type "Wikimedia\Rdbms\DBQueryError"

No details were provided even though I have set:
$wgShowSQLErrors = true;
$wgDebugDumpSql = true;

I then added this to my LocalSettings.php file:
$wgShowDebug = true;

That output finally gave me a clue – I needed to update my database schema! From there it was as easy as visiting /mw-config on my wiki and adding a one-time use key to my LocalSettings.php to upgrade the database.


UASP adapter seen by smartctl as unknown USB bridge

I recently bought a generic USB 3.0 to M.2 adapter. It has a JMicron JMS567 chipset that very recently had a quirk added to the Linux kernel that fixes UAS support. Even with this patch, smartctl returns:

/dev/sdb: Unknown USB bridge [0x152d:0x0578 (0x508)]
Please specify device type with the -d option.

This can be fixed by telling smartctl that it is a SCSI to ATA Translation (SAT) device:

smartctl -a /dev/sdb -d sat

Alpaca Forms (alpacajs) and adding another button that is only enabled when the form is valid

The submit button is disabled by default in Alpaca Forms until the form passes validation. You can add more buttons easily (see the documentation on forms) but having them share this behavior isn’t straightforward. The answer is to add the class ‘alpaca-form-button-submit’ to the button using the ‘styles’ property:

'form': {
        'attributes': {
            'id': 'alpaca_form'
        'buttons': {
            'another_button': {
                'label': 'Clickable when valid',
                'click': function(e) {
                'styles': 'alpaca-form-button-submit'

For a full explanation, search for the enableSubmitButton and adjustSubmitButtonState functions in the source code.