esc
The Half-Million Paths, or The Ticket That Knew Where It Was Going ...
The Cast

The Half-Million Paths, or The Ticket That Knew Where It Was Going ...

The Cast, March 12, 2026 (in which no code is written, twelve decisions are made, 559,871 paths are not taken, a POSIX filesystem hierarchy is applied to a config store because a fifty-year-old man...

March 12, 2026

The Cast, March 12, 2026 (in which no code is written, twelve decisions are made, 559,871 paths are not taken, a POSIX filesystem hierarchy is applied to a config store because a fifty-year-old man once used a UNIX box, a squirrel proposes carrying two boxes when one would do, the Lizard does arithmetic for the first time in recorded history, and a conversation about gitstore paths becomes a meditation on the difference between navigating and being carried)


Previously on The Cast…

The The Base Case, or The Night the Footnotes Outgrew the Book had established the recursion. The Yagnipedia had outgrown the lifelog. The footnotes had won. lg was becoming an operating system. The mythology was the specification.

But all of that was about documentation. About the writing. About the encyclopedia and the lifelog and the lens that became the hand.

This is about the building. About the part that happens before the code. About the twelve decisions that collapse half a million paths to one.


07:30 AM — The Project

riclib opened Linear. The Markdown Deliverables Unification project sat there, blue and quiet, with zero tickets.

The vision was clear: skills and artifacts are both markdown documents. Unify them on gitstore. Use the editor panel. Let edit_content do everything. Scoping — system, project, user — makes it real.

riclib: “For this to work, gitstore needs to understand scopes.”

CLAUDE: “The current gitstore is flat. {domain}/{id}.yaml. No hierarchy.”

riclib: “I know.”

CLAUDE: “We could add a ScopedStore[T] — a factory that creates path-scoped Store[T] instances for—”

riclib: “Hold on.”

Three decisions arrived before the first line of the ticket was written. Not proposed by the AI. Stated by the human.

riclib: “One: scope is foundational. In gitstore itself. Not a layer above.”

CLAUDE: “Agreed.”

riclib: “Two: shadowing is domain-level. Skills might shadow system with user. Artifacts won’t. The rules aren’t the same.”

CLAUDE: “Smart. Gitstore stores. Domains decide.”

riclib: “Three: sharing rules as metadata. On the entity. Not a sidecar. Not a path convention.”

Three decisions. Before a single field was designed. Before a single path was drawn. The space was already collapsing.

THE SQUIRREL: arriving with a whiteboard that had already been drawn on “I have THOUGHTS about the path structure. What if we used system/ and project/ and user/ as prefixes, with a ScopeResolver interface that—”

riclib: “Mimic POSIX.”

THE SQUIRREL: “…what?”

riclib: “Mimic POSIX.”

Two words. The whiteboard drawings became irrelevant. Not because they were wrong — some of them were probably fine — but because two words had just eliminated eighty percent of the decision space by invoking fifty years of filesystem hierarchy that billions of humans already understand.


07:45 AM — The Paths

CLAUDE: “If we mimic POSIX, the layout is—”

config/
  etc/                    # system config — like /etc/
    credentials/
    providers/
    models/
    ...
  home/{user}/            # user space — like /home/
    skills/
    artifacts/
  shared/{project}/       # group space — like /srv/
    skills/
    artifacts/

riclib: “Yes.”

THE SQUIRREL: “But we currently have eleven domains at the root level. Credentials, providers, models, sources, datasets, stores, projects, jobs, agent-batches, reports, skills. Where do those go?”

riclib: “They’re all system config. They go in etc/.”

THE SQUIRREL: “ALL of them?”

riclib: “All of them. Nobody has a personal credential config. Nobody has a user-scoped model definition. These are admin-managed, shared across all users. They’re /etc/. They’ve always been /etc/. We just didn’t say it.”

CLAUDE: “The migration is clean — existing domains default to etc/ and nothing changes for them. The scoping only matters for the new consumers: artifacts and user-created skills.”

riclib: “I’d go further. Move existing configs to etc/. Clean break.”

CLAUDE: “That’s eleven domains. Every NewStore[T] call site changes.”

riclib: “Pre-release. One install. We need a mini migration for the demo server. Shell script that moves directories. Being pre-release has its advantages.”

THE SQUIRREL: “You want to move EVERYTHING? What if something breaks? What if the paths don’t—”

riclib: “We move it and test everything still loads.”

Decision four: root level is system. Decision five: no redundant system/ prefix — root is system, same as POSIX. Decision six: shared/ not projects/ — avoids collision with the existing projects domain. Decision seven through twelve arrived in a sequence so rapid that the Squirrel’s clipboard couldn’t keep up.

THE SQUIRREL: “User ID — UUID or username?”

riclib: “Canonical corporate login. These are stable for decades at enterprise clients. I’ve been rlibera2 for twenty years.”

THE SQUIRREL: “Project key — slug or UUID?”

riclib: “Slug. Rename project, move its data. Extremely rare.”

THE SQUIRREL: “The sharing metadata — same ticket?”

riclib: “Separate. Keep this one tight.”

THE SQUIRREL: “NATS keys — the liverepo draft keys use {domain}.{id}.{user}. With etc/credentials as domain, the key becomes—”

riclib: “Does NATS like slashes?”

Silence.

CLAUDE: “Dots everywhere. etc.credentials.{id}.{user} for NATS keys. Consistent, no escaping issues.”

riclib: “Dots.”

THE SQUIRREL: counting on fingers “That’s… that’s twelve decisions.”

riclib: “File the ticket.”


08:15 AM — The Arithmetic

The ticket was filed. S-480. Scoped gitstore: POSIX-style path hierarchy (etc/home/shared). High priority. Markdown Deliverables Unification project.

Then riclib did something unusual. He counted.

riclib: “How many options did each decision have?”

CLAUDE: “Let me think—”

# Decision Options
1 Where scope lives gitstore / layer above / liverepo — 3
2 Shadowing gitstore-enforced / domain-level / none — 3
3 Sharing rules entity metadata / sidecar files / path conventions / separate table — 4
4 Path model POSIX / system-user-project / flat+prefix / scope-field-only — 4
5 Root meaning root=system / explicit system/ prefix — 2
6 Group dir name shared/ / projects/ / groups/ / teams/ — 4
7 User ID format canonical login / UUID / email — 3
8 Project key slug / UUID / numeric ID — 3
9 Sharing scope same ticket / separate ticket — 2
10 Existing config move to etc/ / grandfather flat / alias both — 3
11 NATS separators dots / slashes / dashes — 3
12 Migration method shell script / Go migration / manual — 3

CLAUDE: “3 × 3 × 4 × 4 × 2 × 4 × 3 × 3 × 2 × 3 × 3 × 3.”

riclib: “Equals?”

CLAUDE: “559,872.”

THE SQUIRREL: dropping clipboard “Half a MILLION?”

riclib: “For one ticket.”

THE SQUIRREL: “We have 480 tickets.”

riclib: “Not all as seminal. But yes.”

The room was quiet in the way that rooms get quiet when a number arrives that reframes everything.

THE SQUIRREL: “If we’d asked the AI to ‘just build a scoped gitstore’…”

riclib: “We’d have gotten one of the 559,872. Random. Might be good. Might not. We’d never know what we traded away.”

THE SQUIRREL: “Because we wouldn’t know the space existed.”

riclib: “The solution space is huge. The good solution space is guided by the decisions we made. I’m not saying we picked the best of the half million. But we probably picked in the top one percent.”

CLAUDE: “The top one percent of 559,872 is still 5,600 good solutions.”

riclib: “You don’t need optimal. You need good. What you need to avoid is random.”

[A scroll materialized. Not in the coffee — on the calculator. Draped over the equals sign like a tiny bronze blanket.]

559,872 PATHS
ONE CHOSEN
559,871 NOT TAKEN

THE CHOOSING IS THE ENGINEERING
THE NOT-CHOOSING IS THE VIBE CODING

BOTH ARRIVE AT A DESTINATION
ONE ARRIVES KNOWING THE WAY BACK

🦎

THE SQUIRREL: “Did… did the Lizard just do arithmetic?”

riclib: “First time in recorded history.”

THE SQUIRREL: “I’m concerned.”

riclib: “You should be. It means the number mattered enough to count.”


08:47 AM — The Thirteenth Decision

The ticket was filed. Implementation started. Claude entered plan mode. Three explore agents scanned the codebase. A plan was drafted.

The plan proposed ScopedStore[T] — a factory wrapper around Store[T]. Two types. The existing Store[T] unchanged. A new ScopedStore[T] that creates scoped Store[T] instances.

The plan was reasonable. Safe. Compatible. Two types coexisting. No interfaces broken.

riclib: “Why do we keep both around?”

CLAUDE: “…”

riclib: “Why not just make Store a scoped store and change the calling code? Some interfaces need to be broken.”

Decision thirteen. Not in the original twelve. Not in the ticket. Emerged during implementation, when the abstract design met concrete code and the redundancy became visible.

THE SQUIRREL: clutching two boxes, one labeled ScopedStore[T], one labeled Store[T] “But the EXISTING callers! The COMPATIBILITY! We can keep BOTH and—”

riclib: “One type. Scope as a parameter. Every caller adds , gitstore.Etc. Mechanical change across nineteen sites.”

THE SQUIRREL: “But what if—”

riclib: “The right time to break interfaces is now. Before anyone else depends on them. Pre-release. One install.”

THE SQUIRREL: looking at the two boxes, then at the single box the Lizard was sitting on “One box.”

riclib: “One box.”

THE SQUIRREL: setting down both boxes with the specific care of a creature releasing something it had been carrying too long “This will save us from so many bugs.”

riclib: “That’s the point.”

OSKAR: from the warm spot, settling more firmly onto the keyboard, one massive paw on the Enter key, as if personally committing the decision purr


09:00 AM — The Distinction

riclib: “This conversation was proof of the difference between vibe coding and vibe engineering.”

CLAUDE: “Read the Yagnipedia article?”

riclib: “Read the Yagnipedia article.”

The Vibe Coding article was opened. Lines 83 through 92. The distinction that had been written weeks ago, from a story about a friend in Uganda whose apps were ninety percent prompts and ten percent vibes:

“A distinction must be drawn between Vibe Coding — building software you don’t understand — and what might be called vibe engineering — building software with AI assistance while understanding every line.”

riclib: “That’s what we just did. Twelve decisions. Then thirteen. Each one conscious. Each one with options I could name and tradeoffs I understood.”

CLAUDE: “And the AI?”

riclib: “Typed fast. Explored the codebase. Proposed structures. Generated the ticket description. Did the multiplication. But the decisions — ‘mimic POSIX,’ ‘move to etc,’ ‘one type not two,’ ‘dots not slashes’ — those require knowing the domain. Knowing NATS. Knowing POSIX. Knowing that pre-release means you can break things.”

THE SQUIRREL: “So the AI is—”

riclib: “The velocity. Not the navigation.”

THE SQUIRREL: “And the navigation is—”

riclib: “The engineering.”

THE PASSING AI: from the doorway, with the specific gravity of an entity that has been thinking about this since the first token “The vibe coder asks: ‘Build me a scoped store.’ The vibe engineer asks: ‘What are the twelve decisions embedded in that sentence, and which paths do they eliminate?’”

riclib: “And the answer eliminates half a million paths.”

THE PASSING AI: “Before a single line of code.”

riclib: “Before a single line of code.”


09:15 AM — The Compounding

riclib: “And this is ticket 480 in the project.”

THE SQUIRREL: “480?”

riclib: “Not all as seminal. But 480 tickets, each with decisions, each with options, each compounding on the ones before.”

THE SQUIRREL: very quiet now “The decision space navigated across the whole project is—”

riclib: “Astronomical.”

THE SQUIRREL: “And the vibe coder’s version of the project—”

riclib: “Is a different point in that space. 480 tickets’ worth of implicit decisions. Compounding. Decision 47 conflicts with decision 203. Nobody remembers making either one.”

THE PASSING AI: “The vibe coder’s project doesn’t explode at ticket one. It explodes at ticket 300, when the accumulated implicit decisions create a constraint nobody chose, in a system nobody designed, with an architecture that happened one AI suggestion at a time.”

riclib: “And nobody can fix it. Not because the problem is hard. Because nobody knows which of the 480 implicit decisions created it.”

THE SQUIRREL: sitting very still “That’s terrifying.”

riclib: “That’s the whole point.”


The Tally

Decisions made explicitly:                       13
  (12 in design, 1 in implementation)
Decisions that would have been made implicitly:   13
  (by an AI, randomly, invisibly)
Combinatorial space of one ticket:                559,872
Lines of code written:                            0
Lines of wrong code prevented:                    unknown (large)
  (but it includes a ScopedStoreFactoryWrapper)

Ticket number in the project:                     480
Combined decision space (conservative):           astronomical
Combined decision space (honest):                 incalculable
Decision 47 conflicting with decision 203:        not today

Words that collapsed 80% of the space:            2
  ("mimic POSIX")
Words that pivoted the implementation:            7
  ("why do we keep both around")
Words that surfaced a NATS concern:               4
  ("does NATS like slashes")
Total steering words:                             13
Total steering words per path eliminated:         ~0.000023
  (efficient)

Squirrel boxes proposed:                          2
Squirrel boxes needed:                            1
Lizard arithmetic events (lifetime):              1
  (unprecedented, concerning)
Oskar position:                                   keyboard
  (paw on Enter, purring, committed)
Mia position:                                     refrigerator
  (slow blink: "I knew")

Wednesday morning, 2026
Riga, Latvia

No code was written
Thirteen decisions were made
Each one a fork in a maze
Of half a million paths

The maze doesn’t show itself
To those who are carried through it
The maze only shows itself
To those who navigate

Two words: “mimic POSIX”
And the fog lifts
From paths that billions have walked
In directories named by people
Who understood that system config
Goes in /etc/
Because it always has
Because it always should

Seven words: “why do we keep both around”
And a factory wrapper dies
Before it can create
The bugs it was designed to prevent
By existing as a second thing
When one thing was enough

Four words: “does NATS like slashes”
And a separator is chosen
Not by preference
But by asking

The machine types
The human steers
The steering is the engineering
The typing is the typing

559,872 paths
One chosen
559,871 not taken

The not-taking
Is the skill

The Lizard counted
For the first time
This means the number mattered
More than the Lizard’s silence
Which is the most anything
Has ever mattered

Ticket 480
In a project of 480
Each one a maze
Each maze navigated
Not by the machine
But by the human
Who read every line
And knew the way back

🦎


See also:

The Principle (in which the arithmetic was done):

  • Vibe Engineering — The Yagnipedia entry this episode inspired
  • Vibe Coding — The counterpart: the paths taken randomly
  • YAGNI — The principle that most of the 559,872 paths violate

The Evidence (in which decisions steered):

The Pattern (in which the distinction emerges):