Skip to content
C.W.K.
Lesson 05 of 05 · published

Self-Contained First, Links Later

~13 min · coupling, self-contained, deferred-design, contracts

Level 0Mise en Place
0 XP0/43 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

The ruling

일단 다른 앱에 의존하지 말고 자체적으로 구현하는 쪽으로 가.

"For now, don't depend on other apps. Go with building it on its own." Ruling 2 spells out what that rules out for version 1: no Waystone or Vesta crumbs, no photos borrowed from the Photos library by reference, nothing from Spark or Forge. Sizzle captures and keeps its own photos and its own records. Links to siblings come after v1, each as a pointer its owner resolves.

The same paragraph draws the line that keeps the ruling sensible. cwkPippa and the vendored cwkSiblingKit plumbing are the family foundation, and the doc refuses to count them as app dependencies. I'm the one who reads the plate, so Sizzle can't stand without me. The kit is code copied into the repository and drift-checked, so it isn't a runtime service at all. sibling-kit-quest explains why the family vendors its shared code instead of packaging it.

What the engine is allowed to dial

You can check a ruling like this against the code. Every family address the engine dials is set in backend/settings.py from the family registry, and only two members appear there. cwkPippa is reached on loopback for readings and conversations. Firelink's facade, also on loopback, is where the brain slots live. Neither one hands Sizzle a plate, a photo or a dish. There is no Forge origin, no Spark origin and no Waystone origin, and the vendored kit modules take their addresses from these settings instead of carrying their own.

Designs that wait

Ruling 2 didn't stop siblings from proposing links. It decided what happens to the proposals. Two are written into the design in detail, and neither is built.

  • The Spark handoff (coop request #264). Spark, the family's interpreter app, proposed a contract on the day Sizzle was designed. It rests on the family item reference from cwkSiblingKit, {app, kind, id, parent}: the owner answers for its item, and the app that links to it never copies it. Spark named two directions. From a translated menu line in Spark, open the dish's principle in Sizzle. From Sizzle, an "order this" action hands Spark a sentence that becomes an interpretation card.
  • Forge links. In the starting material, a meal Dad actually ate would become a cwkForge intake crumb by reference, and Forge state would flow back as constraints. Rulings 2 and 3 narrowed that to nothing for v1.

Sizzle's answer to Spark is a careful middle. It takes the contract in principle, writes counter-notes, and builds nothing until ruling 2 is revisited with Dad. The counter-notes are good design work on their own:

  1. Two owned kinds. A class (principle, dish or variant) and a plate (an encounter). The one-item reads already exist, so taking the contract means adding a display label to them and no new route.
  2. A menu line lands as a question. A plate needs a photo, so a line from Spark would open a Sizzle thread with its text and a pointer back to the Spark moment, kept as a reference and never copied. That needs Sizzle deep links, a web route and a cwksizzle:// scheme, and neither exists.
  3. "Order this" is accepted as proposed, with Dad confirming before Pippa writes the card.

Checking that held means held

"Not built" is a claim about code, so check it. Searching the repository for the deep-link scheme, the kit's item-reference module and Spark's link parameters finds only the architecture doc. The iOS project declares no URL scheme. Of the twelve kit_* modules the engine vendors, none is kit_item_ref. Go looking for these features in the app and you won't find them, and no lesson in this quest teaches them as features.

Why wait

Every link is one more way to fail. While Sizzle stands alone, a missing Spark or a sleeping Forge can't break a capture or a reading. The doc's system table says what happens when the one real dependency is away: if cwkPippa is unavailable, capture and browsing keep working, and readings and replies wait and show as pending. The code keeps the first half and is blunter about the second. A reading that can't reach me records reading.failed, and the plate shows the failure with a Read again button. A reply that can't reach me records turn.failed, and the thread offers Ask again. Nothing waits on its own, and nothing is lost either: the plate, its photos and the question stay where they were. That is a short list of what can go wrong, and Dad chose to keep it short until the core worked.

The held contract earns its place while it waits. When the ruling is revisited, the conversation starts from a contract that already exists on Spark's side and counter-notes that already exist on Sizzle's.

Principle: Write an integration down when it is proposed. Build it when the owner of the data and the person who decides both say go.

Code

cwkSizzle, backend/settings.py: the only two family origins the engine dials (verbatim, lines 25-36)·python
# The engine runs on service host beside cwkPippa and reaches it over loopback,
# like Forge, Vesta and Waystone. Loopback is outside macOS 26's Local
# Network gate and is the boundary cwkPippa trusts without a PIN; a
# tailnet origin here answers 401 pin_required (Easel, 2026-09-25).
PIPPA_BASE = os.environ.get("SIZZLE_PIPPA_BASE", loopback_origin("cwkPippa")).rstrip("/")

# Brains are global family settings held by the Brain Control Plane, reached
# through Firelink's facade on loopback like every engine on service host. Sizzle's
# Settings page and Firelink's Brains tab edit the same per-function slots
# (brain_control.py). These two values only seed the reading slot's first
# registration; after that central is the only truth.
FAMILY_CONTROL_BASE = os.environ.get("SIZZLE_FAMILY_CONTROL_BASE", loopback_origin("cwkFirelink")).rstrip("/")
Run against cwkSizzle origin/main d6212b7: the held links exist only in the design doc (commands and output as printed)·shell
$ git grep -n -E 'cwksizzle://|kit_item_ref|link_app' origin/main -- .
origin/main:docs/SIZZLE-ARCHITECTURE.md:260:(cwkSiblingKit SIBLING-CONTRACTS §16, `kit_item_ref.py`) is `{app, kind,
origin/main:docs/SIZZLE-ARCHITECTURE.md:262:Spark receives links on the web (`/?link_app&link_kind&link_id&link_parent&link_label`)
origin/main:docs/SIZZLE-ARCHITECTURE.md:286:   and a `cwksizzle://` scheme in SizzleMobile, neither of which exists yet.
$ git grep -n 'CFBundleURLTypes' origin/main -- clients; echo "exit $?"
exit 1
$ git ls-tree --name-only origin/main backend/ | grep kit_
backend/kit_atomic_file.py
backend/kit_brain_control.py
backend/kit_brain_control_routes.py
backend/kit_brain_control_testing.py
backend/kit_log_format.py
backend/kit_pippa.py
backend/kit_pippa_brains.py
backend/kit_pippa_uploads.py
backend/kit_product_version.py
backend/kit_staged_uploads.py
backend/kit_ulid.py
backend/kit_webui_static.py
cwkSiblingKit, kit/python/kit_item_ref.py: the family item reference a link would rest on (verbatim, lines 1-13)·python
"""The family item reference: point at another app's item, never copy it.

Canonical here; the contract is SIBLING-CONTRACTS §16. A reference is
``{app, kind, id, parent}``: the owning app, its own word for the item, the
item's id, and the container the id is unique within when it is not unique
alone (a Waystone crumb id is unique inside its journey; a Vesta crumb id is
unique across journals and survives a move, so it carries no parent).

The linking app stores the reference, and at most a label it saw when the
link was made; everything else is asked of the owner when it is shown
(Forge's and Vesta's no-warehouse rule). :func:`resolve` asks the owner's
one-item route and folds the answer into one card shape, so a linking
surface draws a Waystone crumb, a Vesta crumb and a Spark moment the same way.

External links

Exercise

List every outside system your first version talks to at runtime. Sort each into foundation (the product cannot be what it is without it) or dependency (a feature borrowed from someone else's data). For one dependency, write the pointer contract you would use later, in the shape {app, kind, id, parent}, and describe what your v1 does instead today. Then search your code to confirm the deferred link really is absent.
Hint
A pointer contract says who owns the item and what the linking side may keep: usually the reference and at most a label it saw. If your v1 fallback needs a copy of the other app's data, you have built the dependency early under another name.

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 in — Please sign in to comment.

No comments yet — be the first.