BC-067A — Dormant Projection Runtime Activation Design¶
Status: HISTORICAL
For the current architecture, see: ./dependances.md, ../runtime/overview.md, ./bc-067d-reference-core-final-certification.md.
Projet : /mnt/data/cmonchoix-platform
Branche : bc-048-samsung-wearable-enrichment
Verdict¶
BC-067A est fermable.
Recommandation¶
DO_NOT_ACTIVATE
Au 15 juillet 2026, nous n’avons toujours pas de preuve locale suffisante pour activer la chaîne dormant CatalogIntelligenceEngine -> ProjectionEngine/ProjectionCatalogWiring/EventSubscriberRegistry -> AsyncEventQueue/AsyncWorker -> RealtimeCatalogRebuilder.
Le design d’activation peut être préparé, mais il ne doit pas être mis en œuvre sur ce périmètre sans une nouvelle BC dédiée.
Rappel du point de départ¶
BC-066 a fermé la chaîne avec la décision KEEP_DORMANT.
Les preuves déjà certifiées restaient :
- aucun entrypoint runtime live ;
- aucun hook WordPress dédié ;
- aucun cron ou worker spécifique ;
- aucune queue durable ;
- aucun besoin produit live prouvé ;
- une valeur résiduelle de test, compatibilité et documentation.
BC-067A ne change rien à cet état. Elle transforme seulement cette conclusion en dossier d’activation/ non-activation exploitable.
1. Besoin produit¶
Les preuves collectées localement ne montrent aucun besoin produit avéré de realtime.
| Besoin | Source | Fréquence | Impact actuel | Justifie activation |
|---|---|---|---|---|
| Fraîcheur catalogue sous la cadence batch actuelle | docs/architecture/bc-066d-dormant-orchestration-decision.md |
aucune preuve | aucun incident relié à l’inactivité de la chaîne | non |
| Rebuild projection déclenché par événements produit | docs/architecture/bc-066e-final-certification.md |
aucune preuve | la chaîne reste utile seulement pour tests/compat | non |
| Runtime worker dédié pour Projection/Realtime | docs/runtime/overview.md |
non documenté | le runtime courant couvre déjà sync/worker sans cette chaîne | non |
| Débit batch insuffisant | wp ccx sync status exécuté le 15 juillet 2026 |
non prouvé | dernière exécution visible : processed_rows=501, success_rows=493, error_rows=0 |
non |
Conclusion : aucun besoin localement prouvé ne justifie aujourd’hui une activation.
2. Cas d’usage possibles¶
Ces cas d’usage existent conceptuellement, mais leur besoin runtime live n’est pas démontré.
| Use case | Event | Projection cible | Latence requise | Volume |
|---|---|---|---|---|
| création produit | product.created |
catalogue / produit | inconnue ; aucun besoin realtime prouvé | inconnu |
| changement prix offre | offer.price.changed |
intelligence catalogue | inconnue ; batch actuel acceptable | inconnu |
| changement stock offre | offer.stock.changed |
intelligence catalogue | inconnue | inconnu |
| changement taxonomy | taxonomy.changed |
navigation / catalogue | minutes acceptables si besoin futur | faible / inconnu |
| rebuild projection | technical.rebuild.requested |
projections catalogue/produit | opérationnel, piloté opérateur | épisodique |
| replay d’événements | technical.replay.requested |
projections / intelligence | opérationnel, jamais live aujourd’hui | épisodique |
3. Volumétrie¶
Nous avons très peu de métriques directement exploitables pour cette chaîne, ce qui est déjà un signal contre une activation immédiate.
| Metric | Current | Peak | Expected |
|---|---|---|---|
| lignes sync visibles / run | 501 | inconnu | inconnu |
| lignes sync succès / run | 493 | inconnu | inconnu |
| lignes sync erreur / run | 0 | inconnu | inconnu |
| Product Models | 11 | inconnu | inconnu |
| offres couvertes Product Models | 77 | inconnu | inconnu |
| événements / minute | inconnu | inconnu | inconnu |
| payload moyen | inconnu | inconnu | inconnu |
Source runtime live lisible :
wp ccx sync statusexécuté le 15 juillet 2026 ;wp ccx product-models statusexécuté le 15 juillet 2026.
Conclusion : on n’a pas encore la volumétrie minimale nécessaire pour justifier une chaîne événementielle durable.
4. SLA / SLO¶
Il n’existe pas de SLO produit prouvé qui impose l’activation.
| SLO | Target | Required |
|---|---|---|
| latence e2e de traitement événement | non défini | non |
| livraison durable | exigée avant activation | non |
| tolérance à la duplication | faible ; idempotence obligatoire avant activation | non |
| délai de rattrapage | non défini | non |
| retention | non défini | non |
Conclusion : pas de SLO prouvé, donc pas de justification d’activation.
5. Queue durable¶
L’infrastructure locale prouvée au 15 juillet 2026 contient au moins :
- MariaDB (
docker-compose.yml) - Redis (
docker-compose.yml) - conteneur worker (
ccx-platform-worker)
Elle ne prouve pas :
- RabbitMQ
- SQS
- autre broker managé
Comparaison :
| Option | Durabilité | Ops | Coût | Retry | DLQ | Ordering |
|---|---|---|---|---|---|---|
| table SQL dédiée | haute | faible | faible | oui | oui | FIFO par id |
| Redis Streams | moyenne | moyenne | faible à moyen | oui | custom | ordre du stream |
| RabbitMQ | haute | élevée | moyen | oui | oui | ordre par queue |
| SQS | haute | moyenne | externe | oui | oui | standard/FIFO |
| runtime queue feed actuel | n/a | existant | existant | spécifique feed | non pour cette chaîne | spécifique runtime |
Verdict :
- si la chaîne devait être rouverte plus tard, l’option minimale crédible est la table SQL dédiée ;
- non pas par préférence, mais parce qu’elle colle à la stack déjà prouvée, au coût, à la réversibilité et à l’existence d’un prototype
DatabaseQueuedéjà présent danssrc/.
6. Format d’événement¶
Le format persistant actuel prouvé par les tests EventEnvelopeCompatibilityTest et EventPayloadExtractorTest est :
event_type = FQCNpayload = propriétés publiques visibles
Ce format ne doit pas être changé en production dans BC-067A.
Pour une éventuelle réouverture future, l’envelope cible devrait être :
| Field | Required | Type | Purpose |
|---|---|---|---|
event_id |
oui | string/uuid | déduplication et traçabilité |
event_type |
oui | string | clé de routage métier stable |
schema_version |
oui | int | upcasting et compatibilité |
aggregate_id |
oui | string | partition / ordering |
occurred_at |
oui | datetime | chronologie métier |
payload |
oui | object | données métier |
metadata |
non | object | source, FQCN producteur, trace |
correlation_id |
non | string | traçabilité cross-step |
causation_id |
non | string | parent direct |
idempotency_key |
oui | string | anti-duplication côté consumer |
Point clé : le FQCN ne doit plus être le seul identifiant long terme si la chaîne est un jour activée.
7. Versioning¶
Stratégie recommandée si réouverture :
- compatibilité descendante obligatoire ;
- ajout de champ autorisé seulement en optionnel ;
- suppression/changement de champ via upcaster ;
schema_versionobligatoire ;event_typestable sémantiquement ;- FQCN relégué en métadonnée de compatibilité.
8. Idempotence¶
État actuel : absente pour la chaîne dormante.
Stratégie minimale requise avant activation :
- ledger
consumer + idempotency_key; - portée au moins par consumer de projection ;
- écriture atomique avec la projection lorsque possible ;
- replay sûr sans doubles effets.
9. Retry¶
État actuel : absent.
Stratégie minimale :
- retries bornés ;
- backoff exponentiel ou progressif ;
- seuil poison ;
- bascule DLQ après épuisement.
10. DLQ¶
État actuel : absente.
DLQ minimale :
- snapshot de l’envelope ;
- classe/message d’erreur ;
- nombre de tentatives ;
- dates premier/dernier échec ;
- vue d’exploitation simple.
11. Worker model¶
L’AsyncWorker actuel n’est qu’un helper mémoire testable :
- boucle bornée ;
- pas de durabilité ;
- pas de signal ops ;
- pas de backpressure ;
- pas d’isolation process réelle.
Si réouverture :
- commencer avec un worker unique et explicite ;
- claim transactionnel sur queue durable ;
- arrêt gracieux ;
- aucun couplage implicite au
queue-runner.phpcourant.
12. Transactions¶
Avant activation, il faudrait au minimum :
- claim transactionnel du job ;
- mutation projection + ledger idempotence atomiques si possible ;
- politique explicite quand l’ACK est autorisé.
État actuel : non implémenté.
13. Projection versioning¶
Avant activation, il faudrait :
projection_nameprojection_versionrebuild_generation
État actuel : non implémenté pour cette chaîne.
14. Observabilité¶
Absente aujourd’hui pour la chaîne dormante.
Minimum requis avant activation :
queue_depthlag_secondsprocessed_totalfailed_totalretry_totaldlq_totaloldest_event_ageworker_heartbeat
15. Sécurité¶
La chaîne ne doit pas être activable :
- depuis un endpoint public ;
- via hook WordPress caché ;
- via cron implicite ;
- via CLI ajouté sans BC dédiée.
16. Backpressure¶
Aujourd’hui : absente.
Minimum si réouverture :
- batch de dequeue borné ;
- retard contrôlé sur retry ;
- alerte d’âge de queue ;
- throttling producteur si besoin.
17. Plan de rollout¶
Si un jour la décision change :
- preuve besoin produit + SLO ;
- envelope versionnée + idempotence ;
- queue SQL dédiée + worker isolé ;
- shadow mode sans couplage public ;
- rollout à un seul worker ;
- gate explicite de rollback.
18. Runbook de rollback¶
Un rollback crédible devrait être :
- stop worker ;
- disable entrypoint ;
- quarantaine / purge contrôlée des jobs ;
- retour au runtime batch canonique ;
- rebuild explicite si nécessaire.
Aujourd’hui, ce runbook n’existe pas pour la chaîne dormante.
19. Coexistence avec le runtime actuel¶
Le runtime actuel reste la seule source canonique d’exécution opérationnelle.
Frontières à respecter :
- ne pas réutiliser implicitement
ccx_runtime_tick; - ne pas détourner
?ccx_feed_worker=1; - ne pas détourner
?ccx_feed_enqueue=1; - ne pas charger la chaîne dormante depuis les bootstraps plugin/runtime existants.
20. Candidats d’architecture¶
A — Do not activate¶
- garder la chaîne dormante ;
- conserver docs/tests ;
- aucun coût ops ;
- aucun risque runtime.
B — Minimal activation¶
- queue SQL dédiée ;
- worker batch contrôlé ;
- envelope versionnée ;
- idempotence ;
- observabilité minimale.
C’est l’option la plus crédible si un besoin réel apparaît.
C — Full event runtime¶
- runtime événementiel complet ;
- workers distribués ;
- projection/replay/monitoring avancés.
Cette option est surdimensionnée au vu des preuves actuelles.
21. Recommandation finale¶
DO_NOT_ACTIVATE
Pourquoi :
- aucun besoin produit prouvé ;
- aucune volumétrie justifiant un runtime événementiel dédié ;
- aucune pression SLO démontrée ;
- coût ops non justifié ;
- runtime batch canonique déjà en place ;
- la chaîne dormante n’a pas aujourd’hui les prérequis de sécurité opérationnelle.
22. Découpage futur recommandé¶
Si la décision devait être rouverte :
- BC-067B — preuve besoin produit + SLO
- BC-067C — envelope versionnée + idempotence
- BC-067D — queue SQL + worker isolé
- BC-067E — observabilité + rollout + rollback
Si aucun besoin n’apparaît, une autre trajectoire possible sera une BC de retrait progressif documenté, mais ce n’est pas l’objet de BC-067A.
23. Manifest et gates ajoutés¶
Cette tranche ajoute uniquement :
tests/Architecture/fixtures/bc067_runtime_activation_design.phptests/Architecture/RuntimeActivationDesignInventoryTest.phptests/Architecture/DormantRuntimeNoActivationTest.phptests/Architecture/RuntimeReadinessGapTest.php
Aucun code de production n’est modifié.
Conclusion¶
Au 15 juillet 2026, la meilleure décision reste :
- ne pas activer ;
- garder la chaîne dormante certifiée ;
- n’ouvrir une suite BC-067B/C/D/E que sur preuve produit + SLO + design opérationnel complet.
Note postérieure BC-067B¶
BC-067B a confirmé la seconde décision structurante :
DO_NOT_ACTIVATEreste inchangé ;- la chaîne dormante ne doit pas être conservée indéfiniment en l’état ;
- la décision de retraite associée est désormais
REDUCE_TO_REFERENCE_CORE; - aucune suppression n’est réalisée en BC-067B, mais une future BC-067C ou dédiée pourra retirer les placeholders et shells runtime après extraction/characterization suffisante.
Note postérieure BC-067C¶
BC-067C a mis en œuvre cette réduction :
- la décision
DO_NOT_ACTIVATEreste inchangée ; - le flow utile est désormais porté par un service synchrone de référence ;
- les shells/event/queue/worker dormants ont été retirés ;
- aucun entrypoint runtime n’a été ajouté.
Note postérieure BC-067D¶
BC-067D certifie l’état final :
- le runtime reste
not_activated; - le noyau final est
CatalogRankingEngine -> CatalogIntelligenceRebuildService -> CatalogIntelligenceEngine -> CatalogRepositoryInterface; - BC-067 est fermée sans réactivation runtime.