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

The One Question That Decides Membership

~14 min · boundaries, design, judgment, decision-record

Level 0Loose Parts
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

The Test

Every candidate module gets exactly one question: does this need to know what the app is about?

Not "is it used twice". Not "is it generic-looking". Not "would it be nice to reuse". Usage count is a trigger for asking; it is not the answer. A module used by five apps that encodes a product decision still belongs to whichever app owns that decision, and a module used by one app that encodes nothing belongs in the shared layer the moment a second app needs it.

Run it on real candidates and it is unusually decisive:

  • An identifier minter — timestamp plus randomness, sortable, no parsing. Knows nothing. In.
  • Line-level encryption at rest — takes a key slot name as a parameter. Knows nothing. In.
  • A capture-time helper that stamps the device's own local date and offset. Knows nothing about what is being captured. In.
  • The journey container — a trip with a start, an end, and lanes. Knows everything about one app. Out, permanently, even though a second app could technically use it.
  • A health interpretation that turns readings into a narrative. Knows the domain and its ethics. Out.
  • The composer and the record card — every app has one, they look alike, and they are domain-toned all the way through. Out, and recorded as intentional divergence so nobody re-proposes it every quarter.

The Case That Was Actually Hard

The biggest surface the kit ever admitted was a delegation-queue kernel: the machinery behind a workshop that queues work, hands it to a worker, holds a claim so two workers cannot take the same job, leases a landing so two results cannot collide, and records everything. It was the first admission with server-side transition logic, and it looks exactly like a framework.

The test returned the same answer anyway. The kernel knows nothing about quests, episodes, or vault entries. What the subject of a job even is — the column is named differently in each workshop — is injected by the app. The extra columns, the landing semantics, the validation rules, and what makes a job valid at all are each the app's craft. What the kernel owns is only the shapes that three independently written engines had already converged on.

And that convergence is the interesting evidence. One pair of engines was a 72–87% textual copy of each other's plumbing modules, which proves nothing except that somebody copied. The third had roughly 4% textual overlap with them — written independently, by a different session, for a different domain — and it had arrived at the same route contract, the same schema shape, and a column-identical table for tracking dispatch attempts. Two copies prove a copy. Independent convergence from 4% overlap proves the shape was real before anybody named it.

An arguable admission has to be written down with its reasoning, not just decided. Obvious cases need no record — nobody will ever litigate whether a ULID minter knows what the app is about. Arguable cases will be re-litigated, by someone with less context, at a worse moment. Recording the reasoning is not ceremony; it is what makes the next arguable case a comparison rather than a fresh argument.

What the Test Protects Against

The failure mode it prevents is subtle, because it does not look like a mistake at any single step. A module goes in because it is 90% generic. The 10% is handled by a flag. A third app needs a variation, so the flag becomes an enum. A fourth needs behavior the enum cannot express, so a callback is added. Now the shared module contains a small, undocumented model of what applications are, every app must be built to satisfy it, and changing it requires understanding four domains at once.

Each step was locally reasonable. The question at the top would have refused the first one.

Code

The test, applied — and the smell that means you failed it·python
# PASSES: the module cannot tell which app called it.
def new_id(ts_ms: int | None = None) -> str:
    """Timestamp + randomness, lexicographically sortable."""
    ...

def encrypt_line(text: str, *, key_slot: str) -> str:
    """The app names its own key slot; the algorithm does not care."""
    ...

def claims_ddl(subject_col: str) -> str:
    """The app names what a job is ABOUT. The kernel only knows that
    exactly one claim per subject may be active at a time."""
    ...


# FAILS: a shared module that has learned what applications are.
# Nothing here is wrong on its own line. Read it as a whole and it
# is a framework: every app must now be expressible in this vocabulary.
def render_record_card(record, *, app: str):
    if app == "travel":
        title = record["journey"]["name"]        # domain leaked in
    elif app == "journal":
        title = record["date"]                   # ...and again
    elif app == "health":
        title = f"{record['module']} - {record['reading']}"
    else:
        raise ValueError(f"unknown app: {app}")   # <- the smell:
                                                  # the kit can now be
                                                  # WRONG about an app
    ...


# The rewrite that passes: the app supplies the knowledge, the kit
# supplies the mechanism. Note that the kit can no longer be wrong
# about an app, because it no longer knows any app exists.
def render_record_card_ok(record, *, title_of):
    title = title_of(record)
    ...


# A canary for the shared repo's own tests - and note carefully what
# it does NOT assert. Kit modules legitimately NAME consumers in
# provenance docstrings ("extracted from X, Y and Z"), because a
# comment recording where code came from is not knowledge the code
# acts on. What must never appear is a consumer name that the RUNNING
# CODE branches on.
def test_no_kit_module_branches_on_a_consumer(kit_sources, consumers):
    for path, text in kit_sources.items():
        code = strip_comments_and_docstrings(text)
        for name in consumers:
            assert name.lower() not in code.lower(), (
                f"{path} names {name} in executable code"
            )

# And even that is a floor, not the rule. The rule is the question at
# the top - does this module need to know what the app is about? - and
# a module can fail it without ever spelling an app's name, by taking
# a parameter whose VALUES are the apps.

External links

Exercise

Take the three most 'obviously shared' modules in any codebase you work on and run the question against each: does it need to know what the app is about? Then grep each one for the names of your applications, environments, or tenants. Every hit is a place where knowledge leaked into the shared layer. Write down, for one hit, what you would inject instead.
Hint
The grep finds the loud cases. The quiet ones are values rather than names — a default that is only correct for one caller, a magic number that came from one product's requirements, an ordering that matches one screen. Those need the question, not the grep.

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.