Chris Dodds

Tech Person, Writer, Misc.

More adventures in publishing

I’ve put in some work to get a few of my pieces published. The more I learn about the process and ecosystem, the more I respect the people who slog through it.

Stats so far:

  • 7 pieces: 1 novella, 3 short creative nonfiction essays, 3 short stories
  • 36 total submissions
  • 14 rejections
  • 2 of those were personalized, the rest were form.
  • 1 of the rejects made it to the second round

These numbers are low. From what I’ve put together from Duotrope, most pieces take between 8-15 submissions before they get any bites, and that depends both on the form (flash vs. short story, etc) and the tier (higher tier venues have lower acceptance rates). If you’re targeting top-tier magazines or presses, 30+ rejections is not uncommon.

Some places charge fees. Some don’t allow simultaneous submissions. Some are super picky about format. Some only accept submissions on the 6th Tuesday of the 13th month. Some - XRAY, cough cough - have submission windows that last for 30 minutes every month before their Submittable budget runs dry.

I’m integrating all this into my system though.

I’ve tried to suss out fit as best I can to focus where I put my energy. It’s helpful that my style, voice, and chosen forms narrow down the avenues I can target, but that cuts both ways.

Style fit has been my biggest struggle. My writing tends to be very compressed and immediate. It can be claustrophobic and has high sensory pressure, because my ‘tism makes me hyper-tuned to those things. (I’m getting better at emotional contrast and letting readers breathe, but it’s taking a while to find a rhythm that I like).

I tend to be too weird and intense for the more mainstream magazines and presses and too coherent for the wilder ones.

I’m slowly finding the right niche, but it will take some acceptances to validate that. It would probably help to find a writing community to bounce some of my assumptions off of, but I haven’t found one that seems to be a good fit.

There’s logic to this maze - I’m starting to feel the patterns underneath - it’s just taking time to map and some recalibration to live with a longer feedback loop.

Investigating Oklahoma's new medical cost transparency site

Oklahoma launched a new portal for medical cost data because the federal one sucks and enforcement has been minimal. Unfortunately, the Oklahoma one also sucks.

The main issue with the federal portal is that it’s a raw data dump and the information as served is almost completely un-usable because of formatting inconsistency and missing data.

Oklahoma’s is a slight improvement in that it’s filtered down to the state level, but it’s operating on similar flawed premises.

  1. The only real consumer shopping that happens in medicine is for elective procedures, and even that’s limited. Most people just go where-ever their insurance tells them they can go. This seems to be a misunderstanding (probably intentionally so) at the legislative level.

  2. Even if we all did shop for procedures that way, the portal designs are backwards.

What do I mean by backwards? In most price comparison flows, one would start with the item or service they wanted, then compare a list of vendors with listed prices. Think bankrate.com as an example.

On the OK portal, you start by selecting a hospital or facility, then filter to procedures. You could obviously build your own comparison spreadsheet by manually clicking through several different facilities, but the UX is so user-hostile I can’t imagine anyone bothering. And positioning it as a consumer aid feels disingenuous.

That led me to a short investigation of “what would it take to do this properly?”

A small POC

1. Get the data

I tried a few things here. First - could I get it from the OK portal since that’s already filtered to OK. No. Their terms of service don’t allow any kind of export, there didn’t seem to be an API to talk to, and given their UI, orchestrating some sort of scraping would be painful.

Can I get it from the federal portal? Yes, but it’s a vast ocean of garbage. There didn’t appear to be any way to pre-filter, so you basically have to slurp down everything and run it through a map reduce cluster or something similar to clean it up. I didn’t feel like setting up that infrastructure for this.

So I just went to the websites for Oklahoma’s two largest medical providers and downloaded the data directly. That’s where things started getting interesting and explained some of OK portal’s design choices.

One thing that stood out immediately - providers split out their data by facility. Why? Because it appears they’re just dumping it straight out of their practice management software, which has it split by facility - and because the regulation is around facility fees. Hold on to that term because it becomes important later. This tells me that the OK portal’s UI is probably driven by the underlying data schema, which no one has inverted.

2. Look at the data

The data for two similar-sized/capable hospitals was massively different. One CSV was ~300k. The other was 5GB.

Luckily, it was in the roughly the same format (I think both systems use Epic), so I didn’t have to mess with my analysis scripts much.

I picked colonoscopies as a procedure to filter on because there are relatively few variants of it versus some other procedures that have hundreds of related and overlapping CPT codes.

So what does CPT 45378 - diagnostic screening colonoscopy, cost if you pay cash at these two providers?

  • Provider 1 - $920
  • Provider 2 - $1,885

OK, that’s helpful, but what’s this? The provider with the smaller file and cheaper price actually has more useful data in it than the larger file. It included provider fee examples and ranges - these are the fees charged by the person actually performing the procedure. The prices above are just the facility fees - what the hospital charges to have the procedure there.

Now we have:

  • Provider 1 - $2,364-$8,961
  • Provider 2 - $1,885 + some unknown value

So getting full apples to apples is pretty much impossible with this data. You can proxy through the facility cost, but you’re not going to know the actual cost outside of that.

The data sets do contain insurance provider negotiated rates, which were also interesting. In this case, just looking at Provider 1:

  • BCBS pays $2,267
  • Cigna pays $7,695

“So what?” you say. “It doesn’t matter because my insurance will cover it.” Oh no, my friend. Say you have a decent plan with 20% coinsurance. That’s the different between $453 and $1,539 out of pocket cost.

What did I learn?

  1. Medical cost transparency data is probably the best example of malicious compliance I have come across. “We have to publish our pricing data? OK, here’s a tome of unsorted hieroglyphics.” This data is no where close to usable by the average consumer.

  2. “In-network” is just means “we talked and have (waves hand)… some agreement”. Negotiated rate is the core factor, and the best rates are going to go to who has the most clout, which is probably going to be the in-state insurers. BCBS is better positioned for this than Cigna/United, I think. This is another area where misaligned incentives cut us though. There’s nothing compelling an insurer to negotiate harder as long as they’re collecting premiums and their 15-20% grows in absolute terms.

  3. As-is, these transparency laws do very little. They are theatre.

What I still have questions about

  1. What could you do with this data? For elective procedures, I think you could put in a little work and provide some sort of heavily-caveated consumer-friendly data set, but I don’t know that it would actually move the needle broadly. Maybe I’m undervaluing electives and individual consumer power.

  2. Who could actually use this data? Probably self-insured employers. They hire brokers who should help steer them toward cost-efficent systems, but don’t because the incentives aren’t aligned. (Most brokers make % of premiums, not savings). But, if you could construct a decent, human consumable data set and put it in front of large employers and they start pushing their employees to lower cost providers, you could probably nudge the big cost needle pretty hard.

  3. What’s missing from this data? Obviously, provider fees are a big miss. Granted, that would add complexity. It fractures the CPT code maze even further when you add the entropy of different doctor fees. Some providers are figuring out how to do it though. I think one major missing piece is quality ratings. Doug’s House of Surgery and Hotdogs might be the lowest cost, but do I really want to go there?

  4. Is there potential to do some investigative journalism here? Probably, but “X hospital charges 2x more than Y hospital” seems like a story that would barely register on anyone’s radar. “Your insurance company sucks at negotiating because they get paid either way” might be more compelling. More to think on here.

I may pick some of this up again. I think there’s lots of interesting data to dig through here and things to learn. I’m not sure what I’ll do with the knowledge, but if nothing else maybe I can get through the arc of “this seems fixable” -> “omg, this is irretrievably broken” -> “actually, if we press here and here we might accomplish something.”

Fish Stick: Stateless Incident Management

I released Fish Stick, a stateless incident management bot for Slack. Written it up over at Fishstick Labs.

This is the sixth or seventh time I’ve built this bot at different jobs. Figured it was time to stop reinventing the wheel and ship something I could reuse (and that others could use too). I’ve actually had a multi-tenant version of this sitting in a folder for several years, but decided to rip all that stuff out and lean into simplicity and OSS.

Most incident management tools are either too basic (Slack workflows that can’t do enough) or way too complex (enterprise platforms with a thousand knobs you’ll never touch). Fish Stick sits in the sweet spot - does what you actually need without making you wade through (and pay for) features you don’t.

The interesting technical bit: it’s completely stateless. No database, no web UI, no OAuth dance. Slack is the database. Channel properties hold metadata, messages are the timeline, pinned messages are the summary. You can restart the bot whenever and lose nothing. Obviously there are some data durability and keeping-up-with-Slack-API tradeoffs there, but I think it works for this niche and use case. Design constraints for the win.

Check out the full writeup for details on features, architecture decisions, and setup. It’s MIT licensed on GitHub.

RageBlock

I built a Firefox extension that blocks mainstream news sites while keeping investigative journalism and wire services accessible. It’s called RageBlock.

I wanted it for myself.

I noticed that checking news sites made me feel worse without making me better informed. I’d feel anxious and angry, but I wouldn’t actually know anything more useful than I did before. The information-to-anxiety ratio was terrible. And I was often just opening them out of habit, like a nervous tic.

Cable news sites and major papers have optimized for clicks and engagement - and profit. That optimization twists facts toward grievance and keeps you in a constant state of low-grade anxiety. At least it does for me. Breaking news alerts. Live updates. The 24/7 outrage cycle.

Meanwhile, places like ProPublica and The Intercept do deep investigative reporting that matters. And wire services like AP and Reuters still do a pretty good job of reporting “just the facts”. There’s still plenty to be mad about, but less outright manipulation. They’re not trying to keep you glued to the screen refreshing every five minutes.

I still want to stay informed. I still want to read long-form investigative pieces that dig into how things work and why. I just want to skip the outrage porn.

I looked for existing tools. There are content blockers that get reasonably close, but they require you to build your own list or block things in big chunks. Apple’s parental and screen time controls are clunky. Nothing felt right.

So I made something closer to what I want: a curated list (still had to build it), some behavioral nudging, and some insight into my own patterns.

Blocked page view
Extension popup

RageBlock has an opinionated blocklist by default. It blocks 60+ sites: CNN, Fox News, MSNBC, NYT, WaPo, Reddit, Twitter, Facebook, Instagram, TikTok, and most news aggregators. Full domains, including all subdomains.

When you hit a blocked site, you see a message with alternatives. You can bypass for 5 minutes or until midnight if you need to check something specific. But the default is blocked.

The extension tracks your blocks and bypasses from the past week. If you’re bypassing too often, it shows reflection prompts. Gentle reminders to check in with yourself about why you’re doing this.

Building it

This was my first Firefox extension in a while. It’s mostly web dev as long as you’re not doing anything too crazy.

My initial attempt was to make it cross-browser, but I quickly discovered that the WebExtensions standard is a lie. Different APIs, different behaviors, different permissions models. So I punted and went Firefox-only since that’s my browser anyway.

Vibe coding worked reasonably well for this and I think this type of thing is actually a perfect fit for vibe coding. Most of it is boring scaffolding. I had to steer a few things: DRY this up, stop making this so complex, write tests that actually test the code instead of mocking the entire implementation.

The initial block list is basic. I’ll grow it over time as I figure out more things that make sense to block by default.

I debated adding local news sites. They’re generally terrible and subject to the same click-optimization as the major sites. Still deciding what I want to do there.

You might want this too

RageBlock is open source and available on GitHub. It’s MIT licensed. Do whatever you want with it.

It’s also on the Firefox AddOns store.

If you use Chrome, you’ll have to port it yourself. I’m not dealing with Manifest V3 right now.

And if you think the default blocklist is wrong, PRs are welcome, or fork it and make your own. That’s the point. Make the tools that work for you.

Showing Up & Goodbye WTFPod

I listened to the final episode of WTFPod on the way to Santa Fe last week (Airpods plugged in, daughter yelling along with Bluey from the seat behind me). It was the first time I’ve listened to a podcast in quite a while. The structure of my life (working from home, taking care of kids) doesn’t have as much room for them as it once did.

Marc Maron’s interview with Barack Obama ended up hitting close to home. Obama spoke about knowing your values and beliefs as being foundational for building connections and having meaningful conversations, which is something I’ve been thinking about a lot. The core of his point (and Maron chimed in as well) was that having that foundation lets you have difficult, meaningful conversations and there’s a vulnerability to earnestness that helps others listen.

They talked about in-person connection and what we’ve given up by adopting social media. How we see only narrow slices of people and not their contradictions or the unspoken goodness that might only show up in close proximity. I’ve been thinking about this a lot as well. Living in a suburban bubble, I’ve felt the weight of how few unmediated interactions I have anymore.

I know I need a community — and that I’d have something to give back, too. I’m not alone in this. I’ve read a dozen articles this year about how we’ve become an introverted society. Doing something about it is a whole other challenge.

It feels like a core leverage point. If we want things to get better, to live in a world that’s closer to our ideals, we’ve got to start talking to one another again - vulnerable, in-person, not hiding behind a screen. I haven’t gotten in an internet fight in a long time, but I haven’t engaged with the physical world much either. So I’ve got to change.

I found some meetups. Board games, nature walks, random stuff that is at least painless on the surface. So I’m forcing myself to show up. To talk, to listen, to try. If only so my kids see what trying looks like.

I wouldn’t say it was the best WTFPod episode ever, but it reminded me of Obama’s decency and why Maron has always appealed to me. The former made me sad. It was comforting in the moment, but wrapped up in loss as well. Decency is depressingly underrated.

Maron though… I think he’s wired into one of the ideals I’m striving for - to lead with vulnerability. It doesn’t have to be trauma dumping (although he’s done that from time to time), but he’s been a great example of seeing someone be open and enabling others to share that openness with him. I’ll miss his show for that. I wish more disaffected guys would have plugged into that energy instead of mainlining Joe Rogan.

Yeah, Rogan gave people a community, but it’s an aggrieved one that’s mostly defined by its contrarianism and devaluing of decency. There’s a weird vulnerability to the psychology of the manosphere that’s obvious from a distance. “Oh, this is for people who are hurting or empty in some way.” But the manosphere would never admit that.

A younger version of me would have rolled his eyes that I’m writing about decency and vulnerability being the building blocks for the world I want. Luckily, he grew up and knows how to admit he was wrong.