The Wheels Turn. A monome norns+arc four track inspired recorder.

Concept

The idea is to have four audio tracks that we play back and record against, one assigned to each wheel (knob control on the Arc).

One pattern I like a lot is a bin/service wrapper. In each of your services (I like to call them Macro Service instead of Microservice).

The idea is to provide a few key things:

  • Simple tools for developers to manage the service
  • Lifecycle hooks for deployment
  • All wrapped up in code, providing executable self-documentation

Taking inspiration from The Star Thrower; Action, even in the face of futility, is the path I take.

The Ocean


Editor Note: This piece is by Loren Eiseley, 1969. Published in The Unexpected Universe. Transcribed here from a PDF scan I found.

Printed Version Screenshot

Using the new ChatGPT GPT-4o Image Generation to incrementally generate a photo of Hoda! (A "Chipin" is a 50-50 Chuhuahua and Mini-Pincer. Hoda is 70-20, so is a ChuhuaPin!)


Previously if you asked ChatGPT to generate you an image it would switch over to DALL-E, a separate image generation model. Each time it generated a new image it would more or less start from the beginning, maybe, and it was a challenge to get small incremental changes to an image.

Since I'm going some consulting work I have to do a bit of time tracking. And you know what that means! Playing with my taskwarrior and timewarrior config!!!

stopwatch oil painting

openai: Generate an image of a stopwatch in the style of an impressionist oil painting with thick bold brush strokes

My friend Brad asked about what I've been reading lately in the AI/LLM space to keep up. Here's my link roundup! Things that have been on my rotation lately.

LLM Newspaper Dog Cartoon

  • AI Engineering: Building Applications with Foundation Models: Great January-2025 catch up on consuming LLM/AI usage in real world applications; enough background to Get It without being distracted by details
  • Simon Willison Website: Follow for great links and chasing the dragon of new releases and thoughts
  • LLM CLI (Datasette): From Simon Willison, a very handy CLI tool for interfacing with LLMs. Once set up, I use this as a unixy native tool. Like ... cat some_file.txt | llm -s 'Turn this into a CSV of street, city, state, zip' > data.csv
  • /r/LocalLLaMA: Reddit community all about running local LLMs; even if you only ever run things on other people's computer (API) it is interesting to know what might be happening on the other side
  • /r/ClaudeAI: Latest and Greatest with Claude Stuff
  • Groq: Hardware accelerated LLM (also see Cerebras)
  • Aider: Open source CLI coding assistant. They've been building up an Aider LLM Leaderboard which is interesting, especially the highlighted polyglot board (one model for architecture plan, another for low-level coding)
  • Sourcegraph Cody: There are several VSCode-embedded code assistants in this space, Cody is one to keep an eye on. Recently Copilot Edits has stepped up to a similar cross-file assistant too. There are a bunch of others; I'm not really psyched about switching from vim to vscode, and I certainly don't want to switch to a proprietary editor, so I haven't spent much time with things like Cursor (yet)
  • Matthew Berman (YouTube): He does videos with some demos and commentary that is pretty fun; I may not always agree, but even knowing what the latest topics are is very helpful!
  • Practical AI Podcast: I listen to podcasts when I commute or go for longer drives, which isn't often but often enough that I've listened to some good episodes both here and on other ChangeLogs.
  • Latent Space: The AI Engineer Podcast: I've only listened to a few of these, but it is on top of my feed list in AntennaPod currently

Figured out how to make opening a CSV in firefox pop open a terminal running VisiData (vd)

VisiData!

I like VisiData! If you are working with tabular data, like a CSV file, it is a lovely slicer and dicer. It's a pretty terminal-keyboard-heavy program, like a vim family thing. Like many of these power tools, I find that you can get into it best by finding ONE use-case and then gradually introducing new tricks from there. So the simple use-case for VisiData is simply viewing CSV files.

A small data transform / cleanup task using LLM labor.


My mom is now running a small business, $129 Arizona Discount Traffic Survival School, and I'm tinkering away at a website for her. The other day she gives me a google doc with venue addresses, asking if I can put it up on the site.

Drawing Xes in Boxes is harder than you might think! Teaching Ghostwriter a bit about space by pre-segmenting the input image gets us closer.

The Problem

You may recall from TLT - 2024.11.23 - A Ghostly Game that Ghostwriter is ... not good with spatial awareness. For example, we can ask it to draw an X in a box and see how close it gets...

Working on Ghostwriter, making some incremental progress on playing tic-tac-toe.

It Was Worse Before

I've been trying to play tic-tac-toe with Ghostwriter, but it is quite bad. Reading the LLM transcript, it sees that we are playing, has a good idea of what it wants to do, but can't aim its output very well at all.

Each token is one choice from many forking paths. Let's see some of the other possibilities. Also try the Live LLM Token Tree Visualization Tool!

The Next-Token Machine

Mostly we talk about LLMs (Large Language Models) as generating one token (roughly a syllable, it depends) at a time. But that's not really the whole picture. Given the context, all of the text that has led up to this point, the model will rank all of the possible tokens and assign each a weight (a probability).

Part of the Ruby For Good organization; inventory control for diaper and period-supply banks.

human essentials admin

See the Human Essentials Github repo for the main project itself. I am but one contributor, though I've been working on this project very steadily since 2022 (with some smaller contributions in 2018-2019).

This is the website and wiki of me, Brock Wilcox a.k.a. awwaiid. Please see the Home page if you would like a less philosophical introduction to this site. Otherwise, read on!


I love living in the future -- we have so many neat things. One of my favorites is the internet. For me the internet is a powerful communication tool, and this website is one of the ways I utilize the internet to communicate. By placing my thoughts, papers, and projects on this site for the world to view I hope to communicate a little about myself to whomever is interested in knowing me.

I use Unison File Synchronizer to keep my important files synchronized between machines. This is a description of how I have it arranged and automated. I have been using this setup since 2006!

unison sync screenshot

Directory Setup

In-Hub, LLM + Sonic Pi, dash of docker-compose

In-Hub, LLM Club, Mediapipe, Coffee Project, docker-compose

Website updates to break insulation, bit of Human Essentials

A week spent coughing, writing Java, and watching Andor. First World Problems hah. Not bad in the scheme of things! :)

Pairing, unicode tokens, graphviz bling

Unicode token tree with Chinese

  • General Status:
    • Starting to get into the hub-vibe a bit more, love it. Starting to actually remember individuals better! I'm so bad with names, but will keep asking over and over until I get it :)
    • I got to show the token-tree thing to a few individuals and then presented at the big session, very fun
    • Still having wayland/sway + zoom issues :( . Weird color inversion, floating-vs-non-floating-windows, etc. But I'm sticking with it. Hard to switch after like 15 years of xmonad (and like 25 years of X11 heh), but it's at like 99.9% so can't stop now
    • Shout out again to O who helped me sort out some caching issues that was slowing down CPU token generation. Making it fast-enough has been really helpful
    • Will be Virtual RC tomorrow (Friday), gotta do some errands and prep for a friend-visit over the weekend
  • Alloy+LLM+Rails Project:
    • Working on wrapping up token-visualization
    • Paired with Q, sorted out some escaping and unicode things
    • Added a bit of bling shadows and scaling (styling SVG with CSS is fun!)
    • Got incremental streaming of updates, background threading of the processing, and interruptability
    • Going to now switch over to Alloy; do some tutorials and toy models, build a few by-hand models of real world apps (Human Essentials Rails)
    • Somewhat of a pure-research project, so I'll go with where it takes me. But I am feeling the time-pressure a bit, and am hungry for artifacts to show off in the end. We'll see what comes next :)

Llamas, Pythons, Coffee, and Sway

Part I - Morning

  • Morning Status:
    • I feel pretty great today, but going to be Virtual anyway. Got some errands to run
    • I've got llama-cpp-python up and running, so I'm going to work on a back-end for it
    • I'll likely solicit pairing once I get it a bit further, especially for some visuals

Fuzzy brained, but starting to figure this thing out.

First day of RC!

I'm attending a 6-week retreat at Recurse Center! This will go from March 25 - May 3. So ... gotta get set up!

A robot making lists

The Basics

I'm trying to solidify my understanding of the schema organization for Human Essentials. The goal is to build up some documentation to make contribution even easier for new folks. Also I like to play with PlantUML and GraphViz.

Schema Exploration

First I ran rails erd filetype=dot attributes=false and got a beast of a diagram. This includes all of the models and some indirect relationships.

Jam with Theo -- banging drums, strumming bass, and making up nonsense about Wanda Vision!

(download)

Theo and I went over to 7DrumCity and jammed for a while. He and Sacha were telling me about Wanda Vision, which I haven't seen at all, so I started to make up a song. A delightful time was had by all!

Song inspired by Hoda The Dog lounging about in the living room sun!

Voice note (download)
Revision 1 (download)
Revision 2 (download)
Revision 3 (download)

G
My little dog
C
laying in my living room
G
she's laying in
D
a patch of sun

G
My little dog
C
laying in my living room
G
And I think her day
D                  G
is gonna be a good one

G
My little dog
C
laying in my living room
G
she's laying in
D
a patch of sun

G
My little dog
C
laying in my living room
G
And I think her day
D                  G
is gonna be a good one

C
She's laying there
G
all through the day
C
Just seeing her
G
takes my cares away
C
What she's dreaming of
G
I couldn't say
D
But I bet it's something
G
real fun

G
My little dog
C
laying in my living room
G
she's laying in
D
a patch of sun

G
My little dog
C
laying in my living room
G
And I think her day
D                  G
is gonna be a good one

START HERE! This page is an overview; much of the music I've written or been involved with in one lovely place. Also check out my Music Gear and Setup!

These works are licensed under a Creative Commons Attribution-ShareAlike (CC BY-SA) License (or maybe CC BY-NC... feel free to ask).

Here are a bunch of songs! Some of these are more proof-of-concept than anything :) . These include both solo efforts and collaborations, follow the links to learn more and maybe get some lyrics, variations, and background.

Initial attempt at My Little Dog, part of the 2023 RPM Challenge

I did a voice recording of this in April 2022, noodling around on the mandolin and singing to Hoda while she (quite obviously from the lyrics) lay basking in the sun. Here is the voice recording:

(download)

I'm going to try to do the RPM Challenge again this year. Millionth try is a charm?

Previous Attempts

The challenge: 10 tracks or 35 minutes of original music recorded during the month of February.

I had ChatGPT write me a poem .... but first some somewhat irrelevant background information!

Snake Lights

I've purchased and chained a few Neopixel-like LED fairy-light strands (these ones on Amazon) as a fun winter/Christmasy project. I have them hooked up to an Arduino-like, right now this M4 Feather Express, but I'm planning on switching to an ESP32-S2 TFT Feather. Each LED is individually controllable using Arduino/C++. The idea is to make some holiday light displays with different colors and twinkling and all that. While learning how to use it I made a few toy animations, such as this simple snake:

Monome Norns is a music-sentric device built on top of the Raspberri Pi by https://monome.org/. There is a healthy community at https://llllllll.co/ ("Lines"), though they talk about a lot more than only Monome. Norns is scripted primarily with Lua and SuperCollider, though is a fully Linux system.

Pair a keyboard with the Norns and Grid. Then you record commands like a set of timed and sequenced macros visible and triggered on the grid. Like a guitar-looper mashed up with a REPL mashed up with a sequencer!

REPL-Looper Demo

See https://github.com/awwaiid/repl-looper for the code, documentation, and a journal of development.

In today's sugary exploration, let's take a look at a shorthand for object key expansion in Javascript (ECMAScript 2015+, es6+). For an overview of the TON of delicious sugar that was added to Javascript at around es6, check out es6-features.org.

Most of the "scripting" languages (Python, Ruby) have "dictionaries" or "hashes", a datastructure of key-value pairs. In JS these are called "objects", and they do a lot of other things beyond this basic data-storage behavior. In JSON -- JavaScript Object Notation -- you can see the basic literal declaration syntax. Let's build an addressbook, keyed (indexed) by name.

let addressBook = {
  "alice": {
    "street": "123 Elsewhere Lane",
    "zip": "32341"
  },
  "bob": {
    "street": "221 Baker Street",
    "zip": "00234"
  },
  "clarence": {
    "street": "P.O. Box 17",
    "zip": "88877"
  }
};

console.log("Bob's info", addressBook["bob"]);

A brain-dump of various approaches to debugging (code) things that I like.

We're using Firebase as the hosting service for https://covidcanidoit.com and the experience has been kinda weird, coming from a more traditional server-database world.

First, I didn't even realize that Firebase was more than a cloud-JSON-blob! Our initial use of it was only for static asset hosting. This is a VueJS application that so far mostly lives in the browser, so static hosting is perfect. I generally use Github Pages for this purpose, but another team member had already set up Firebase for us.

Once I learned that it was even a thing, all was good. I wrapped the CLI that Firebase provides into yarn land, and now you can do yarn deploy and it'll build up the local assets and push them up. Works quite well! The auth is stored somewhere else on my computer. If a new dev wants to deploy, you add their google account to the Firebase project and presto!

I got a Pocket Operator PO-33 a while back, and find it super fun -- it is minimalist and usable. It inspires me to play around with beats and tunes ... and it also inspires me to work on my own samplers, sequencers, and synths.

Let's see what we can do with Web Audio these days! Starting with a basic VueJS app, I googled lots of stuff. Somewhat randomly, I wanted a Wicki-Hayden hexagon style keyboard, so had to find some CSS that makes hex-buttons. I'll probably switch to this Hexi-Flexi-Grid at some point, to make dynamically sized hexagons easier, but these work.

Combine that with a simple synth, and now we have a playable thing. I had to make some tweaks to get it to work tolerably on my phone -- fix the layout size, use touch events. Unfortunately it isn't very usable at this point due to a sizeable delay between pushing a button and the sound. I'm going to write a pure-JS snippet to eliminate any overhead from VueJS, and if that is also slow then I'm not sure what I'll do. It's kinda cool that I can use Web Audio ... and I'd sure like to keep using it. We'll see!

The graph module uses GraphViz to draw graphs. Here are some examples I've put together, but much fancier thinges are possible. See http://www.research.att.com/sw/tools/graphviz/refs.html for GraphViz documentation, and see http://www.research.att.com/sw/tools/graphviz/examples/ for some examples.

<graph abc>
  digraph {
    a -> b - > c;
  }
</graph>
<graph>
digraph {
  rankdir=LR;
  node [ shape=plaintext fontsize=10 ];
  struct1 [
    label=<<TABLE border="0" cellborder="1" cellspacing="0" cellpadding="0" width="75">
      <TR><TD bgcolor="lightgrey">foo</TD></TR>
      <TR><TD>columnx</TD></TR>
      <TR><TD>id</TD></TR>
      <TR><TD port="barid1">bar_id</TD></TR>
      <TR><TD>baz</TD></TR>
      </TABLE>
    >
  ];
  struct0 [
    label=<<TABLE border="0" cellborder="1" cellspacing="0">
      <TR><TD bgcolor="lightgrey">bar</TD></TR>
      <TR><TD port="barid0">id</TD></TR>
      <TR><TD>name</TD></TR>
      <TR><TD>date</TD></TR>
      </TABLE>
    >
  ];
  struct1:barid1 -> struct0:barid0;
}
</graph>

<graph>
  digraph {
    n1 -> n2;
    n2 -> n3;
    n3 -> n1;
  }
</graph>
<graph>
  digraph {
    node [shape=box];
    rankdir=LR;
    n1 -> n2;
    n2 -> n3;
    n3 -> n1;
  }
</graph>

<graph>
digraph G {

    subgraph cluster_0 {
        style=filled;
        color=lightgrey;
        node [style=filled,color=white];
        a0 -> a1 -> a2 -> a3;
        label = "process #1";
    }

    subgraph cluster_1 {
        node [style=filled];
        b0 -> b1 -> b2 -> b3;
        label = "process #2";
        color=blue
    }
    start -> a0;
    start -> b0;
    a1 -> b3;
    b2 -> a3;
    a3 -> a0;
    a3 -> end;
    b3 -> end;

    start [shape=Mdiamond];
    end [shape=Msquare];
}
</graph>

(Cats Dominate Our Lives Too Much)

(download)

Wake up
Feed me
Don't wait
I need
You've got your own world
But you brought me here
Suck it up you worthless whore
I feel like you
Don't care
Be kind
Shut up
Leave me
I know that you think
I am here to entertain
My attention is not free
Sometimes you can be
So vain
Tease me
Be touched
Give me
Wake up
Feed me
Don't wait
I need
You

I've been doing a spot of accounting at work over the last few months. This is clearly a failure of delegation and management on my part, but it has led to at least one deep observation that I mightn't have had otherwise.

Accountants are secretly time travelers.

Perhaps that is a slight exaggeration. They don't ACTUALLY travel through time. But if you hang out with them a bit and observe their twisted time and verb conjugation ... well it's obvious that they would be right at home hopping around a branching multiverse.

  • Is Google Making Us Stupid?
    • I have a big stack of books that I've made ... fairly little progress on
    • Maybe the internet is eating my brain!
    • So now I will post links and bullets
  • Base-4 fractions in Telugu
    • Interesting explanation of the traditional Telugu fraction numbering. Also draws comparison to the traditional English measures
  • Git remote branches and Git's missing terminology
    • Presents a better understanding of git remote branches, highlighting that to really comprehend what's going on you must acknowledge the implicit local branch that is your cache of the upstream (such as origin/master)
    • I'm a little worried that I'm going to end up linking half of MJD's blog posts. Oh well, they are great. Example, /dev/null Follies has a hilarious nerdy punchline.

1 Comment.

This is perfect timing for me !

I did something close with mine using apache a few months ago but I am not satisfied with it.
I run it onto my SAN Synology box.

Un-Mixed: (download)

Artist: Sacha (writing, music, lyrics), Brock (mixing)
Copy and Share: under the terms of Creative
Commons Attribution-NonCommercial
license!

I know a dog
And he's my friend
His name is Oliver
Oliver Boliver

I Dockerized this website yesterday! I had already built a cpanfile that declares the Perl5 dependencies of OddMuse, which made it easy. I'm also going to run this with the data directory directly bind-mounted.

First the Dockerfile:

FROM perl:latest

# Set up the deploy user
ARG uid=1000
ARG gid=1000
RUN echo groupadd -g $gid deploy
RUN groupadd -g $gid deploy
RUN useradd --create-home -u $uid -g $gid -ms /bin/bash deploy

WORKDIR /app

COPY cpanfile .
RUN cpanm -qn --installdeps .

USER deploy

9 Comments.

Some uses I know of which do not appear to be in your list:

say :: # Pseudopackage representing null namespace?

Listen: (download)

Artist: Brock Wilcox, Sacha
Copy and Share: under the terms of Creative Commons Attribution-NonCommercial license!

Chords:

I've been having lots of fun with https://github.com/vimwiki/vimwiki lately! I've mixed in a bit of encryptfs to have a private directory of notes. Sometime during boot, I set it up with:

sudo mount -t ecryptfs \
  -o key=passphrase,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=no,ecryptfs_enable_filename_crypto=yes,ecryptfs_fnek_sig=1a9380706fdf5bce \
  ~/docs/private/vimwiki ~/notes

I haven't done much customization yet. But one thing I'm playing with now is making it easy to post notes from VimWiki directly onto my website.

Listen: (download)

Artist: Brock Wilcox
Copy and Share: under the terms of Creative Commons Attribution-NonCommercial license!

Lyrics

Last night at the DC Perl Mongers meetup we collaboratively built a proof-of-concept for storing key/value pairs as messages in a slack channel, https://github.com/plicease/globalhash. This was made straightforward by great Slack API docs and cpan:WebService::Slack::WebApi. Example usage:

# writes "hello=world" into the #globalhash channel
$ globalhash set hello world

# reads the #globalhash channel for the most
# recent value of hello and prints it
$ globalhash get hello
world

There are of course a TON of things you could do from here. Some ideas:

  • Meet people where they're at
  • Tailor the guidance style based on the situation
  • Do things on purpose
    • Be hands off because you want to, not because you are too busy
    • Be hands on because you want to, not because you haven't stepped back to see how to empower
  • Top down strategy (problems), Bottom up tactics (solutions)
  • With great responsibility comes great power
  • The price of many things is time, the most precious commodity. It takes time to manage - if you are not spending time you are likely not managing
  • People mostly want to be happy and do the right thing. If they aren't, try to figure out why.
    • Often people aren't doing what you want because of other factors - they don't understand (and thus buy in) to the bigger picture. Assuming a base level of cooperation is a better starting point
  • Feedback works well when you can illustrate the results of actions (impact feedback). The causality chain is an important part to everyone.
  • Get people to "consent" - full agreement is great, but there is a space between full agreement and veto that can be used for compromise and experimentation
  • Build and use tight feedback loops!
    • In building code things
      • Edit code, see live results
      • Push code, get expensive test results
      • Submit PR, get other dev feedback
      • Deploy to staging, get qa and stakeholder feedback
      • Deploy to production, get real world data and usage experience from users
    • Same patterns apply for manager feedback loops
    • Instant feedback let's us dynamically adjust, like riding a snowboard
    • If feedback is fast enough then things become an extension of our body
    • Slower feedback limits us to slow adjustment
    • Reaction time to feedback is proportional to the event to feedback delay
    • Force feedback loops to exist; have 1-1 or solicit impactful feedback
    • Everyone needs feedback, even bosses
  • Humans are humans - messy flawed amazing machines made of meat. They can be programmed directly to a degree, but are mostly self-programming. Look for ways of enhancing the self program system - feedback of the results of actions is a great way to do this, as their self-programming system is entirely based on feedback mechanisms
  • Look for ways to leverage strengths
  • Help people imagine a better world and figure out how to move in that direction
  • "The only difference between science and screwing around is writing it down". Write down your plan and results.
  • Decrease the barrier to doing things right. Make it so it is easier, more convenient, more joyous to do things right than to do them wrong
  • Failure is required for learning
  • Don't test people, instead talk to them and teach them, ensure they succeed

A fun thing to do is to explore things using introspection/reflection. In Ruby and Perl6, for example, we can get a list of methods for a given object instance pretty easily:

# Ruby
"hello good people!".methods.each { |method| puts method.to_s }

# Perl6
for "hello good people!".^methods -> $method { say $method }

On the REPL (irb/pry or perl6) this is even shorter since it prints out lists of things by default, so you can do:

One of the codebases I work on regularly has a large and slow test suite. So slow that it typically only runs in totality in a continuous-integration (ci) environment, and there it uses the parallel_tests gem to slice it into pieces and run in parallel. This gets it to run in like 30 minutes instead of 2.5 hours.

But I want to run the whole thing linearly sometimes, especially so I can make sure tests aren't conflicting with each other. So I created a new ci job that runs it linearly ... and got a fail that I didn't get otherwise. Took forever to figure it out!

This was about a worker that I call a "sweeper" -- it's job is to run once a day and make sure nothing was missed by other realtime jobs during the day. Here is a simplified version.