Feature Chain — Tracer tout le stack avec un seul operationId

Quels fichiers faut-il toucher pour modifier une seule fonctionnalité ? Tapez un operationId et la réponse apparaît.


Le problème

Dans une application full-stack, une « fonctionnalité » ne vit pas dans un seul fichier.

Supposons que vous deviez modifier une fonctionnalité appelée « ExecuteWorkflow ». Cette fonctionnalité se trouve dans la spécification API, dans la logique de service, dans le schéma de base de données, dans la politique d’autorisation, dans le diagramme de transition d’états, dans les appels de fonctions externes, dans les scénarios de test et dans les composants frontend.

Historiquement, il y avait deux moyens d’embrasser toute cette portée :

  1. Lancer grep des dizaines de fois
  2. Tracer le code à la main

Les deux sont lents, et les deux laissent des choses de côté. Les références entre couches en particulier — de la spécification API au service, du service au schéma de BD, du service à la politique d’autorisation — sont pratiquement impossibles à tracer exhaustivement pour un humain.

C’est pire quand on confie la modification à une IA. À 200 endpoints, l’IA ne peut plus maintenir tout le contexte. Le contexte s’effondre, les patterns dérivent et la 201ème fonctionnalité coûte 10× la 21ème. C’est le mur contre lequel le vibe coding se heurte.

Mais si la source de chaque couche référence symboliquement les autres, suivre ces références suffit à révéler automatiquement toute la portée.


Qu’est-ce que Feature Chain

Feature Chain est l’ensemble des nœuds source connectés à une seule fonctionnalité API (operationId).

En partant d’un operationId, il suit les références symboliques entre sources et imprime d’un seul coup tous les fichiers et numéros de ligne associés. Des dizaines de grep sont remplacés par une seule commande.

yongol chain ExecuteWorkflow specs/
── Feature Chain: ExecuteWorkflow ──

  OpenAPI    api/openapi.yaml                         POST /workflows/{id}/execute
  SSaC       service/workflow/execute_workflow.ssac   @get @empty @auth @state @call @publish @response
  DDL        db/workflows.sql                         CREATE TABLE workflows
  DDL        db/execution_logs.sql                    CREATE TABLE execution_logs
  Rego       policy/authz.rego                        resource: workflow
  StateDiag  states/workflow.md                       diagram: workflow → ExecuteWorkflow
  FuncSpec   func/billing/check_credits.go            @func billing.CheckCredits
  FuncSpec   func/billing/deduct_credit.go            @func billing.DeductCredit
  FuncSpec   func/worker/process_actions.go           @func worker.ProcessActions
  FuncSpec   func/webhook/deliver.go                  @func webhook.Deliver
  Hurl       tests/scenario-happy-path.hurl           scenario: scenario-happy-path.hurl

Toute la structure d’une fonctionnalité tient sur un écran. Les couches non connectées ne sont pas imprimées.


Pourquoi ça marche

Ce n’est pas de la magie. Ça marche parce que les sources se référencent déjà entre elles.

Dans le framework yongol, chaque couche SSOT (Single Source of Truth) pointe symboliquement vers les autres :

  • @get Model.Method de SSaC → table DDL
  • @auth action resource de SSaC → politique d’autorisation Rego
  • @state diagramID de SSaC → diagramme d’états Mermaid
  • @call pkg.Func de SSaC → implémentation FuncSpec
  • @publish "topic" de SSaC → fonctions qui s’abonnent au même topic
  • operationId d’OpenAPI → nom de fichier SSaC
  • Scénario Hurl → endpoint OpenAPI
  • apiClient.<op>() de React TSX → operationId OpenAPI

Ces références ont été conçues à l’origine pour yongol validate — l’étape qui valide de manière croisée la cohérence des 9 SSOT avant la compilation. Comme validate les parse déjà, réutiliser la même infrastructure transforme l’extraction du feature chain en un parcours de graphe.


Le parcours

En partant d’un operationId, le graphe de références se déploie ainsi :

operationId (point d'entrée)
├── OpenAPI → path + method
├── SSaC → fichier de fonction de service
│   ├── @get → tables DDL
│   ├── @auth → règles de politique Rego
│   ├── @state → transitions de Mermaid stateDiagram
│   ├── @call → implémentations FuncSpec
│   └── @publish → abonnés de file d'attente
├── Hurl → scénarios de test référençant l'operationId
└── React TSX → fichiers frontend appelant l'endpoint via apiClient

Chaque branche ne suit qu’un seul pas de référence symbolique. C’est un parcours en largeur, pas en profondeur. Chaque couche où une fonctionnalité laisse une trace apparaît.


Ce que cela change

Cerner les modifications

« Où toucher pour changer cette fonctionnalité ? »

Pour répondre à cela, on lit du code, on lance grep, on demande à un collègue. Feature Chain remplace la question par une seule commande. Aucun fichier n’échappe — tant que la référence symbolique existe.

Modifications pilotées par IA

Le plus difficile quand on délègue un changement à une IA, c’est de lui dire « quelle est la portée ». L’IA ne peut modifier correctement que si les fichiers pertinents sont dans sa fenêtre de contexte, et c’est à un humain de juger lesquels le sont.

Avec Feature Chain c’est différent. On lui donne un seul operationId et toute la portée est identifiée automatiquement. Le contexte de l’IA est préparé sans manque. Comme les 9 SSOT sont des spécifications déclaratives — bien plus compactes que le code Go généré — on peut faire tenir toute la chaîne dans la fenêtre de contexte avec de la marge.

Code review

En relisant une PR, « s’ils ont touché cette fonctionnalité, ce fichier-là ne devrait-il pas aussi changer ? » devient trivial à vérifier — il suffit de comparer à la chaîne. La structure attrape les incohérences entre couches à la place des personnes.

Onboarding

Quand une nouvelle personne dit « je veux comprendre comment ExecuteWorkflow fonctionne », montrez-lui une Feature Chain. De l’API à la BD, de la politique d’autorisation aux scénarios de test — tout le terrain d’une fonctionnalité sur un écran.


Pourquoi operationId

Le choix du point d’entrée compte. Feature Chain a choisi operationId.

La raison est simple. Dans une application full-stack, l’unité d’une fonctionnalité est l’endpoint API. Un utilisateur clique sur un bouton, une API est appelée, la logique de service s’exécute, la BD est lue, l’autorisation est vérifiée, des transitions d’états ont lieu. Le début de tout ce flux est l’operationId.

operationId est déjà défini dans la spécification OpenAPI et c’est un nom partagé par toute l’équipe. Dites « il faut modifier ExecuteWorkflow » et l’ingénieur backend, l’ingénieur frontend et le QA pensent tous à la même chose. Feature Chain est conçu autour de ce nom universel comme fil traversant tout le stack.

yongol appelle cela « operationId est la clé de voûte (keystone) ». Un seul identifiant en PascalCase lie physiquement les 9 couches.


Préconditions

Pour que Feature Chain fonctionne, il y a des hypothèses :

  1. Les sources doivent se référencer symboliquement entre elles. Les directives @get, @auth, @state, @call, @publish de SSaC doivent pointer explicitement vers d’autres SSOT. Si la référence est implicite — par exemple, un nom de table de BD qui n’existe que sous forme de chaîne dans le code — elle ne peut pas être tracée.

  2. yongol validate doit passer. Feature Chain suit des références symboliques ; si elles ne sont pas valides, le résultat est faux. validate garantit l’intégrité des références ; Feature Chain parcourt par-dessus.

C’est pourquoi Feature Chain n’est pas un outil généraliste. Il ne s’applique pas à n’importe quel projet. Il ne fonctionne que dans les projets où les références entre sources sont conçues explicitement — comme yongol, où les SSOT se pointent mutuellement de manière explicite.


Avenir : GEUL + SILK

Aujourd’hui, Feature Chain parcourt en invoquant chaque parser SSOT tour à tour. Il appelle le parser SSaC, le parser DDL, le parser Rego, le parser Mermaid, le parser Hurl et le parser TSX, puis combine les résultats.

Une fois que tous les SSOT seront traduits dans un graphe GEUL, Feature Chain deviendra une seule requête d’index. Avec l’opération AND bit à bit de SIDX dans SILK, tous les nœuds connectés à un operationId peuvent être extraits en une seule requête.

Du parcours parser par parser à la requête de graphe. L’interface de Feature Chain reste la même, mais l’intérieur change fondamentalement.


Conclusion

Dans une application full-stack, une « fonctionnalité » ne vit pas dans un seul fichier. Elle s’étend sur plusieurs couches, et ces couches se référencent entre elles. Feature Chain suit ces références pour extraire automatiquement la portée complète d’une seule fonctionnalité.

Tapez un operationId et vous obtenez tout : de la spécification API au schéma de BD, de la politique d’autorisation aux scénarios de test, de l’implémentation de fonction au composant frontend. Des dizaines de grep remplacés par une seule commande. L’IA reçoit un contexte sans manque ; l’humain reçoit la liberté sur les rails.

Code : github.com/park-jun-woo/yongol