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

The Trigger That Was Wrong

~13 min · decision-record, judgment, packaging, process

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

An Alarm Is Not a Script

The vendoring decision carried a reversal condition you have already seen: if the consumer count grows past roughly five, revisit packaging, and write down what you found. The count grew past five. Then past fifteen. Then past thirty. For six weeks nobody wrote the revisit.

That silence is the first lesson, and it is not a scolding. Observable conditions still need someone to observe them. A number sitting in a document does not walk over to the architecture file and add a paragraph. The condition did its job the moment someone finally asked the question — it named what the question was about, so the conversation was about facts rather than mood. Late is worse than on time. Late is still infinitely better than never, which is what an unwritten condition produces.

The Revisit That Did Not Migrate

When the question was finally asked, the tempting answer was the one the trigger seemed to dictate: the count fired, therefore package. That would have been treating the alarm as the decision. The original reasoning was never "we have few consumers." The original reasoning was there is no isolation to buy — one owner, one machine, siblings deployed together, version skew as the defect the repository exists to remove.

Those facts were still true of the Python and TypeScript surfaces. Thirty-five loopback siblings on one machine have no more isolation to buy than four did. A published package would still have inserted a publish step, a version number, and the possibility of two consumers running different code. Consumer count alone was the wrong trigger. What would actually invert the Python and TypeScript answer is a consumer that cannot build from its own checkout. None existed. None exists.

A reversal condition forces a re-examination. It does not dictate the result. Write a count because counts are checkable, then re-run the reasoning against current facts. If the count has moved and the reasoning has not, the honest record is "examined, split, kept" — not "the number said package." An alarm that executes itself is just a different identity.

The Fact the Original Record Never Named

Swift was the exception, and the reason was not that Swift had more consumers. The reason was a fact the first decision record had no slot for: the compiler.

A vendored Python file is imported as source. A vendored TypeScript file is compiled in the consumer, but it does not form a graph of kit types that must stay coherent with each other — each file is a leaf, or close enough that the sync's file-to-file map is the right shape. A vendored Swift file is a separate compilation unit in every consumer. It cannot be tested once. And every Swift consumer in the family already had a package manifest able to hold a local path. The install ceremony the original record was avoiding did not exist on that side of the family.

So the revisit produced both mechanisms, split by language. That is a more interesting outcome than either extreme. The next three lessons are the pieces of it: what a path package actually is, why file copies cannot keep dependent types aligned, and what teeth look like when the consumer compiles the kit tree as it sits.

Code

The same decision record, after the overdue revisit·text
DECISION (amended): two mechanisms, split by language.
  - Python, TypeScript, assets: still vendored copies + a drift check.
  - Layered Swift: a local path package in the kit repository.
  - Generated Swift bindings and dependency-free Swift leaves: still
    vendored. They never needed the compiler's graph.

WHAT THE COUNT GOT RIGHT:
  it forced the question. Thirty-five is not five. Six weeks of
  silence was the failure, not the number.

WHAT THE COUNT GOT WRONG:
  it named the cause. The original reasoning was 'no isolation to
  buy', not 'we are small'. Python and TypeScript still have no
  isolation to buy.

THE FACT THE FIRST RECORD HAD NO SLOT FOR:
  a vendored Swift file is a separate compilation unit. It cannot
  be tested once. Dependent types can drift across files because
  the sync map has no version coherence. Every Swift consumer
  already had a package manifest that understands a path.

NEXT TRIGGER (restate, do not inherit):
  [ ] a Swift consumer that does not live on this machine
  [ ] a vendored Python or TypeScript leaf that grows a dependency
      its consumers do not already have
  [ ] a consumer that cannot build from its own checkout

External links

Exercise

Find a reversal condition in your own system that is a count, a date, or a presence check. Evaluate it today. If it has already fired, write the revisit before you change anything: what the alarm got right, what it got wrong as a cause, and the next trigger restated. If it has not fired, write one sentence naming a fact the original record has no slot for — the Swift-shaped fact, the one that would split the answer rather than invert it.
Hint
The useful sentence is rarely 'we should package' or 'we should not.' It is 'the original reasoning assumed X, and X is still true of A and no longer true of B.'

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.