Time until first hard stop: ## 8h
Time until next hard stop: ## 8h

Tim's The Bomb Dot Com

Burgeoning Exocortex

- Sept. 16, 2018, 7:20 p.m.


As a reasonable analog to Dan McKinley’s excellent essay, Choose Boring Technology, there is value in choosing boring methodologies. In the very smart book, Atul Gawande’s The Checklist Manifesto: How to Get Things Right, the story of the checklist was surprisingly a page turner despite the hidden value of checklists sounding entirely underwhelming at first.

One of the book’s greatest strengths is the riveting stories, as the author is a surgeon with war stories straight from the ER, and the greatest research into the effective use of checklists is in the study of aviation disaster prevention with its wealth of near misses (and near hits) to draw on. The greatest strength, however, is the subject material itself- checklists are unassuming, yet provide a reasonable answer to the question: is there a reason why air travel is not just safer, but orders of magnitude safer than other means of travelling?

To try to correctly sell the value of the pre-flight checklist or the book itself in a few sentences would be an injustice, although a reasonable attempt is the story of checklists becoming a permanent and mandatory tool in manned flight almost a century ago. I highly recommend the story and Atul Gawande’s book both.

So what does that have to do with an Exocortex? Well, it began with a desire to try this out in practice. It turns out the difference between a pre-flight checklist and a grocery checklist is distinct and meaningful, and putting together a little webapp for personal pre-flight checklists was an afternoon exercise:

A good checklist skips all the things that an expert would definitely do, and includes the few things that could be skipped but make a big impact. Surprisingly, I found a lot of value in the tool and have found myself using it daily. As someone who has written more than one toy productivity tool, I was amazed that checklists were somehow less boring than trying to remember the litany of little things I could get wrong in a given situation. I quickly made a clone of this for work and have been getting clear gains there as well.


That would have been that, but the Charles Stross’ book Accelerando is a perfect audiobook for a morning commute, and the transition from driving to walking is a perfect time for a checklist.

In Accelerando, estimates of the near future (which predate the announcement of the iPhone, somehow) include big jumps in human-computer interfaces. One tantalizing one is the ability to spin off search threads mid conversation, only to be presented with those results via a cool Magic Leap-esque headset when they’re ready. Of course, being futurism, this expands into adept users of technology running entire feasibility studies asynchronously via a cloud of workers, able to attack problems from several angles at once and turn impossible problems into simple solutions that work for everyone.

Without spoiling too much, at one point a headset is stolen to pawn for cash. In a twist of events, the thief dons the headset and has limited success walking into the life of its former owner- he is hurried along to meet schedules, presented with talking points and research for discussions he knows nothing about, and tries to hum along.

The idea of offloading mental workload into a computer gives rise to the idea of an “exocortex”, a part of the mind that exists outside of the head. At a certain level of integration, it becomes an indistinguishable part of who that person is.


Back in the real world, several checklists at work and home deep, I added this item to the top of my morning checklist:

As it turns out, whatever part of my mind grumbles about getting out of bed (aside, also the part that grumbles about doing dishes or picking up) is placated by putting on headphones and listening to music. It’s night and day- it turns out I can do almost any chores with some reasonably loud music playing. I know how to catch a plane when I need to, but getting out of bed on the first alarm has been a challenge my whole adult life. This seems to have solved the problem, and thoroughly.

Not to make a mountain out of a molehill, as this isn’t particularly noteworthy in and of itself. Music helps get people out of bed is not shocking. However, effectively convincing a brain into doing something it otherwise would refuse to do feels, well, worth thinking about. Being bad at getting out of bed in the morning isn’t a personality trait per say, but maybe always getting out of bed on time is. And if it’s not, what about the difference between not being caught flat footed in a meeting 85% of the time vs 100% of the time? Isn’t that the difference between the people who are at the top, and those near it?

Perfection is incredibly rare, and it gives a strong the impression to others. Does that make it a part of who someone is? How much does a webapp need to affect a person before it too is a part of who they are?

So the thought has been running through my mind. This toy productivity app has been extremely helpful, yet for the moment it remains a toy. But, as I write new checklists, as I add new toy productivity apps- I can’t help but admit these toys are becoming a bigger part of my successes and failures. That success and that failure will always be a part of what I believe myself to be. How much of this burgeoning exocortex is?

Carrots and Sticks - A VideoLAN Project

- April 1, 2018, 11:25 p.m.

A quick project to help spur creativity, self assessment and productivity- I found myself in need of a throwy camera, something I can place anywhere, and it will still stream video to my main machine.

Considering I'm knee deep in Raspberry Pi 3's, a bitchin webcam that has been sitting unused, and a UPS for the RPI I never set up, I figured it looked like a good combo.

Challengingly enough, getting video streaming out of an RPi3 is not easy nor well documented. Or if it is, I managed to find none of the prior art on the subject.

The first step I took in this direction was to find a great how-to guide which was up at the time of posting here, and props to Steven Gordon for putting it together. However, there were a couple of points that didn't work out of the box, but I liked it because it showed some command of the cvlc interface (rather than try to do this through the GUI), and it looked like a simple server-client setup that I wanted.

For starters, I set up another RPI with Raspbian, setting up the root device on a thumb drive and only leaving the boot partition on the sd card. Those damn SD cards are too finicky, even the class 10 ones, and I've not had trouble with corruption since I started doing this. I put together a repo for automating the process here, which goes over the theory behind the setup a bit more in depth.

However, installing VLC on the RPI and running cvlc as a server immediately was a failure:

# original command attemp cvlc -vvv v4l2:///dev/video0 --sout '#transcode{vcodec=mp2v,acodec=none}:rtp{sdp=rtsp://:8554/}'

The problem with this was two fold:

  • cvlc cli options are some dialect of greek
  • The "mp2v" codec throws errors

Looking into the error details, the MPEG2 codec, specified on the command line as mp2v, seems to not play nicely with the real time transfer (rtp) module.

The problem with vlc docs is that the subject is pretty beefy, so the docs get thick, fast. The biggest help was simply getting a clear description of two things, one being the command line string structure, and the other was the full guide to streaming modules and options. Once I had an idea of how those two work together, I could take all the crap settings I found in other one off blog posts that have gone out of date (like this most certainly has by the time you're reading it), and reverse engineer whatever the hell they were trying to do into something useful for myself.

Armed with a little more knowledge, I found that mp2v can be replaced by mp4v, and that was enough to get a server and client working successfully:

# transcode options transcode{vcodec=mp4v,vb=80,acodec=none,fps=30} # client, untouched: vlc -vvv --network-caching 200 rtsp://
This was super stuttery, and had a ton of graphical issues, but was cleary a POC that at least the concept would work.
I finally landed on these settings for the server, dropping the final resolution way, way down:

# transcode options transcode{vcodec=mp4v,acodec=none,fps=25,scale=0.333,threads=3}

Even still the actual framerate is nothing near the requested 25, but it's good enough a stream over the wifi that I could be using it for any variety of ML tests.


- Feb. 19, 2018, 11:57 p.m.

A self-hacking topic near and dear to my heart, I built a recurring task system into my blog. I was quite happy with it too, right up until I stopped using it.

Here's a quick description of the Upkeep system, some of the pros and cons, and then the future of the system.


A quick and dirty way to irregularly do regular tasks.

Problem Space

I have tunnel vision. Recently I've been stuck in work helping get software built, tested, and out the door, and because of my focus on that, I've forgotten to do some things I should do all the time. Some of these things are straight up more work- keep posting to my blog, reach out to thought leaders in the field, or work on a long term project that I need to keep touching once every few days.

Some of these things, admittedly, are bald faced examples of how much of a terrible human being I am. I forgot to reach out to my sister who is teaching abroad for two solid months- I also have some friends who are travelling, and keeping up with their travels is to share in their adventure.

Despite being busy, most of these things only take a couple of minutes (sending a text is inconsequentially small amounts of time to do, but the payoff in keeping up with people is huge). The ones that take longer pay off dividends on the effort put in several times over.

However, some things should be done once a week, others irregularly like week and a half or so, and some things, like submitting code or exercising, should be done every. single. day.

Upkeep: A System for Keeping Up With Stuff

So I made a blog system for recurring things. After writing a task, it has exactly one action that you can perform on it: DONE.

It also has only three attributes: a title, a description, and a wait time. A task that has less more than 75% of its wait time remaining is green, and goes in an All Tasks list. A task that has less than 25% of its wait time remaining is red, and goes in a Red Tasks list.

The routine is simple - look at the red tasks daily, and plan to close them all.

The Clearly Awesome Advantages of Such a System as Upkeep

This served me quite well for a long time. Despite it being Web 1.0, built from django templates and html redirects, I managed to keep regular/irregular contact with people I care about and always had an idea of what was going on in their lives.

I also did an excellent job of keeping up with small tasks that I wanted to do daily- at least break a sweat. Try to get 8 hours of sleep daily. And when I didn't- especially in the case of that last one, I got to see how long it had been since I could honestly say I'd done it, and it would nag at me.

The Inevitable Failure

Like all self-hacking, after an astoundingly capable couple of months, this failed miserably. There was one thing that stayed on my red list that never got done.

I never wrote a third blog post.

That grated at me, and was enough to annoy but not enough to make me stop using the Upkeep system. Well, one item led to two, and two items (and awful css) meant everything before the fold of the Red list never moved.

I skipped looking at the list until the weekend, when I knew I'd have time to do one of the big ticket items. Then I missed the weekend and two weeks later I'd forgotten all about it. Tunnel vision had set back in.

The Underlying Problems

Some tasks are more difficult than others, and not giving leeway to allow for the challenge of challenging tasks meant that some tasks never got done.

Another issue was that there wasn't actually a concept of weekends, or holidays, or vacation time. This meant any time off (which I don't for a second think I can do without forever) would turn into a long list of red tasks I'd need to pick back up all at once. Bug or feature, it was sort of annoying.

Outlook: Good

Instead of just trying harder and expecting different results, this time the goal is to build in mechanisms to directly deal with the challenges that made me stop using it in the first place.

First and foremost, missed tasks need special treatment. For starters, if a task gets missed for a long period of time, it will disappear for a cycle and come back. A simple retry and backoff mechanism will let the really tough tasks that sometimes you need to take months off of (*cough* blogging *cough*) go away, and eventually they can feel fresh again and even like a good idea. Like today!

Secondly, respecting downtime. This, as all time related functions, will be a complete abysmal mess. Programming in arbitrary vacation days and setting up caveats for weekends will be a non-trivial, completely un-reusable project. However, it will probably be fun to write.

Finally, and just as importantly as the other two, I am going to put some work into the frontend of this site. I've already got a plan to write a version of this awesome blog on using django with websockets, but with modern versions of these libraries. The ideal stack here is django/channels with react as a frontend. Time to learn how to web dev like it's 2015!

One Foot In Front of the Other

The most important thing is to try to stick to the routine, and add one 3 day task- make an update to Upkeep. Plan is to open source the entire timsthebomb.com site on github to add to my impressive portfolio of ancient, broken chatbots and the forks of large, impressive frameworks I submitted documentation patches to.

Until next time!

How This Mess Works

- March 24, 2017, 11:03 p.m.

So I promised a brief explanation of how this is put together, as I thought it was worth building a website from scratch. Not quite FROM scratch, but, well, not too far either.

                        DIAGRAM 1.A

             |  raspberry pi                   |
             |                                 |
             |  ---------------+               |
             |  | rpi_apline   |               |---------- 
             |  +--------------+               |  boot   +|
             |  | nginx        +----------+    | from sd  |
             |  |              |          |    |  card   +|
             |  | uwsgi        | <-----+  |    |---------- 
             |  | django       |       |  |    |
             |  ---------------+       |  |    |
+----------+ |                         |  |    |
|------------+-------------------+     |  |    |
|----------|                     |     |  |    |
|----------|  +-+                |     |  |    |
|----------|  | |                |     |  |    |
|----------|  +-+  root volume   |     |  |    |
|----------|           on        |     |  |    |
|----------|  +-+  thumb drive   |     |  |    |
|----------|  | |                |     |  |    |
|----------|  +-+                |     |  |    |
|----------|                     |     |  |    |
|------------+-------------------+     |  |    |
+----------+ |                         |  |    |
                                       |  |
                 +------------------+  |  |
           +-----+                  +--+  |
           |     |    home router   |     |     +---
           |  +--+                  +-----+     |
           |  |  +------------------+           | t
           |  |                                 | h
           |  |  +-----------------+            | e
           |  |  | google cloud    |            |
           |  |  +-----------------+            | i
           |  |  |                 |            | n
           |  |  |    +-------+    |            | t
           | ++-----> |       +---------------> | e
           |     |    | nginx |    |            | r
           +----------+       | <---------------+ n
                 |    +-------+    |            | e
                 |                 |            | t
                 |                 |            |
                 +-----------------+            +---

The short answer is this website is hosted on my local hardware, on a raspberry pi, in an alpine docker container, running supervisord maintaining nginx and uwsgi, the latter of which is using the django framework to render pages and save data to a mounted volume on a thumb drive in a sqlite.db file.

The anatomy of the raspberry pi (3, of course. It's my webserver after all) is a boot partition on the sd card, which references a thumb drive as its root partition. This guide goes over it pretty clear detail and it's worked great.

To avoid ruffians bothering me at home, I set up a google cloud engine supertiny instance that's running the official nginx docker image with a simple proxy set up- forward :80 and :443 traffic to my super secret hidden base.

I wanted deployment to be as simple as possible, so I set up this as an ideal deployment workflow:

  • git clone the code repository
  • run ./build-prod.sh
    • build-prod.sh runs docker build . -t prod
    • build-prod.sh runs docker run . -t prod

I strayed a bit from that workflow, but eventually I crafted a CD script that regularly pulls from master, checks if the script needs to be reloaded (due to changes in the CD script itself), and if not it builds a new docker image and replaces the existing running container with one from the newly built code.

That's it! It took probably three weekends to string and glue everything together. Despite this, any pushes to master in github are automatically deployed within five minutes and if both the webserver melted into the ground and my proxy disappeared in an s3-colored cloud of smoke, it would take less than a couple hours to build everything back up.

Except for backups. Ok, adding that to the todo list.


- March 19, 2017, 10:07 p.m.

So the infrastructure is in place, but there are still plenty of things to add to make this feel like home. The following is a loosely prioritized list of follow-up items to work out:
  • Get letsencrypt running and disable port 80 access (sub follow-up: change password)
  • Side bar that gives a quick blurb about who I am ✓
  • GUI based picture uploads and content serving
  • a favicon :)
  • oauth to replace password logins and privilege groups to support arbitrary user logins (for posting comments)
  • Add support for comments and single blog post views
  • Footer ✓
  • "Projects" page.
  • Come up with a convenient way to highlight syntax.
  • Fix Success URL / Next's for login and task updates
  • Fix chrome autocomplete for the damn login page. How is that not working?
  • "Read" page for blog posts.
  • "Edited" snitch tag at the bottom of a post.
  • Set up NTP, and add to the provisioning playbooks.
At that point I should have enough to call this rough draft of a blog complete.
As a side note, it must have been done before, but I'd like to maintain the minimalist look of a css-less webpage, relying on the stock h, p, and ul/li styling, but adding complexity to the page in as subtle a way a possible. I think this will give it a timeless 'rough cut' look, without requiring too much creative thinking.

First Post!

- March 19, 2017, 8:32 p.m.

Got the damn thing up! Looks like it's serving traffic.
Just a quick couple of additions and I'll write up a bit about how this mess runs.
My name is Tim Winter, I work as a Release Manager in Engineering for DataRobot.

I'm a senior python developer at DataRobot, but I also manage teams, shepherd projects and get things done.

I am a novice Data Scientist and enjoy kicking up ML projects on weekends as I can fit them in around a startup schedule.

Husband. Above average coolness for a dad.

Strong Technology Suites:
  • Python, my first love
  • DevOps, CI/CD, Automation and Release Management
  • Several flavors of Linux, primarily Debian, Centos, and Ubuntu
  • Packaging, repo and dep management
  • Bash, Make, and other handy tools that are easy to shoot yourself in the foot with
  • Git, Github
Fun Facts about me:
  • At one point I had a 10% ascention rate on nethack.alt.org - and someday I will again!
  • I max out at about 120 wpm on Dvorak, ~100 on Qwerty
  • I'm a bit of a 3d printer enthusiast, even though it's 2/3 calibration and 1/3 actual printing
  • Markov chains are boss, markov chain bots are bossest
Links worth checking out:
  • DataRobot - Automated ML Tools for Data Scientists and anyone else who works with data
  • raspi-maker - My RPi3 provision tool written in pure python 2.7
  • console - A pythonic 'drop this to shell' implementation that handles dynamic inputs and correctly manages stdin and stdout pipes via asynchronous queues/li>
  • botman-v3 - A markov chain bot for slack, which trains on any overheard text by storing it as up-to-4-grams.