Files
ng-eventually/.project/concepts/app-contract/rule_would-the-caller-unlearn-it.md
T
Sylvain Duchesne 30f6263db5 docs(concept): le contrat entre le polyfill et l'application qui l'utilise
Amorce le système `concept` dans ce dépôt et ouvre `app-contract` — la frontière
entre cette bibliothèque et les applications qui la consomment.

C'est un contrat **inter-dépôts** et ce dépôt en est le FOURNISSEUR : les applications
vivent ailleurs et tireront `sdk-surface` d'ici. D'où le type `contract_`, ses cinq
sections obligatoires, et l'inscription dans `.project/contracts.yaml` — c'est
l'inscription qui publie.

Trois feuilles :

- **`contract_sdk-surface`** — l'engagement, écrit du point de vue de l'appelant.
  Ce qu'il peut tenir pour acquis : permissif en entrée et précis en sortie ; toute
  référence rendue est NUE, aucun appel ne rend jamais de clé ; lire est la possession,
  écrire est la propriété ; donner à lire est un seul acte et le destinataire n'appelle
  rien ; un dépôt s'adresse à une inbox, jamais à un document ; `ensureIdentity()` est
  toute la connexion ; et `configure` est le seul appel qu'il supprimera.
  Ce qu'il ne doit PAS tenir pour acquis, dit aussi crûment : aucune confidentialité,
  rien de « par lecteur » sur un document public, aucune révocation, aucune écriture
  déléguée, et les références ne voyagent que dans un déploiement.

- **`rule_would-the-caller-unlearn-it`** — le test qui décide de tout : est-ce que
  ceci ferait apprendre à l'appelant quelque chose qu'il devra DÉSAPPRENDRE ? Avec les
  deux tells que la revue de ces jours-ci a rendus concrets : une exception nommée
  cesse d'en être une dès qu'on la publie, et un symbole gardé parce qu'il était là
  n'est pas une décision.

- **`knowledge_what-an-app-deletes-at-migration`** — les deux destins d'un symbole
  publié, le cas intermédiaire d'`ensureIdentity` (substance jetée, site d'appel
  conservé), et le fait que la liste de suppression n'est plus portée par un chemin
  d'import depuis la fusion des entrées : une garantie mécanique remplacée par une
  garantie documentaire, dont seule la moitié est tenue par un test.

Le vocabulaire du concept fixe trois termes que ce projet a déjà payé cher :
`reference` (jamais « lien »), `ReadCap`, `polyfill-era`. `lint` est conformant.

Reste à décider : ce dépôt n'a pas de `CLAUDE.md` racine, donc l'`AGENTS.md` généré
n'est chargé nulle part.
2026-08-10 09:25:01 +02:00

3.0 KiB

type, summary
type summary
rule Before publishing anything, ask whether a caller would have to unlearn it — that outranks cost, latency and convenience

Would the caller have to UNLEARN it?

Rule: Before adding, keeping or changing anything on the published surface, ask: would an application coding against this learn something it has to unlearn at migration? If yes, it is a deviation — whatever it buys in cost, latency or ergonomics. Both halves are binding: the surface must be as close as possible to the future SDK, and the implementation as close as possible to what NextGraph actually plans. Where upstream's behaviour is known, it is a specification, not a reference.

"Known" is narrow: read in nextgraph-rs, or stated by its author. Never inferred from what an npm package happens to expose, and never inferred from an absent implementation"the engine does not do X" says nothing about whether the target will.

Why: this library's entire value is that an application keeps its code. A layer that teaches a false model destroys exactly what it was built to produce, and it does so silently: nothing fails, the application simply learns a habit that has no successor. Two instances, both caught only by asking the question — "every document has a native inbox", written from general reasoning, false, and already an implementation; and a per-document inbox pointed at its owner's inbox to absorb a measured cost, emulating a many-to-one relation the target cannot express and which would have made applications tag their deposits, for nothing.

The pressure to deviate never announces itself as one. It arrives as a cost, a latency, an ergonomic wrinkle — all real, all legitimate. That disguise is what makes it dangerous. When shape and cost conflict: keep the shape and attack the cost elsewhere (usually the lever is who pays and when). If the cost is genuinely unsolvable, say so rather than bending the model quietly.

How to apply: the tell is a symbol that makes the caller handle something the target will never hand it — a key, an inbox address, a store id, its own identity. Two secondary tells, both of which have produced real holes here:

  • A named exception stops being one the moment it is published. A door documented as "only this internal caller uses it" is a door any application can open; the note is not a mechanism. Move it out of the published surface instead.
  • A symbol kept because it was already there is not a decision. At every surface change, re-ask whether an application still needs each neighbouring symbol; inertia has repeatedly left published what nothing calls.

Applies to the published surface first, but also to internal choices that shape it: an emulation whose relation the target cannot express will surface as a habit sooner or later. When a deviation is genuinely necessary, it must be deliberate, documented and invisible to the caller — what is forbidden is the silent one, adopted because it was convenient.