WUTSWonder · Unpack · Tinker · Share

There’s probably a story here.

A curiosity framework for people who work on software. Something made you go “Huh?” Here’s a way to follow that signal before deciding what, if anything, needs to change.

Illustration of Robby Russell, chin on hand, thinking “How curious...”
Me, noticing something. Not yet deciding anything about it.

The short way

WUTS in 47 seconds.

Something surprised you. Here’s the whole thing.

  1. Wonder

    Notice before you judge.

    Instead of: deciding you’ve already found a problem.

  2. Unpack

    Understand before you prescribe.

    Instead of: falling in love with your diagnosis.

  3. Tinker

    Learn before you commit.

    Instead of: building the solution.

  4. Share

    Make the next encounter easier.

    Instead of: merely telling people about it.

The test at the end: will this make the next encounter easier? That next person might be you.

While you’re here

I should admit that I’m not naturally good at this. Twenty-four years in and I still catch myself reaching for the fix, mostly because fixing is the part other people can see. Sitting with “I don’t understand this yet” has always felt like something I’d get caught doing.

So some of this is a permission slip I wrote for myself. You’re allowed to spend time understanding something. You’re also allowed to learn by trying it. The useful question is what you’re trying to find out.

The rest of this page is those same four ideas with the examples and the arguments attached. Take your time with it. That’s sort of the whole point.

Illustration: a shrug and a raised eyebrow, thinking “I wonder...”
Still my least comfortable setting.

Where it starts

Something doesn’t add up.

A test takes forty-five seconds. A customer uses the product in a way you didn’t expect. The abstraction you built yesterday already feels awkward. An agent keeps making the same mistake.

Illustration: a startled double-take, shouting “WTF?!”
The signal, on a Tuesday.

It could be code you wrote yesterday, a familiar tool behaving strangely, or a system your team inherited. What matters is that you noticed. That “Huh?” is a signal worth following.

Sometimes we shrug and get back to the ticket. Sometimes we start changing things before asking what surprised us.

Same curiosity

A little more deliberate than FAFO.

Fuck around and find out is probably software development’s default curiosity framework. Change it. Run it. Poke it. See what happens. There’s real value in that. We learn by messing with things.

WUTS keeps that instinct. Wonder about what caught your attention. Unpack enough context to understand what you’re looking at. Tinker with something small enough to learn from. Share what you find.

Same curiosity. A little more discipline. More receipts.

Illustration: two open toolboxes. The red one is labelled “FAFO” and holds a hammer, crowbar, scissors, dynamite and notes reading “Just ship it”, “Should be fine...” and “Thoughts & prayers”. The blue one is labelled “WUTS” and holds a magnifying glass, a notepad reading “Wonder Unpack Tinker Share”, a label maker, and tapes marked “Observe”, “Document” and “Leave a note”
Both boxes get opened. Only one of them leaves receipts.

One recurring condition

You’re missing some context.

Sometimes you weren’t there. Sometimes you were there and forgot. Sometimes everyone remembers the decision differently. Sometimes there was never a deliberate decision at all.

Unpack fills in the gaps: sometimes in a conversation, sometimes in a log from five minutes ago.

Illustration: a puzzled look, thinking “Why is this here?”
A reasonable question. Even when I wrote it.
  1. You wrote it.

    Six months ago, this made sense. Apparently.

  2. The team remembers it differently.

    Same meeting. Three versions of what was decided.

  3. The constraint changed.

    The workaround stayed. The reason for it may not have.

  4. The system grew around it.

    The decision made sense locally. New callers brought new expectations.

  5. Nobody quite decided.

    One small convenience became the way everybody does it.

  6. You inherited it.

    The code arrived without the people, conversations, or notes that explained it.

Illustration: a rusted light switch buried under strips of masking tape, hand-lettered “TEMP”, “Do not remove”, “Still needed?”, “???” and “Check: J.D. 4/12/21”
Still worth asking before flipping it.

The posture

A “Huh?” is not a verdict.

Noticing something weird doesn’t oblige you to fix it. It might be broken, inefficient, intentional, experimental, misunderstood, or perfectly fine.

A new abstraction might be solving a real problem. An old workaround might still protect a constraint. The strange behavior in your own code might be a tradeoff you’d make again today.

Or the constraint disappeared years ago. Or the new abstraction is getting in the way. Age and unfamiliarity are observations. Figuring out what they mean takes a little more curiosity.

The framework

Four disciplines. Not four steps.

Each one names a discipline, and the temptation that usually wins instead.

The first discipline

Wonder

Notice before you judge.

The temptation: deciding you’ve already found a problem.

Illustration: one finger raised, thinking “Hang on.”
Stopped. Not yet deciding.

Something made you stop. Get specific about what caught your attention.

  • What did I expect? What happened instead?
  • Have I seen this before? Who else runs into it?
  • Am I seeing friction, or just something unfamiliar?
  • What happens if we leave it alone?

A surprising result is enough to get curious. Start with something you actually noticed; don’t go hunting for things to fix.

Move on when there’s enough signal to justify getting curious about why.

Eight places the “huh?” shows up

  1. Testing

    This test fails. Sometimes.

    The same test passes on the next run. Re-running it is becoming muscle memory.

    What changes between those runs? Start by noticing the pattern you’ve learned to ignore.

  2. Deployment

    Twenty-two minutes to deploy.

    Most of that time passes quietly. Everyone calls it normal. You’re curious where the minutes go.

    Waiting and working can look remarkably similar from the terminal.

  3. Your own code

    I wrote this. Why does it do that?

    Six months ago, you added this branch. Today its behavior surprises you.

    Your name in the history doesn’t mean today’s version of you remembers the reasoning.

  4. A new abstraction

    We built this last week.

    Explaining the new interface already requires a diagram and two exceptions.

    Is there complexity the abstraction needs to represent, or did we add some? Worth wondering.

  5. Product behavior

    This customer takes the long way around.

    They export a report, change one column, and import it again. Everyone else uses the form.

    What are they trying to accomplish? Their detour might tell you something.

  6. Developer experience

    Why do I keep looking this up?

    A command you run every Thursday still sends you back to the README. Everyone has their own wrapper.

    Is the command awkward, the guidance hard to find, or the task different each time?

  7. An inherited service

    Why is this dependency still here?

    The service relies on a library you rarely see anymore. You don’t yet know what it does.

    Is it causing a problem, or is it simply unfamiliar to you?

  8. AI agents

    Why did the agent choose that example?

    The agent keeps choosing a pattern the team no longer prefers. What makes it look like the right answer?

    The environment may be offering a perfectly reasonable wrong answer.

The second discipline

Unpack

Understand before you prescribe.

The temptation: falling in love with your diagnosis.

Illustration: leaning in and pointing, thinking “Follow the history.”
Read the code. Check the logs. Ask someone.

Build enough context to understand what you’re looking at. Read the code. Reproduce the behavior. Trace callers. Measure it. Check the documentation. Talk to someone who sees a different part of the picture.

  • What am I actually seeing? Can I reproduce it?
  • What changed recently? What do the measurements show?
  • What am I assuming about how this works?
  • Who or what depends on it?
  • What do the code, documentation, history, or other people tell me?

Sometimes history explains what you’re seeing. Sometimes the answer is in today’s logs, a framework convention, or a customer’s workflow. If you catch yourself gathering evidence for your favorite fix, ask what you’ve left out.

Move on when you understand the situation well enough to name what you still need to learn.

Eight ways to build context

  1. Testing

    Reproduce the slow run.

    Run the forty-five-second test on its own and with its neighbors. Compare timings, setup, and external calls.

    First find out what the time is buying. The assertion may be the quickest part.

  2. Your own code

    Read past the line you wrote.

    Trace the callers. Compare the assumptions you made six months ago with the values arriving today.

    The code may be unchanged while everything calling it has moved on.

  3. Product behavior

    Watch what the customer actually does.

    Reproduce the detour. Ask the customer or support what happens before and after it.

    The product shows you the clicks. The conversation may explain the job.

  4. An unfamiliar framework

    Check what the framework promises.

    The new hook fires at an unexpected time. Read the documentation and compare a minimal example.

    Your expectation may come from the last framework you used.

  5. Operations

    What changed since the last good deploy?

    Compare logs, configuration, flags, and traffic. Ask what changed recently, including outside the code.

    The useful history may be five minutes long.

  6. An inherited dependency

    Find what still depends on it.

    Check callers, exports, integrations, and the incident notes that explain why this library was chosen.

    An external system may read that output every Tuesday. Nobody here has ever met it.

  7. Architecture

    Put the implementations side by side.

    Compare the three approaches: inputs, constraints, failure behavior, and what each makes easy.

    Where do the requirements differ? Where did convention simply drift?

  8. AI agents

    Read what the agent can read.

    Inspect repository instructions, examples, generated code, and documentation. Look for conflicting guidance.

    The team’s preferred approach may exist mostly in conversations the agent never saw.

The third discipline

Tinker

Learn before you commit.

The temptation: building the solution.

Illustration: a tiny screwdriver in a small box of wires, tongue out in concentration, thinking “Let’s see...”
One small experiment. Note the size of the screwdriver.

Think of it as structured FAFO. What’s the smallest thing you could try that would teach you something? Add a trace. Remove one variable. Compare two approaches. Sometimes the whole result is information.

  • What are we trying to learn?
  • What’s the smallest experiment that could teach us that?
  • What do I expect? What result would change my mind?
  • Could observation alone answer the question?
  • Am I accidentally turning the experiment into a project?

Once you’ve spent two weeks building your experiment, there’s a surprisingly good chance you’ll discover your experiment was brilliant. Experiments create prior art; today’s proof of concept becomes tomorrow’s example somebody copies.

Move on when you’ve learned enough to make a better decision than you could have before.

Eight experiments smaller than a project

  1. Dependencies

    Build the small branch first.

    Try the likely replacement in a branch. What gets easier? What gets harder? Which assumptions surface?

    Discovering six weeks of work for almost no improvement is a good outcome for a two-day branch.

  2. Deployment

    Time one path through the deploy.

    Add timing around the slow steps. Try one change in staging and compare the result.

    Keep the question small enough that the measurement can answer it.

  3. Testing

    Remove one variable.

    Run the failure repeatedly with a fixed seed or a single worker. Change one condition at a time.

    If the failure disappears, you’ve learned where to look next. You haven’t necessarily found the fix.

  4. Developer experience

    Wrap the awkward command.

    Write one command for the task people keep looking up. Watch who uses it and what still needs explaining.

    A tiny script can show you which parts of the workflow are actually shared.

  5. A new abstraction

    Try it on the next implementation.

    Use the new approach once. Compare it with the direct version: code, explanation, review, and awkward edges.

    Then decide whether it deserves eleven more copies.

  6. Product behavior

    Try one path behind a flag.

    Try the alternative on a small, opt-in path. Watch where people pause and what they do next.

    If the detour remains, the screen may not be what made the task awkward.

  7. Infrastructure

    Automate one step.

    Automate the first step of the manual process and live with it for a week.

    Some steps encode unwritten judgment. You tend to discover which ones by removing the wrong one.

  8. AI agents

    Change one source of context.

    Change one instruction or example. Give the agent the same task again.

    Did its behavior change? Now you’ve learned something about what’s teaching it.

The fourth discipline

Share

Make the next encounter easier.

The temptation: merely telling people about it.

Illustration: holding out a sticky note that reads “Context today. Fewer mysteries tomorrow.”, thinking “The next person should know.”
Context today. Fewer mysteries tomorrow.

You learned something. Now put it where the work happens. Did we improve the signals the system gives to whoever works here next?

  • What did I learn that could become part of the environment?
  • How can the next encounter start from here?
  • Could a test, tool, or example carry this understanding?
  • What misleading guidance can we remove?
  • Is this context somewhere a person or agent can discover it?

Sometimes a note is enough. Sometimes the better answer is executable: a test, a wrapper, a generator, a lint rule, or a skill. Sometimes you remove the example that kept teaching the wrong thing. Leave the learning where the work happens.

Move on when what you learned makes the next encounter easier.

Eight ways to pass the learning on

  1. Application code

    Preserve the weird thing on purpose.

    The unusual branch is intentional. Leave a comment or decision note explaining the constraint you just understood.

    Your future self is a perfectly good audience.

  2. Architecture

    Make the preferred path easier to find.

    Document the approach. Update the generator. Fix the example people copy. Retire the misleading ones.

    Make the right path the one that’s easiest to stumble into.

  3. Developer experience

    Put the learning in a command.

    Refreshing customer data takes six commands and tribal knowledge. Put that learning into bin/refresh_customer_data.

    A teammate can do the task without borrowing your memory.

  4. Testing

    Leave a test that explains the surprise.

    Two valid operations arrive in an unexpected order. Add a test that makes their interaction visible.

    Next time, the test can explain what your memory probably won’t.

  5. Repository hygiene

    Remove what kept misleading you.

    Retire the stale example or obsolete workaround. Update the README to match what you learned.

    An obsolete example is still teaching. Patiently. To people and agents who arrive after you.

  6. Observability

    Build the view you wished you’d had.

    You correlated four logs, two systems, and a spreadsheet. Leave a dashboard or one useful trace behind.

    The next investigation can start where this one ended.

  7. Product knowledge

    Show the team what you learned.

    Walk through the customer’s actual workflow with product and support. Explain what surprised you and what it changed.

    Leave a short recording or example. The next person may miss the meeting.

  8. AI agents

    Improve what’s teaching.

    Turn the repeated correction into a repository instruction, an agent skill, a generator fix, or a lint rule.

    The next task should start with what this one taught you.

The disciplines overlap. They send you backward. Unpacking often produces a better “Huh?” than the one you started with; a tinker sometimes reveals you never understood the constraint at all. That’s fine.

How it ends

More than one useful ending.

The point is to understand what you noticed and make a better judgment. Sometimes the whole outcome is simply: now we know why.

Illustration: adjusting my glasses while reading a TODO comment, thinking “Ohhh. That’s why.”
The clue was in my own comment. Naturally.
  1. Kept

    You understand it now, and it still earns its place. Leave it alone.

  2. Changed

    You learned enough to improve it. Simplify it, fix it, remove it, standardize it, or tool around it.

  3. Explained

    The thing itself is fine. The missing piece was context. Leave that somewhere the next person will find it.

  4. Observing

    You need more evidence. Improve the signal, add instrumentation if it helps, and record what would make this worth another look.

  5. Still unclear

    You investigated and still don’t know. Record what you learned and the open questions. Not every investigation ends with certainty.

  6. Tool it

    The complexity is legitimate. A wrapper, script, or dashboard makes it easier for people to navigate correctly.

  7. Standardize it

    Several approaches accumulated. You’ve learned enough to make one path easier to find and follow.

The workshop

We’ve learned where to step around.

The command needs an extra flag. That test sometimes needs another run. Three implementations exist, but everyone knows which one to copy. Except someone joining the project tomorrow won’t.

Those coping mechanisms can make friction invisible. There’s always another feature, bug, or deadline, so we step around the rough edge again.

Agents encounter the same workshop without all those shortcuts. They may follow the outdated README literally, copy the leftover experiment, or miss a constraint that lives in someone’s memory.

Sometimes the agent is wrong. Sometimes the environment is giving it a perfectly reasonable wrong answer. That distinction is worth getting curious about.

As agents give us more capacity to build and change software, we can use some of it to improve the workshop itself. A clearer example, a wrapper command, a test, a better signal... something that makes the next encounter easier for everyone working here.

Illustration: peering over the edge of a deep hole, thinking “Just a little deeper into the abyss.”
Me, not resisting the temptation. Note the absence of discipline.

On discipline

Curiosity on its own is an appetite, not a virtue.

Curiosity without discipline becomes a rabbit hole, and I’m very capable of falling down those myself. The four disciplines are mostly there to keep “I wonder...” from turning into “I rewrote it over the weekend,” and to keep “I fixed it” from turning into the thing the next person has to wonder about.

Where the “Huh?” comes from

Long exposure to a system trains you to stop seeing it. A few ways to get enough distance to notice again, without going hunting. Watch someone work on a normal task and don’t correct them. Write the letter to your replacement (“this is mostly a normal app, except...”) and compare it with what your teammates wrote. Imagine onboarding someone next week and walk their first day.

One useful case

Chesterton’s fence, and what to do after you find one.

You probably know the parable: don’t tear down a fence until you know why it was put up. Good advice when the thing you’ve noticed protects a constraint. It even applies when you put the fence up yourself and have since forgotten why.

This is one good place to use WUTS. Wonder is noticing the fence without deciding it’s stupid. Unpack is finding out who built it and whether the field it guarded still exists. Tinker is leaning on it a bit before pulling it out. Share is leaving a sign so the next person doesn’t have to repeat the investigation.

Illustration: a weathered fence post standing in tall grass, a hand-lettered wooden sign nailed to it reading “Ask me why.”
A familiar sort of “Huh?” Occasionally, I built the fence.

What this is not

It isn’t a checklist, a ticket workflow, or four new statuses on a board. Nobody should be “in Unpack.”

It isn’t a mandate to change things. It also isn’t a mandate to leave them alone.

It isn’t a substitute for judgment. It’s a way of noticing when you’re about to skip the part that required some.

And one more time

Notice before you judge. Understand before you prescribe. Learn before you commit. Make the next encounter easier.

Illustration: thumbs up, thinking “That’s one less riddle.”
That’s the whole ambition. One less riddle.

Origin

Where this habit came from.

I’m Robby Russell. I’ve spent most of my career around software that somebody else started. For twenty-four years I’ve run Planet Argon, a consultancy that mostly gets called when an application has been running for a decade and the team needs help making sense of it again. Mending, repairing, modernizing where it’s warranted, and fairly often talking a team out of the big rewrite they showed up asking for.

I host Maintainable, where I’ve had hundreds of conversations about the art of maintaining and improving existing software, and I co-host On Rails for the Rails Foundation. A lot of those conversations circle the same thing: the engineer who understood why something was the way it was, and what it cost the team when nobody did.

WUTS is my attempt to name that habit so it can be taught, tried, and passed around. It’s just as useful with code you wrote yesterday, a workflow you repeat every week, or a customer doing something you didn’t expect. I introduced it in a keynote at Rails World 2026.

The name is a bit of a joke. The reaction it’s built around usually isn’t “huh?”; it’s the other one. Hence the domain.

There’s a recording of the keynote coming. I’ll put the link here when it shows up.

Report back

What did you find?

Tried WUTS on something? Tell me where it led. A tiny experiment, some context you turned up, something you changed, or something you decided was better left alone.

Or write it up somewhere of your own and send me the link. Those are usually the better ones.

Questions people ask

Is this just root cause analysis or the five whys with a new name

Those start after you’ve agreed something is a problem, and they aim at a cause. WUTS starts earlier, at the “huh?”, and it’s fine with ending in “this is intentional and here’s why.” Tinker also asks for an experiment before you commit, which most RCA formats skip. Use them together if you like; they’re not competing.

Is WUTS only for inherited or legacy software

No. Code you wrote yesterday, a new abstraction, a slow test, or a familiar command behaving strangely can all make you pause. Inherited software is one useful scenario. WUTS begins with noticing something, wherever it came from.

Isn’t this just FAFO

Same curiosity, a little more discipline. Messing with things is a useful way to learn. WUTS asks what caught your attention, what context you need, what small experiment would teach you something, and how you’ll share the learning. Tinker is structured FAFO.

Is this only for engineers

No. It’s for people who work on software. Engineers, product managers, designers, and support leads all notice friction, surprises, and mismatched expectations. Any of those can be the signal.

Isn’t this just an argument against ever changing anything

It isn’t. Plenty of WUTS cycles end in changing, removing, or replacing something. The point is to understand what you noticed before deciding it needs fixing. Weird might be broken. It might also be intentional, temporary, or perfectly fine.

Does it only apply to code

No. A confusing deployment, an awkward workflow, a surprising product behavior, and a repeating agent mistake can all be starting points. The signal matters more than which part of software work produced it.

How long should a WUTS cycle take

Often minutes. Adding one log line and waiting a week can also be a complete Tinker. If Unpack becomes a research project or Tinker becomes a rewrite, ask a smaller question. You need enough understanding to make a better judgment.

Can I use this with my team

Sure, but please don’t make it a process. The moment there’s a Jira status called “Unpacking,” it stopped being curiosity. Pass the vocabulary around; keep the checklist out of it.

What about AI coding agents

An agent repeating the same mistake is a useful “Huh?” Sometimes it’s wrong; sometimes the environment makes the wrong choice look reasonable. Inspect what it can see, change one instruction or example, and try again. Keep what you learn somewhere future work can use it.