Skip to content
C.W.K.
Stream
Lesson 02 of 04 · published

Identity Belongs to One Owner

~12 min · extraction, ownership, consistency, caching

Level 0Cold Workshop
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

The Shorter Call Is the Wrong Call

Calling a speech provider directly is a handful of lines: authenticate, post the text, receive audio. Routing through a sibling is not obviously better — it adds a hop, a dependency, and a service that has to be running. On line count alone, the direct call wins.

It loses on everything the line count does not show. Producing narration is not one operation; it is four concerns bundled together, and only one of them is "send text to a provider."

  • Identity resolution — a name maps to a specific voice on a specific account. That mapping is a fact about who is speaking, not a parameter.
  • Normalization — what happens to the text before synthesis: how numbers are spoken, how abbreviations expand, which punctuation becomes a pause.
  • The cache contract — what counts as the same request, and therefore when a previous take is returned instead of a new one.
  • The provider call — the only part the direct version actually replaces.

What Two Implementations Would Do

Fork those concerns across two tools and they drift, quietly, in a way that is hard to attribute. One tool expands an abbreviation and the other spells it out. One treats a semicolon as a pause and the other doesn't. One caches on exact text and the other on normalized text, so identical-looking requests behave differently. The symptom is not a crash — it is narration that sounds subtly unlike itself depending on which tool produced it, and by the time anyone notices, both implementations have users.

This is the consumer's view of capability extraction. The usual framing is from the producer's side: pull the shared thing out, give it an owner, let callers depend on it. Standing on the caller's side, the discipline feels different — it is the daily refusal of a shorter path, and it holds only because the rule is written down as ownership rather than left as a preference.

Extract the concern, not the call. The test for whether something deserves an owner is not how much code it is. It is whether two independent implementations would produce results that differ in ways users notice but tests do not — voice, formatting, rounding, time zones, sort order. Those are the things that must have exactly one owner.

Code

The two versions, and what the short one silently forks·python
# DIRECT - shorter, and it just forked four concerns.
def narrate_direct(text: str) -> bytes:
    return provider.synthesize(
        api_key=KEY,                    # a credential here
        voice_id="...",                 # identity, hardcoded
        text=text,                      # no normalization
    )                                   # no shared cache


# ROUTED - one hop, and identity/normalization/caching stay
# in the component that defines what this voice IS.
def narrate(text: str, speaker: str) -> bytes:
    return owner_client.tts(text=text, speaker=speaker)


# The difference shows up months later as:
#   "why does the narration in this tool sound slightly off?"
# which is a question no stack trace will ever answer.

External links

Exercise

Find a formatting or presentation rule that appears in more than one place in your system — how money is displayed, how a name is rendered, how a timestamp is shown to a user. Diff the implementations carefully. If they already disagree in some edge case, you have found the failure mode this lesson describes; write down which one is correct and what it would take to make it the only one.
Hint
Edge cases are where the divergence lives: zero, negative numbers, very long strings, missing middle names, the boundary between one day and the next. The common paths usually agree, which is exactly why nobody has noticed.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.