<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Darkwood Blog</title><link>http://darkwood.com</link><description>Venez affronter le monde et devenez celebre sur le site</description><copyright>Copyright 2005, tous droits reserves</copyright><language>en</language><pubDate>Mon, 09 Nov 2015 08:50:06 +0000</pubDate><atom:link href="https://darkwood.com/rss" rel="self" type="application/rss+xml"/><item><title>Website opened</title><pubDate>Wed, 05 Oct 2005 00:20:02 +0000</pubDate><description><![CDATA[Here it is, the website is now open.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Here it is, the website is now open.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/website-opened</link><guid>https://blog.darkwood.com/article/website-opened</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Daily fight</title><pubDate>Sat, 08 Oct 2005 19:52:37 +0000</pubDate><description><![CDATA[Face a new player every day.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Face a new player every day.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/daily-fight</link><guid>https://blog.darkwood.com/article/daily-fight</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>New ranklist</title><pubDate>Sat, 08 Oct 2005 21:44:49 +0000</pubDate><description><![CDATA[The rank of the players of the daily fight is now available in the menu.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The rank of the players of the daily fight is now available in the menu.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/new-ranklist</link><guid>https://blog.darkwood.com/article/new-ranklist</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Add-ons</title><pubDate>Sun, 09 Oct 2005 00:12:22 +0000</pubDate><description><![CDATA[You can now view the list of registered and the informations on the players.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can now view the list of registered and the informations on the players.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/add-ons</link><guid>https://blog.darkwood.com/article/add-ons</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Changements when die after a fight</title><pubDate>Sun, 09 Oct 2005 21:24:42 +0000</pubDate><description><![CDATA[If you die after a fight, you lose all your gold and 10 times the experience of the enemy who has defeated you.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>If you die after a fight, you lose all your gold and 10 times the experience of the enemy who has defeated you.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/changements-when-die-after-a-fight</link><guid>https://blog.darkwood.com/article/changements-when-die-after-a-fight</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Changements on swords</title><pubDate>Sun, 09 Oct 2005 22:18:35 +0000</pubDate><description><![CDATA[SPEED parameter swords has been suppressed
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>SPEED parameter swords has been suppressed</p>
]]></content:encoded><link>https://blog.darkwood.com/article/changements-on-swords</link><guid>https://blog.darkwood.com/article/changements-on-swords</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Lists too long</title><pubDate>Sat, 15 Oct 2005 23:53:09 +0000</pubDate><description><![CDATA[The display lists were too long.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The display lists were too long.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/lists-too-long</link><guid>https://blog.darkwood.com/article/lists-too-long</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Invite a friend on this website</title><pubDate>Sun, 16 Oct 2005 11:42:52 +0000</pubDate><description><![CDATA[You can invite a friend by mail.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can invite a friend by mail.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/invite-a-friend-on-this-website</link><guid>https://blog.darkwood.com/article/invite-a-friend-on-this-website</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>The news in RSS format</title><pubDate>Tue, 18 Oct 2005 21:20:17 +0000</pubDate><description><![CDATA[You can now find all the news via the RSS feed
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can now find all the news via the RSS feed</p>
]]></content:encoded><link>https://blog.darkwood.com/article/the-news-in-rss-format</link><guid>https://blog.darkwood.com/article/the-news-in-rss-format</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Counter added</title><pubDate>Sat, 22 Oct 2005 14:16:39 +0000</pubDate><description><![CDATA[You can now see the number of people who have gone on the main page of this site.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can now see the number of people who have gone on the main page of this site.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/counter-added</link><guid>https://blog.darkwood.com/article/counter-added</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Guestbook added</title><pubDate>Sun, 23 Oct 2005 23:28:40 +0000</pubDate><description><![CDATA[Post your messages on the guestbook.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Post your messages on the guestbook.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/guestbook-added</link><guid>https://blog.darkwood.com/article/guestbook-added</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Chat on the site</title><pubDate>Mon, 24 Oct 2005 22:05:44 +0000</pubDate><description><![CDATA[Chat on the site
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Chat on the site</p>
]]></content:encoded><link>https://blog.darkwood.com/article/chat-on-the-site</link><guid>https://blog.darkwood.com/article/chat-on-the-site</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Login and Password</title><pubDate>Wed, 26 Oct 2005 22:43:42 +0000</pubDate><description><![CDATA[The fields Login and Password may contain only the alpha-numeric characters (upper or lower case numbers and spaces).
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The fields Login and Password may contain only the alpha-numeric characters (upper or lower case numbers and spaces).</p>
]]></content:encoded><link>https://blog.darkwood.com/article/login-and-password</link><guid>https://blog.darkwood.com/article/login-and-password</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Record numbers of registered</title><pubDate>Fri, 28 Oct 2005 13:14:47 +0000</pubDate><description><![CDATA[Thank you for your participation!
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Thank you for your participation!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/record-numbers-of-registered</link><guid>https://blog.darkwood.com/article/record-numbers-of-registered</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Registration date</title><pubDate>Sat, 29 Oct 2005 03:04:45 +0000</pubDate><description><![CDATA[The date is visible in the information of a player.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The date is visible in the information of a player.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/registration-date</link><guid>https://blog.darkwood.com/article/registration-date</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Major update</title><pubDate>Sun, 30 Oct 2005 20:33:27 +0000</pubDate><description><![CDATA[This is a major update.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>This is a major update.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/major-update</link><guid>https://blog.darkwood.com/article/major-update</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Next update</title><pubDate>Fri, 04 Nov 2005 05:05:41 +0000</pubDate><description><![CDATA[The database has been fully reviewed, following the major upgrade.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The database has been fully reviewed, following the major upgrade.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/next-update</link><guid>https://blog.darkwood.com/article/next-update</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Disconnection during a fight</title><pubDate>Sun, 06 Nov 2005 14:04:35 +0000</pubDate><description><![CDATA[During a battle and if you disconnect, you will return exactly the same point you left off at the next reconnection.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>During a battle and if you disconnect, you will return exactly the same point you left off at the next reconnection.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/disconnection-during-a-fight</link><guid>https://blog.darkwood.com/article/disconnection-during-a-fight</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Changes when die</title><pubDate>Sun, 20 Nov 2005 14:43:24 +0000</pubDate><description><![CDATA[You lose 10 times the gold of the enemy who has defeated you.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You lose 10 times the gold of the enemy who has defeated you.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/changes-when-die</link><guid>https://blog.darkwood.com/article/changes-when-die</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Classes added</title><pubDate>Tue, 22 Nov 2005 23:08:35 +0000</pubDate><description><![CDATA[You can now choose your class.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can now choose your class.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/classes-added</link><guid>https://blog.darkwood.com/article/classes-added</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Viewing Classes</title><pubDate>Sat, 26 Nov 2005 16:40:03 +0000</pubDate><description><![CDATA[You can now view what is the class of any player.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can now view what is the class of any player.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/viewing-classes</link><guid>https://blog.darkwood.com/article/viewing-classes</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Look for Ruby!</title><pubDate>Mon, 05 Dec 2005 15:59:30 +0000</pubDate><description><![CDATA[You can add up to a maximum of 3 ruby on your sword in order to improve it.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>You can add up to a maximum of 3 ruby on your sword in order to improve it.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/look-for-ruby</link><guid>https://blog.darkwood.com/article/look-for-ruby</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>New Banner</title><pubDate>Fri, 09 Dec 2005 17:10:02 +0000</pubDate><description><![CDATA[Grimaldi Jordael participated in the creation of the new banner.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Grimaldi Jordael participated in the creation of the new banner.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/new-banner</link><guid>https://blog.darkwood.com/article/new-banner</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Record numbers of registered</title><pubDate>Sat, 27 May 2006 12:33:52 +0000</pubDate><description><![CDATA[Thank you for your participation!
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Thank you for your participation!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/record-numbers-of-registered-2</link><guid>https://blog.darkwood.com/article/record-numbers-of-registered-2</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Setting the website Standards</title><pubDate>Mon, 25 Sep 2006 23:27:51 +0000</pubDate><description><![CDATA[This site is compatible with the standards XHTML 1.1, CSS, RSS.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>This site is compatible with the standards XHTML 1.1, CSS, RSS.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/setting-the-website-standards</link><guid>https://blog.darkwood.com/article/setting-the-website-standards</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Creation of site map</title><pubDate>Sat, 30 Sep 2006 22:24:36 +0000</pubDate><description><![CDATA[The site map is now available in the menu.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The site map is now available in the menu.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/creation-of-site-map</link><guid>https://blog.darkwood.com/article/creation-of-site-map</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Darkwood&#039;s Statistics</title><pubDate>Fri, 19 Jan 2007 21:35:29 +0000</pubDate><description><![CDATA[Site statistics are available.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Site statistics are available.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-s-statistics</link><guid>https://blog.darkwood.com/article/darkwood-s-statistics</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Last fight</title><pubDate>Tue, 24 Jun 2008 21:48:26 +0000</pubDate><description><![CDATA[The last enemy you fought is stored in memory. You will find it the next time you come.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The last enemy you fought is stored in memory. You will find it the next time you come.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/last-fight</link><guid>https://blog.darkwood.com/article/last-fight</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Free killed Darkwood</title><pubDate>Sun, 31 Aug 2008 16:03:45 +0000</pubDate><description><![CDATA[Darkwood&#039;s site undergoes an interruption of several days by Free.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Darkwood's site undergoes an interruption of several days by Free.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/free-killed-darkwood</link><guid>https://blog.darkwood.com/article/free-killed-darkwood</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>25 new enemies</title><pubDate>Sun, 31 Aug 2008 19:32:11 +0000</pubDate><description><![CDATA[Skydean proposed 25 new enemies to fight.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Skydean proposed 25 new enemies to fight.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/25-new-enemies</link><guid>https://blog.darkwood.com/article/25-new-enemies</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Darkwood cleaned</title><pubDate>Thu, 25 Sep 2008 21:06:01 +0000</pubDate><description><![CDATA[The player who has not logged for at least 3 months and still remained at 0 for XP will be deleted!
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>The player who has not logged for at least 3 months and still remained at 0 for XP will be deleted!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-cleaned</link><guid>https://blog.darkwood.com/article/darkwood-cleaned</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Darkwood, new style, new life!</title><pubDate>Tue, 10 Aug 2010 00:00:00 +0000</pubDate><description><![CDATA[It is with joy that I announce the opening of the site www.darkwood.fr.
Darkwood comeback containing the original foundations of the previous site dating from 2005, while providing a new frame is more robust and flexible, which were made freshly new wait

C...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>It is with joy that I announce the opening of the site www.darkwood.fr.</p><p>Darkwood comeback containing the original foundations of the previous site dating from 2005, while providing a new frame is more robust and flexible, which were made freshly new wait</p><ul><li>Complete redesign of the site code.</li><li>New graphics.</li><li>Added support of multi-language.</li><li>New connection is allowed by a facebook account.</li></ul><p>Of course, the whole community and Darkwood migrating all your data remains intact. Competition is tough to reach the heights of glory. While the best man win, all shots are allowed.</p><p>I hope you enjoy your time on Darkwood!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-new-style-new-life</link><guid>https://blog.darkwood.com/article/darkwood-new-style-new-life</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Darkwood, Cross-Platform!</title><pubDate>Wed, 01 Dec 2010 00:00:00 +0000</pubDate><description><![CDATA[Darkwood has not finished invade you in your life, find your favorite game on the platform of your choice.

You&#039;re on the move, but you do lose your time in the trip.
Remember to bring your iPhone to keep you busy and move up the rankings.
You sit quietly i...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p>Darkwood has not finished invade you in your life, find your favorite game on the platform of your choice.</p><ul><li>You're on the move, but you do lose your time in the trip.<br />
Remember to bring your iPhone to keep you busy and move up the rankings.</li><li>You sit quietly in your living room, but you do not know what to do?<br />
Come out and play your iPad Darkwood.</li><li>You know every corner of your Mac.<br />
No, there is still Darkwood, the application for Macs will flex more than one.</li><li>You have good bars laughter with your friends on Facebook<br />
But have fun even more by winning the Darkwood application for Facebook.</li></ul><p>In short, no more excuses are allowed to not take advantage of Darkwood.<br />
So go for it, your competitors have not already begun!<br />
Hurry up, everything goes under the heading <a href="/extra">Extra</a>.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-cross-platform</link><guid>https://blog.darkwood.com/article/darkwood-cross-platform</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>Darkwood Symfony !</title><pubDate>Fri, 13 Nov 2015 21:06:03 +0000</pubDate><description><![CDATA[Today is a sad and good news.
Sad because Darkwood no longer uses Delia.
A little thought and tear for this house made framework and built with love.
However, it became difficult to maintain for a single person.
But happy because Darkwood now changing and c...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f53f920a365e503225024.png" /></p><p>Today is a sad and good news.</p><p>Sad because Darkwood no longer uses Delia.
A little thought and tear for this house made framework and built with love.
However, it became difficult to maintain for a single person.</p><p>But happy because Darkwood now changing and carbide in the framework <a href="http://symfony.com/">symfony</a> !<br />
Symfony is a PHP middleware recognized and maintained by a community of passionate people!
Thus Darkwood can benefit such as security updates, as well as dependencies (or vendors) used by the site.</p><p>Darkwood retains all previous features like multi-site and multi-language and the migration of its entire community.
But Darkwood can thus boast of openness to cross-domain!
With the creation of dedicated subdomains for the site, something he was not possible before!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-symfony</link><guid>https://blog.darkwood.com/article/darkwood-symfony</guid><enclosure url="http://darkwood.com/media/articles/5f53f920a365e503225024.png" /></item><item><title>Écrire ses notes et les synchroniser</title><pubDate>Fri, 11 Dec 2015 00:36:50 +0000</pubDate><description><![CDATA[Quand je travaille, j’aime beaucoup les utilitaires du quotidien qui améliorent la productivité. Aujourd’hui, je vous explique ma façon que j’utilise pour la prise de notes.
Prendre des notes n’est pas quelque chose d’anodin quand on se penche sur le sujet....]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/566a0770ddbf3.jpg" /></p><p>Quand je travaille, j’aime beaucoup les utilitaires du quotidien qui améliorent la productivité. Aujourd’hui, je vous explique ma façon que j’utilise pour la prise de notes.</p><p>Prendre des notes n’est pas quelque chose d’anodin quand on se penche sur le sujet. En général on va essayer de faire des choses assez rapidement, écrire l’essentiel. On ne souhaite pas trop se prendre la tête sûr comment on va la stocker. Numériser ses notes est intéressant, car on va vouloir faire des copier/coller si par exemple on note une adresse google maps, le texte numérique est vraiment réutilisable pour cela. Le classement, la catégorisation de la note doit aussi être rapide, au plus simple : un titre le contenu brut.</p><p>Ce que j’aime d’autant plus c’est de passer par des solutions open-source pour lesquelles je garde le contrôle sur mes données.</p><p>En effet l’open-source assure la transparence du logiciel que l’on utilise. Et passer par un service externe, on n’est jamais à l’abri de savoir si on ne va pas finir par devoir payer une version premium. D’autant plus qu’on ne sais pas ce que ces sociétés font de nos données.</p><p>Ainsi aujourd’hui, je vais vous parler du duo OwnCloud et nvALT qui fonctionnent pour moi très bien à ce jour.</p><h2>nvALT</h2><p>Un éditeur de prise de notes que j’adore, c’est le logiciel nvALT
On pourrait utiliser “Notes” pour Mac, “Notes”, c’est pour moi la prise de notes “poubelle” qui ne restent pas. Et nvALT a quelques autres particularités que j’aime bien.</p><ul><li>Déjà c’est un logiciel dédié à la prise de notes. Léger et rapide à lancer, la disposition des fenêtres (une seule en occurrence) met bien en valeur la zone où l’on prend ses notes.</li><li>La barre de recherche (accessible via raccourcis clavier Pomme+L, comme sur les navigateurs) permet de faire une recherche sur l’ensemble des contenus, mais aussi de créer un nouveau contenu que l’on nommera directement.</li><li>Il est possible de tagger sa note, c’est plutôt bien, comme cela on se créer des catégories de notes, sans avoir à les ranger spécifiquement dans des dossiers ainsi la recherche retournera des notes du même tag.</li><li>Il est Markdown friendly, habituez vous à la prise de note au format Markdown, au quotidien cela rend vos textes plus lisible et structurés. De plus, j’ai adapté la preview afin d’avoir un rendu joli de ma note au besoin. Pour cela il faut utiliser strapdown en ajoutant un fichier dont la procédure est décrite dans ce gist.</li><li>On peut activer le chiffrement afin que les données soient protégée si quelqu’un venait à avoir un accès à vos fichiers.</li></ul><h2>Owncloud</h2><p>A l’instar des gros services de synchronisation tels que <a href="https://www.dropbox.com/">dropbox</a> pour ne pas citer. <a href="https://owncloud.org/">OwnCloud</a> est vraiment pour moi mon espace de données sécurisé sur le net.</p><p>Bon bien sûr il vous faudra débourser un petit montant tous les mois pour avoir un serveur. Personnellement j’utilise <a href="https://www.gandi.net/">gandi</a> avec la formule <a href="https://www.gandi.net/hosting/simple?language=php&amp;db=mysql&amp;grid=A">simple hosting</a> qui n’est pas forcément très cher. Et c’est vous verrez que c’est aussi super de partager ses photos, sans clef USB à n’importe quel ami !</p><p>Si vous souhaitez la version gratuite, alors il vous faudra monter votre propre serveur via un <a href="https://www.raspberrypi.org/">Raspberry</a> par exemple. Mais bon cela a un coût d’entretien et est ce que vous n’avez jamais de panne ou débit limité chez vous est une autre question. Alors payer un peu sans avoir à s’investir dans les contraintes technique est plutôt un bon rapport qualité/prix.</p><p>L’installation sur le serveur, consiste pratiquement à dezipper l’archive sur le serveur, donc 3 fois rien !</p><p>Ensuite pour synchroniser nvALT, on choisit dans les préférences :</p><p>nvALT =&gt; Préférences … =&gt; Notes =&gt; Lire les notes du dossier</p><p>Que l’on fait pointer sur le dossier (ou sous dossier) du dossier de synchronisation de OwnCloud sur Mac.</p><p>That’s it ! Démarrer nvALT, prenez vos notes au bureau. rentrez chez vous, owncloud synchronise rapidement les fichiers. Ouvrez nvALT et continuer à écrire ce que vous avez commencé au travail. Et ainsi de suite et vice-versa.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/ecrire-ses-notes-et-les-synchroniser</link><guid>https://blog.darkwood.com/article/ecrire-ses-notes-et-les-synchroniser</guid><enclosure url="http://darkwood.com/media/articles/566a0770ddbf3.jpg" /></item><item><title>Le gardien du savoir</title><pubDate>Sun, 20 Dec 2015 18:42:13 +0000</pubDate><description><![CDATA[Voilà la release du gardien du savoir by Darkwood !
Oui, effectivement sur l&#039;AppleStore on peut aussi publier ses applications Mac avec un seul compte Member Center pour mac. Au paravent il fallait payer deux fois 80€ pour chaque stores : le Mac AppStore et...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a8221a0f23009164970.jpeg" /></p><p>Voilà la release du gardien du savoir by Darkwood !</p><p>Oui, effectivement sur l'AppleStore on peut aussi publier ses applications Mac avec un seul compte Member Center pour mac. Au paravent il fallait payer deux fois 80€ pour chaque stores : le Mac AppStore et l'iTunes Store. Donc pas vraiment envie de sortir le porte monnaie juste pour délivrer une application mac que l'on peut télécharger à la rigueur directement via un lien. Mais cela a changé, car pour la modique somme de 100€ (+25% au passage) il est inclus la publication iTunes Store, Mac App Store, AppleWatch, Safari. Donc pourquoi ne pas en profiter, puisque le gardien du savoir était déjà à l'origine cross plateforme !</p><p>C'est avec une grande joie que vous pouvez dès a présent télécharger Le Gardien du Savoir dans vos Stores respectifs, et cela ce passe ici :</p><p>iOS via iTunes Store: <a href="https://itunes.apple.com/us/app/lgs/id400268502?l=fr&amp;ls=1&amp;mt=8">https://itunes.apple.com/us/app/lgs/id400268502?l=fr&amp;ls=1&amp;mt=8</a><br />
Mac via App Store: <a href="https://itunes.apple.com/us/app/lgs/id1066865483?l=fr&amp;ls=1&amp;mt=12">https://itunes.apple.com/us/app/lgs/id1066865483?l=fr&amp;ls=1&amp;mt=12</a>
Le code source : <a href="https://github.com/matyo91/LGS">https://github.com/matyo91/LGS</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/le-gardien-du-savoir</link><guid>https://blog.darkwood.com/article/le-gardien-du-savoir</guid><enclosure url="http://darkwood.com/media/articles/5f6a8221a0f23009164970.jpeg" /></item><item><title>Neural Style</title><pubDate>Sun, 13 Mar 2016 17:39:35 +0000</pubDate><description><![CDATA[L&#039;intelligence artificielle, la robotique, ou les réseaux de neurones seront des technologies de demain.
Demain
Concrètement, on l&#039;a bien vu cette semaine, AlphaGo a battu Lee Sedol, l&#039;un des champions mondiaux du jeu de go.
On a franchi une barrière compar...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a82259cee1957704817.jpg" /></p><p>L'intelligence artificielle, la robotique, ou les réseaux de neurones seront des technologies de demain.</p><h2>Demain</h2><p>Concrètement, on l'a bien vu cette semaine, AlphaGo a battu Lee Sedol, l'un des champions mondiaux du jeu de go.
On a franchi une barrière comparé au match entre Kasparov et DeepBlue qui déduisait son meilleur coup à jouer parmi toutes les combinaisons possibles. Le jeu de Go amène tellement de possibilités qu'il n'est pas possible de toutes les énumérer. Ainsi on combine la reflexion de l'ordinateur avec des réseaux de neurones qui « apprennent les meilleurs coups à jouer ».</p><p>L'intelligence artificielle est aujourd'hui utilisée dans de nombreux domaines : <a href="http://www.wired.com/2012/04/can-an-algorithm-write-a-better-news-story-than-a-human-reporter/">génération de contenu textuels</a>, <a href="http://russ.glaue.org/proj/ai-music/">génération de musique</a>, mix d'images.</p><h2>Installation et utilisation de Neural Style</h2><p>Et aujourd'hui, je voulais présenter concrètement, comment avec votre ordi combiner deux images et observer le résultat. En effet, cet algorithme utilise les réseaux de neurones pour « apprendre » le style artistique qui se dégage d’une image. Et on utilise une autre image (la source), afin d’appliquer ce style sur celle ci.
Vous trouverez le projet sur Github <a href="https://github.com/jcjohnson/neural-style">https://github.com/jcjohnson/neural-style</a>.</p><p>Grâce à <a href="https://www.docker.com/">Docker</a>, nous allons virtualiser le projet sur notre ordinateur.</p><p>Dans un premier temps, il faut cloner le projet dans un dossier, et télécharger la base de test neurale</p><pre><code>$ git clone https://github.com/jcjohnson/neural-style.git
$ cd neural-style
$ bash models/download_models.sh
</code></pre><p>Ensuite, créer un nouvelle machine docker sous virtualbox, ici on s'assure d'avoir assez de mémoire, car l'appli est gourmande en ressources (4Go de mémoire recommandé) !</p><pre><code>$ docker-machine create -d virtualbox --virtualbox-memory &quot;8192&quot; neural-style
$ eval $(docker-machine env neural-style)
</code></pre><p>Puis on lance le conteneur Docker, ici on utilise l'image de docker Hub kwzr/neural-style et on lie 3 dossiers entre la VM et notre disque physique : les modèles que l'on vient de télécharger, les images sources que l'on veux process, ainsi que l'output (on veut voir le résultat!) :</p><pre><code>$ docker run -i -v $PWD/models:/root/torch/neural-style/models -v $PWD/images:/root/torch/neural-style/images -v $PWD/outputs:/root/torch/neural-style/outputs -t kwzr/neural-style /bin/bash
</code></pre><p>Donc là, nous sommes dans le shell du conteneur docker. Et on peut lancer la commande :</p><pre><code>$ th neural_style.lua -gpu -1 -style_image examples/inputs/starry_night.jpg -content_image examples/inputs/hoovertowernight.jpg -output_image outputs/test.png -image_size 256 -optimizer adam
</code></pre><p>Les options en résumé :</p><ul><li>L'option -gpu -1 est mise, car nous utilisons le CPU du conteneur à la place de la carte graphique.</li><li>Ensuite -style_image et -content_image sont les options des images que l'on souhaite mixer, respectivement le style à appliquer ainsi que l'image que l'on veux traiter.</li><li>L'option -output_image est le chemin d'enregistrement, on précise bien sûr dans le dossier outputs, car c'est le dossier que l'on a partagé entre la VM et notre disque physique.</li><li>Les options -image_size et -optimizer sont facultative, mais permettent au programme de s'executer plus ou moins rapidement mais avec une qualité variable.</li></ul><p>Voici un exemple de rendu :</p><p class="image"><img src="{{ asset('/blog/images/articles/neural-style/me.jpg') }}" alt="Image Source" height="100px" class="center" /></p><p class="image"><img src="{{ asset('/blog/images/articles/neural-style/model.jpg') }}" alt="Image Modèle" height="100px" class="center" /></p><p class="image"><img src="{{ asset('/blog/images/articles/neural-style/me_neural.jpg') }}" alt="Image Rendue" height="100px" class="center" /></p><p class="image"><img src="{{ asset('/blog/images/articles/neural-style/me_neural2.jpg') }}" alt="Image Rendue" height="100px" class="center" /></p><p class="image"><img src="{{ asset('/blog/images/articles/neural-style/me_neural3.jpg') }}" alt="Image Rendue" height="100px" class="center" /></p>
]]></content:encoded><link>https://blog.darkwood.com/article/neural-style</link><guid>https://blog.darkwood.com/article/neural-style</guid><enclosure url="http://darkwood.com/media/articles/5f6a82259cee1957704817.jpg" /></item><item><title>HTTPS !</title><pubDate>Sat, 09 Apr 2016 23:08:44 +0000</pubDate><description><![CDATA[Darkwood est maintenant secure et utilise le protocole https ! Cela veut dire que votre connexion est chiffrée de bout en bout lorsque vous naviguez sur le site. Cela prévient par exemple les attaques du type Man in the middle. Par ailleurs SSL devient un s...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a822907868529286329.png" /></p><p>Darkwood est maintenant secure et utilise le protocole https ! Cela veut dire que votre connexion est chiffrée de bout en bout lorsque vous naviguez sur le site. Cela prévient par exemple les attaques du type <a href="https://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man in the middle</a>. Par ailleurs SSL devient un standard, tous les acteurs majeurs du web l'on déjà adopté.</p><p>Un grand merci à <a href="https://letsencrypt.org/">Let’s Encrypt</a> qui a permit cet exploit. En effet, un certificat wildcard SSL coûte très cher (NULL€/an) pour un serveur particulier, alors que Let’s Encrypt le fait gratuitement!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/https</link><guid>https://blog.darkwood.com/article/https</guid><enclosure url="http://darkwood.com/media/articles/5f6a822907868529286329.png" /></item><item><title>Uniflow</title><pubDate>Mon, 11 Dec 2017 20:00:13 +0000</pubDate><description><![CDATA[
Today, je release la version actuelle de l&#039;outil que j&#039;ai commencé à développer depuis le 13 juin 2013, date du premier commit !
Mais effectivement, il y a eu pas mal de remaniements, car j&#039;avais aussi changé la version, le 19 octobre 2016 je changeais l&#039;i...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63867ed579eca555348518.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/q0nubN_NB-k" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p>Today, je release la version actuelle de l'outil que j'ai commencé à développer depuis le 13 juin 2013, date du premier commit !
Mais effectivement, il y a eu pas mal de remaniements, car j'avais aussi changé la version, le 19 octobre 2016 je changeais l'interface pour passer en full VueJS. Je pense aussi évoluer dans un nouveau temps vers React.</p><p>Bref, parmi tous mes projets dont pas mal sont passé dans la poubelle ou incomplets c'est peut-être celui là qui ressort ! Et peut être, c'est cool un jour de se focus sur un projet.
L'officialiser, c'est un peu dire : hey coucou je suis là. Pour le moment ce sera un outil très fermé car il n'y a pas de docs, juste le nécéssaire pour se connecter à l'interface.</p><p>Tout cela rejoins beaucoup d'idées après des réflexions à gauche et à droite.
Mais c'est quoi Uniflow ?!</p><p>Très bonne question, c'est un programme qui est sensé dans les grandes ligne faire le café. Oui, l'idée dernière cet outil est tout simplement : ne rien avoir à faire, plus rien du tout, plus rien faire de sa vie, il ne reste plus qu'a regarder ! Un rêve pour tous les développeurs flemmards.</p><p>L'idée est donc un mélange de flow-programming. Qu'est ce que le flow programming, c'est un concept où l'on conçoit des applications en empilant des boites noires. Chaque boites noire a une tache particulière comme par exemple donner l'heure ou bien faire l'addition de deux nombres. Et en liant les boites entre elles, on en découle une grosse boite noire qui devient un service.
Pensez à IFTT par exemple.</p><p>Du coup, j'ai eu pas mal d'inspiration durant ces années sur plusieurs sources tels quelque : Automator, No-Flow, Workflow pour iOS. L'idée dans tous ces systèmes c'est bien d'assembler des processus entre eux et ainsi de 'coder' en empilant des mini-fonctionnalités. Un peu comme les légos où l'on réalise un modèle en assemblant les briques de base.</p><p>Aussi, le nom donné c'est bien Uniflow : en effet je ne veux pas me retrouver à avoir à gérer un diagramme, car à la fin il devient pas compréhensible. Ce que j'ai remarqué, c'est qu'on aime bien lire les choses de manière linéaire de haut en bas un peu comme le flux d'actualité. Donc le mot Uni a son sens du fait que le flow ne va s'écrire que de haut en bas.</p><p>Un autre inspiration provient de mon éditeur de notes préféré : NvAlt.
L'idée est d'écrire des micro programme, mais de pouvoir les retrouver rapidement en les titrant, mais aussi en les tagant et rien de plus. Aussi, il n'y a pas bouton de sauvegarde, elle se fait en continue !</p><p>La brique de base, c'est le javascript, cela permet donc de créer n'importe quel programme. Autour de cette brique, j'ai mis d'autres qui permettent de saisir du texte, d'importer des images, de cocher des cases et sélectionner des valeurs. La dernière c'est de pouvoir utiliser SocketIO qui est utile pour communiquer en local avec le système de fichier et bien d'autres outils comme RoboJS ;-) en NodeJS.</p><p>La release aujourd'hui est seulement l'url publique de l'outil. Vous pouvez créer un compte et l'utiliser. Il y aura des modifications apportées dans le temps.</p><p>Evidement tout cela se passe ici : <a href="https://uniflow.darkwood.fr/">https://uniflow.darkwood.fr/</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/uniflow</link><guid>https://blog.darkwood.com/article/uniflow</guid><enclosure url="http://darkwood.com/media/articles/63867ed579eca555348518.png" /></item><item><title>Serverless starter</title><pubDate>Sat, 29 Aug 2020 12:32:23 +0000</pubDate><description><![CDATA[Il s&#039;en est passé des changements depuis j&#039;étais hébergé gratuitement sur les pages personnelles free. Le service est gratuit et le déploiement se fait via FTP. Mais c&#039;était un bon point de départ pour https://darkwood.fr lorsqu&#039;on a zéro budget pour un étu...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a822fe38e3890221429.png" /></p><p>Il s'en est passé des changements depuis j'étais hébergé gratuitement sur les <a href="http://ftpperso.free.fr">pages personnelles free</a>. Le service est gratuit et le déploiement se fait via FTP. Mais c'était un bon point de départ pour <a href="https://darkwood.fr">https://darkwood.fr</a> lorsqu'on a zéro budget pour un étudiant.
Ensuite le switch chez <a href="https://www.gandi.net">Gandi</a> pour avoir un hébergement dédié plus professionnel pour une offre d'une dizaines d'euros par mois dans les années 2013. Cependant, avec le temps, j'ai switché sur l'offre <a href="https://lightsail.aws.amazon.com">AWS Lightsail</a> pour réduire encore mes dépenses mensuelles et de pouvoir configurer un Debian dédié pour 3,5€ par mois. Cependant, il est possible de faire encore mieux !</p><p>Aujourd'hui la virtualisation, le développement de sites internets sous docker permet de conteneuriser les services. Il est possible de construire des solutions PAAS dites &quot;serverless&quot;. C'est à dire sans avoir à se soucier de la configuration des services, ces services sont facturés à l'usage. Cela peut être l'utilisation d'un espace disque dynamique via S3, mais aussi l'exécution de code PHP ou NodeJS via Amazon Lambda. Ou encore de déploiement de CloudFront faisant office de CDN, ce qui permet de créer un site statique avec S3 ou lier à un site dynamique avec Lambda.</p><p>Pour comprendre comment tout cela fonctionne, je vous recommande la formation de Matthieu Napoli : <a href="https://gumroad.com/l/dLXqt">Serverless Visually Explained</a> qui explique visuellement comment fonctionnent les services AWS et comment les utiliser.
<a href="https://github.com/Nemo64/serverless-symfony">Serverless Symfony</a> a aussi été une bonne inspiration pour finaliser certains points techniques, je recommande cette solution si vous souhaitez utiliser purement Symfony.</p><p>Grâce à ces différentes sources, j'ai pu configurer via le framework serverless mon propre <strong>starter <a href="https://github.com/darkwood-fr/serverless-starter">https://github.com/darkwood-fr/serverless-starter</a></strong> qui permet d'avoir un espace avec deux environnements déploiement (production et pré-production) via des commandes Makefile, un site statique et une api liée a ce site.</p><p>Je verrais à l'avenir pour améliorer au besoin ce starter, comme par exemple avoir le choix d'utiliser une Api en NodeJS ou Symfony, un frontend en VueJS ou Gatsby, de configurer un déploiement automatique via des actions Github, et pourquoi pas avec l'aide de <a href="https://seed.run/">Seed</a> et <a href="https://www.netlify.com/">Netlify</a>. <a href="https://serverless-stack.com">Serverless Stack</a> est un bon guide complémentaire par rapport à ce projet.</p><p>Bien sûr, je suis ouvert à toute contribution sur le starter.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/serverless-starter</link><guid>https://blog.darkwood.com/article/serverless-starter</guid><enclosure url="http://darkwood.com/media/articles/5f6a822fe38e3890221429.png" /></item><item><title>Darkwood Opensource</title><pubDate>Sun, 06 Sep 2020 17:32:48 +0000</pubDate><description><![CDATA[Aujourd&#039;hui, je release Darkwood en open source. Pourquoi ? Pour rien en fait, juste pour rigoler. Peut être que vous avez toujours rêvé de faire votre propre site internet et vous souhaitez un exemple de site et voir comment celui-ci fonctionne en producti...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a823328294764390471.jpg" /></p><p>Aujourd'hui, je release Darkwood en open source. Pourquoi ? Pour rien en fait, juste pour rigoler. Peut être que vous avez toujours rêvé de faire votre propre site internet et vous souhaitez un exemple de site et voir comment celui-ci fonctionne en production. On ne sait jamais, peut être quelqu'un serait interessé à contribuer. Mais aussi, moi même à apprendre des autres et des bonnes pratiques.</p><p>N'empêche, il m'a tout de même fallu une semaine de dev complète pour migrer le site de Symfony 3.4 à Symfony 5.1, la structure de ficher change, ne plus utiliser FOS UserBundle, les annotations, migration de bootstrap 3 à bootstrap 4.5 et j'en passe.</p><p>Alors profitez en, consultez le depot Github : <strong><a href="https://github.com/darkwood-fr/darkwood-fr">https://github.com/darkwood-fr/darkwood-fr</a></strong></p><p>Happy coding time.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-opensource</link><guid>https://blog.darkwood.com/article/darkwood-opensource</guid><enclosure url="http://darkwood.com/media/articles/5f6a823328294764390471.jpg" /></item><item><title>Joplin</title><pubDate>Mon, 07 Sep 2020 16:48:04 +0000</pubDate><description><![CDATA[Cet article fait suite à mon article précédent sur la prise de note via NVAlt.
Adieu NVAlt, bonjour Joplin !
Joplin
Cela faisait un moment que NVAlt n&#039;étais plus mis à jour. J&#039;ai fais une petite prospection, afin de voir s&#039;il y avait autre chose sur le net....]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a82364c16e661809038.png" /></p><p>Cet article fait suite à mon article précédent sur la prise de note via NVAlt.</p><p>Adieu <a href="https://brettterpstra.com/projects/nvalt/">NVAlt</a>, bonjour <a href="https://joplinapp.org">Joplin</a> !</p><h2>Joplin</h2><p>Cela faisait un moment que NVAlt n'étais plus mis à jour. J'ai fais une petite prospection, afin de voir s'il y avait autre chose sur le net. Et j'ai effectivement trouvé Joplin après une prospection sur Github.</p><p>Il y a quelques avantages par rapport à NVAlt :</p><ul><li>Les notes peuvent se ranger dans une arborescence de dossier, en plus des tags déjà existant dans NVAlt. Cela m'a permis de mieux sectionner mes différents espaces de notes.</li><li>La possibilité d'utiliser une synchronisation directement via WebDAV avec Nextcloud. Avant cette synchronisation était effectivement faite car j'exportais mon dossier de travail NVAlt via le système de fichier lié Nextcloud Desktop. Maintenant que cette synchronisation est native, cela permet aussi d'avoir beaucoup moins de conflits.</li><li>L'application mobile est disponible sur iOS ou Android. Très pratique, car cela permet d'éditer simplement mes notes, alors que précédemment, il fallait utiliser l'éditeur de Nextcloud.</li><li>La possibilité de synchroniser des images, mais je n'ai pas eu l'occasion de l'utiliser. Je préfère encore taper des textes pur.</li><li>J'ai installé l'extension <a href="https://joplinapp.org/clipper/">clipper</a>, mais j'ai pas vraiment pris l'habitude de l'utiliser, s'il pouvait y avoir un usage iso avec le mobile cela serait cool aussi pour uniformiser les process.</li></ul><p>Par contre :</p><ul><li>Je trouve qu'il manque un petit quelque chose pour que l'interface soit légèrement plus sexy (exemple : <a href="https://github.com/notable/notable">Notable</a> qui utilise des emoji et a un theme plus clean en dark et light). Je trouve la bare de recherche moins visible, je préférais quand elle prenais toute la largeur. Et plus légère beaucoup de boutons en haut, différents niveau de toggle. Mais l'interface reste elle bien fonctionnelle.</li><li>Il faut s'habituer à la nouvelle recherche : la documentation est disponible <a href="https://joplinapp.org/#searching">https://joplinapp.org/#searching</a>. Sur NVAlt, j'avais effectivement l'habitude de faire une recherche full texte, ici, il faut commencer sa recherche par '/' pour faire la même chose, car par défaut, c'est une recherche par mot.</li><li>Sur NVAlt, on pouvais créer des notes directement en appuyant sur la touche entrée via la recherche, pour Joplin il faut créer sa nouvelle note avec un bouton ! Ca c'était une feature cool de NVAlt que j'aimais bien !</li></ul><h2>Nextcloud</h2><p>Oui, avant je disais utiliser <a href="https://owncloud.com/">Owncloud</a>, mais un fork du projet a été fait sous le nom de <a href="https://nextcloud.com/">Nextcloud</a>. J'utilise Nextcloud depuis.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/joplin</link><guid>https://blog.darkwood.com/article/joplin</guid><enclosure url="http://darkwood.com/media/articles/5f6a82364c16e661809038.png" /></item><item><title>Participer à une Game Jam</title><pubDate>Mon, 21 Sep 2020 00:00:53 +0000</pubDate><description><![CDATA[J&#039;ai participé à une Game Jam !
Avant tout de chose, le lien de la jam : https://itch.io/jam/godot-wild-jam-25/rate/763282.
Game Jam, qu&#039;est-ce que c&#039;est ?
Peut-être que vous avez déjà dû entendre le terme « Game Jam ». Le principe est le même qu’un hackato...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f6a82397b0f4910958534.png" /></p><h1>J'ai participé à une Game Jam !</h1><p>Avant tout de chose, le lien de la jam : <a href="https://itch.io/jam/godot-wild-jam-25/rate/763282">https://itch.io/jam/godot-wild-jam-25/rate/763282</a>.</p><h2>Game Jam, qu'est-ce que c'est ?</h2><p>Peut-être que vous avez déjà dû entendre le terme « Game Jam ». Le principe est le même qu’un hackaton qui peut être de l'ordre de 1 heure à un mois par exemple, mais avec un objectif différent. Des développeurs créent un jeu, avec un thème donné, à partir de zéro, seul ou en équipe, avec des personnes qu’ils ne connaissent pas forcément. Le but est simplement de créer pour le plaisir et d’expérimenter des concepts de jeux. Les Game Jams sont des événements gratuits organisés par des associations et accessibles à tous.</p><h2>Comment trouver une Jam ?</h2><p>Mon attrait pour avoir rejoint une Game Jam est à la fois par plaisir, découverte, mais aussi initiation et apprentissage. Mais cela s'est fait aussi par rapport aux choix technique vers lesquels je souhaite m'orienter. Avant d'arriver dans le milieu du développement web, j'avais déjà eu une expérience passée dans le monde du jeu vidéo. J'avais fait tout un tas de projets par mes études ou dans le cadre de mon temps personnel que vous pouvez consulter sur <a href="https://apps.darkwood.fr/">https://apps.darkwood.fr</a>. Mon stage de dernière année a été de travailler pour la réalisation d'un moteur de jeu avec les équipes de <a href="http://www.kylotonn.com">http://www.kylotonn.com</a> qui avait bien voulu de moi ! Mon <a href="https://me.darkwood.fr/me/images/cv/rapport-stage-2008.pdf">rapport de stage</a> à ce sujet est consultable en ligne. Gamer, les jeux vidéo m'ont beaucoup attiré. Mais aussi j'ai pas mal joué à différents jeux de plateaux, et <a href="https://boardgamegeek.com/">Board Game Geek</a> est une référence en la matière. D'ailleurs, je trouve intéressant le pont entre les jeux vidéo et les jeux de plateaux, la frontière n'est pas si éloignée.</p><p>Alors oui, il y a beaucoup de plateforme aujourd'hui qui propose de télécharger des jeux vidéo, cela peut aller des triples A (les jeux créés par les acteurs majeurs), mais aussi des acteurs indépendants : les <em>indies</em> couramment appelé. Oui il est possible pour une seule personne de créer un jeu et de le vendre. Je pense alors aux plateformes <a href="https://www.blizzard.com/">Blizzard</a> (mon battle ID : Matyo#2285) mais aussi <a href="https://store.steampowered.com/">Steam</a> (mon profil steam <a href="https://steamcommunity.com/id/matyo91/">matyo91</a>). Cependant, ces plateformes sont principalement dédiées à la vente de jeu et de créer une communauté de joueurs autour des jeux. Il existe d'autres plateformes qui sont dédiées à l'accompagnement et la création de jeux pour mieux se lancer quand on démarre de zéro. Le portail <a href="https://itch.io/">Itch</a> est réputé, c'est celle que j'ai choisi d'utiliser, car elle offre la possibilité de rejoindre des Games Jam. En effet, Itch est beaucoup plus orienté pour les créateurs de jeux indépendants, car elle offre un panel plus large concernant les choix de vente de son jeu, mais la communauté autour de ce milieu est aussi portée sur l'entraide et la création de jeu. Il existe expressément un onglet Jam sur le site. Et en matière de panel, ce n'est pas seulement une Jam, mais plusieurs dizaines qui sont ouvertes en parallèle.</p><p>J'ai rejoint la jam <a href="https://itch.io/jam/godot-wild-jam-25">https://itch.io/jam/godot-wild-jam-25</a> pour laquelle nous avons une semaine du 12 au 21 septembre 2020 pour concevoir et livrer un jeu suivant le thème imposé.</p><h2>Alors, pourquoi j'ai rejoint une Game Jam ?</h2><h3>Seul on va vite, à plusieurs on va plus loin</h3><p>Pour mon cas, je souhaite faire part à une Game Jam afin de monter rapidement en compétences à l'aide d'un groupe de personnes, sans avoir de pression autre que la death line, c'est-à-dire le rendu du projet. Dans un tel groupe, on peut rencontrer différents profils de personnes, de l'initié au plus expérimenté. Au final, tous les membres du groupe sont libres d'apporter leur contribution à leur échelle de connaissance, de disponibilité. Les échanges sont horizontaux, il n'y a pas de faire valoir ou d'allégeance a attribuer à telle ou telle personne. Dans une Jam, chacun peut donner son avis et prendre des décisions sur l'avancée du projet. Les Game Jam sont centrés sur le fair-play et l'altruisme, c'est une force qui en ressort. L'objectif qui prime est bien sûr la death line à respecter pour soumettre le projet, mais l'envie de participer et le fun sont là.</p><h3>La technique</h3><p>Au-delà de l'aspect humain, j'ai aussi choisi une Game Jam pour son aspect technique. Mais pas n'importe quelle Game Jam, souvenez-vous, sur Itch, il existe une dizaine de Game Jam en simultané. J'ai choisi de rejoindre la Jam <a href="https://godotwildjam.com">https://godotwildjam.com</a> qui n'autorise que des Jam centrés sur l'utilisation du moteur de jeu : <a href="https://godotengine.org/">Godot</a>. A moins de vouloir réinventer la roue et repartir de zéro, il existe plusieurs moteurs de jeux sur le marché qui permettent de se focaliser sur la conception de jeux. Après prospection, j'ai trouvé trois acteurs majeurs : <a href="https://unity.com/">Unity</a>, <a href="https://unity.com/">Unreal Engine</a> et <a href="https://godotengine.org/">Godot</a>.</p><p>Je n'entrerais pas spécialement dans les détails et d'autres articles sur Internet le feront mieux qu'ici, mais Unity et Unreal Engine sont de gros acteurs sur le marché et se positionnent différemment en matière de modèle économique, c'est-à-dire le coût qu'il faudra payer pour utiliser la licence du moteur. L'avantage d'utiliser un de ces deux moteurs sera d'accéder à des solutions professionnelles en matière de graphique, de distribution, de performance, de gagner du temps sur la conception en utilisant un vaste panel d'assets mis à disposition des développeurs. J'ai choisi Godot engine essentiellement car il est libre de droits et open-source (Licence MIT) : la transparence du moteur de jeu et aussi il n'y a pas de licence à payer pour concevoir un jeu, léger : une dizaine de mégas à télécharger et l'interface s'en ressent épurée et réactive.</p><h2>Comment cela s'est passé ?</h2><p>On vient de soumettre le projet <a href="https://github.com/btzr-io/gwj-25">https://github.com/btzr-io/gwj-25</a> ! Et je suis très fier de mon équipe !</p><p>Pour y arriver, j'ai d'abord rejoint le discord de la Jam <a href="https://discord.gg/eUYMFqT">https://discord.gg/eUYMFqT</a>. Après m'être présenté sur le channel d'introduction aux nouveaux arrivant, j'ai demandé à rejoindre une team dans le channel &quot;team-up&quot;. J'ai directement contacté des personnes qui s'étaient déjà manifestées pour demander à rejoindre une team. Et c'est partit, j'ai rejoin un discord privé de notre groupe fraîchement formé. Les discussions de départ étaient essentiellement au départ de se présenter et quelle idée de jeu nous souhaitons créer. Ensuite la création d'un <a href="https://github.com/btzr-io/gwj-25">dépôt Github</a> pour centraliser le développement. Les taches ont été découpéees via l'utilisation d'Issues et chaque participant est invité à faire des Pull Request afin de contribuer au développement du jeu.</p><p>Cela a été l'occasion pour ma part d'avoir une meilleure utilisation du moteur Godot. Le moteur utilise le concept de scène, nous avons mis en place des mécaniques communes de tout jeu de plateforme tel que les collisions, le saut, la prise d'objet, l'utilisation de la caméra, les menus, les gestionnaires de scène les signaux, l'export du jeu sur différentes plateformes.</p><h2>Notez le jeu !</h2><p>La phase de soumission du jeu viens de se terminer. C'est maintenant la phase d'évaluation du jeu, pour cela, rendez-vous sur <a href="https://itch.io/jam/godot-wild-jam-25/rate/763282">https://itch.io/jam/godot-wild-jam-25/rate/763282</a>.</p><p>Et n'oubliez pas d'évaluer le jeu qui ainsi que de donner vos commentaires ! Les résultats des votes sont dans 3 jours.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/participer-a-une-game-jam</link><guid>https://blog.darkwood.com/article/participer-a-une-game-jam</guid><enclosure url="http://darkwood.com/media/articles/5f6a82397b0f4910958534.png" /></item><item><title>Raccourci pour lire des vidéos 2X</title><pubDate>Sun, 11 Oct 2020 13:54:48 +0000</pubDate><description><![CDATA[Ce qui va suivre est un retour d&#039;expérience sur le thème de l&#039;apprentissage, une manière de consommer l&#039;information, en et en particulier les vidéos. J&#039;ai besoin de faire une mise en contexte pour parler enfin de comment utiliser les raccourcis clavier. J&#039;a...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5f830f6f8e3fc432336848.jpg" /></p><p>Ce qui va suivre est un retour d'expérience sur le thème de l'apprentissage, une manière de consommer l'information, en et en particulier les vidéos. J'ai besoin de faire une mise en contexte pour parler enfin de comment utiliser les raccourcis clavier. J'ai partage ici un userscript adapté à cet article.</p><p>Lorsque l'on souhaite se former, suivre l'actualité ou s'intéresser a des sujets par altruisme, il sera toujours plus efficace de lire du texte brut. Si l'on souhaite approfondir un sujet précis, lire un livre sera beaucoup plus adapté, car l'auteur aura fait en amont un travail pour retranscrire l'information. Pour comprendre rapidement une application, le meilleur est de se référer à la documentation.</p><p>Il existe un moyen alternatif a la lecture, la vidéo. Regarder une vidéo n'aura pas le même impact que de lire du texte. Lire du texte permet de faire travailler son imagination, alors qu'une vidéo évite ce travail. La transmission de l'information se rapproche d'une conversation, sauf que l'on est passif.</p><p>Je suis un gros consommateur de vidéos YouTube. Je me suis habitué a consommer l'information par la vidéo, car c'est un format qui me demande moins de concentration que la lecture. L'aspect passif est reposant, un peu comme si l'on allait voir un film au cinéma. Il est aussi possible de regarder une vidéo tout en travaillant sur autre chose à côté. Il m'arrive aussi de simplement avoir envie d'écouter le son de la vidéo, car l'image n'est qu'un support (exemple : les vidéos TedX sur le développement personnel).</p><p>Dans les vidéos, l'information est transmi de manière naturelle, il est possible d'accélérer les vidéos. En général je mets la lecture au maximum en 2x. Pourquoi ? Parce que dans une vidéo, l'information ne sera systématiquement condensé dans la durée, il peut y avoir des passages de blanc ou des mises en situation qui ne sont pas difficile a comprendre en accéléré. En pratiquant régulièrement, je me suis habitué a regarder des vidéos en accéléré, ça devient naturel et c'est simplement une question d'habitude. Cela me permet de gagner du temps et consommer plus d'informations.</p><p>Seulement voilà, certains passages clefs dans une vidéo nécessitent de revenir sur une lecture 1x car il y a trop d'informations et c'est difficile de comprendre avec une lecture 2x.</p><p>Alors c'est très simple, sur Youtube il existe un raccourci clavier '&gt;' pour accélérer la vidéo. Et '&lt;' pour ralentir la vidéo.</p><p>Pour des raisons que j'ignore, je ne suis jamais arrivé a faire fonctionner le raccourci '&lt;' clavier qui permet de ralentir la vidéo, je suis sur Mac OS avec un clavier AZERTY. J'imagine qu'il y a un bug pour cette configuration, mais ce bug n'existe pas pour les claviers QWERTY.</p><p><strong>Voici l'url du script : <a href="https://gist.github.com/matyo91/faff107e0017229e5e93360b050bd385">https://gist.github.com/matyo91/faff107e0017229e5e93360b050bd385</a></strong></p><p>J'ai cherché partout sur les forums, mais je n'ai jamais trouvé une solution a ce problème. C'est la raison pour laquelle je vous partage ici un userscript que j'ai écrit qui règle ce problème. Il permet de systématiquement mettre la vidéo en 1x dès que l'on appuie sur '&lt;'. Si vous êtes intéressé par ce sujet, je serai intéressé d'avoir vos retours !</p>
]]></content:encoded><link>https://blog.darkwood.com/article/raccourci-pour-lire-des-videos-2x</link><guid>https://blog.darkwood.com/article/raccourci-pour-lire-des-videos-2x</guid><enclosure url="http://darkwood.com/media/articles/5f830f6f8e3fc432336848.jpg" /></item><item><title>Organiser son dossier de musique pour DJ sur le Cloud</title><pubDate>Tue, 03 Nov 2020 12:10:16 +0000</pubDate><description><![CDATA[Voici un petit tuto, pour lequel j&#039;ai mis pas mal de temps à réfléchir. En effet, si vous êtes intéressé par le monde de la musique en général, vous avez surement envie de garder tous vos morceaux le temps.
Par le passé, j&#039;utilisais iTunes (aujourd&#039;hui Musi...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5fa149de3b7e4560935740.jpg" /></p><p>Voici un petit tuto, pour lequel j'ai mis pas mal de temps à réfléchir. En effet, si vous êtes intéressé par le monde de la musique en général, vous avez surement envie de garder tous vos morceaux le temps.</p><p>Par le passé, j'utilisais iTunes (aujourd'hui Musique pour MacOS) qui me permettait de tenir ma bibliothèque de musique organisée. Cela s'avère pratique, car l'interface à elle seule permet d'ordonner vos morceaux suivant différentes données comme l'année, l'artiste, l'album. Cependant, iTunes range les morceaux dans une arborescence de fichiers physiques qui est propre à son algorithme. Pour rappel Itunes est la propriété d'Apple et il n'est pas possible de connaître à l'avance la politique appliquée à cet algorithme suivant les années.</p><p>Et pourquoi cela est-il important ? Parce qu'en tant que DJ, il faut toujours avoir sur soi ses morceaux. En l'occurrence, j'utilise le logiciel <a href="https://rekordbox.com">RekordBox</a> (les platines Pioneer) et si un fichier venait à être déplacé ou renommé pour une raison ou une autre, Rekordbox perd la référence et vous ne pouvez plus vous fier aux morceaux listés dans votre bibliothèque musicale.</p><p>Pour ma part je ne souhaite pas non plus dépendre du système de classement de Rekordbox, car le problème est le même : que ce passe-t-il si vous changez de logiciel de mixage ?</p><p>Pour de dépendre d'aucun logiciel, et organiser ses morceaux de manière pérenne, il suffit à se définir son propre système de classement. Pour ma part, j'ai choisi de classer mes morceaux selon une arborescence propre {artiste}/{album}/{titre}</p><p>Afin de classer tous les morceaux de manière automatique, j'utilise le logiciel <a href="https://picard.musicbrainz.org">MusicBrainz Picard</a> disponible en open source. Il permet de scaner un dossier contenant des musiques audio. Dans les préférences, j'ai ainsi spécifié la section : &quot;Nommage des fichiers&quot;. Il faut cocher la case &quot;Renommer les fichiers à l'enregistrement&quot; et inscrire &quot;%artist%/%album%/%title%&quot; dans la section dédiée au scripting.</p><p>Ce sont actuellement encore des sujets en cours, étant donné qu'un <a href="https://github.com/EvanPurkhiser/tune-manager">dépôt github</a> fait aussi ce travail automatique. Je regarde actuellement pour contribuer dessus. Ma bibliothèque est actuellement sur le Cloud en étant acquéreur de 2To avec <a href="https://pcloud.com">pcloud.com</a>, ce serait interesssant et plus propre d'effectuer ce renommage en utilisant directement l'API proposé par pCloud, plutôt que de faire ces changements via pCloud Drive.</p><p>La finalité est donc d'avoir une bibliothèque organisée sur le Cloud. De cette manière, il est techniquement possible d'accéder et d'utiliser sa bibliothèque musicale, sans être dépendant d'un logiciel de musique.</p><p>Qu'en pensez-vous ?</p>
]]></content:encoded><link>https://blog.darkwood.com/article/organiser-son-dossier-de-musique-pour-dj-sur-le-cloud</link><guid>https://blog.darkwood.com/article/organiser-son-dossier-de-musique-pour-dj-sur-le-cloud</guid><enclosure url="http://darkwood.com/media/articles/5fa149de3b7e4560935740.jpg" /></item><item><title>SymfonyWorld, quoi de neuf ?</title><pubDate>Sat, 05 Dec 2020 17:56:51 +0000</pubDate><description><![CDATA[Cette semaine, il y a eu un séisme dans l&#039;univers PHP et Symfony ! Découvrons cela ensemble.
Avertissement : Cet article se base uniquement sur les annonces publiques qui ont été faites sur le compte Twitter #SymfonyWorld
Libérer votre potentiel avec Javasc...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5fcf6a50a8766161418367.jpg" /></p><p>Cette semaine, il y a eu un séisme dans l'univers PHP et Symfony ! Découvrons cela ensemble.</p><p><em>Avertissement : Cet article se base uniquement sur les annonces publiques qui ont été faites sur le compte Twitter <a href="https://twitter.com/search?q=%23SymfonyWorld">#SymfonyWorld</a></em></p><h2>Libérer votre potentiel avec Javascript</h2><p>C'est la mise à l'honneur de Symfony UX qui permet d'être <em>framework agnostique</em> quand aux choix que vous allez faire pour intégrer vos contenus dynamiques sur vos sites.</p><p><a href="https://speakerdeck.com/tgalopin/symfony-ux-a-new-javascript-ecosystem-for-symfony">https://speakerdeck.com/tgalopin/symfony-ux-a-new-javascript-ecosystem-for-symfony</a></p><h2>PHP8</h2><p>Où comment un langage passe à un stade mature.<br />
Compilation juste à temps, Les attributs, constructeurs à variable, arguments només, les types d'union et mixé, le match opérateur, l'opérateur null &quot;safe&quot;.</p><p><a href="https://www2.slideshare.net/nikita_ppv/whats-new-in-php-80-239762987">https://www2.slideshare.net/nikita_ppv/whats-new-in-php-80-239762987</a></p><h2>Api-platform 2.6, Next.js and Nuxt.js app generator, Caddy server, ActivityPub</h2><p>Api-platform continue la conquête de l'étique à l'usage du web.</p><p><a href="https://dunglas.fr/2020/12/api-platform-2-6-php-8-support-next-js-and-nuxt-js-app-generator-caddy-server-activitypub-and-much-more/">https://dunglas.fr/2020/12/api-platform-2-6-php-8-support-next-js-and-nuxt-js-app-generator-caddy-server-activitypub-and-much-more/</a></p><h2>La cryptographie et la course au décryptage</h2><p>SHA1, AES, DES3, Bob et Alice, puissance de calcul, probabilités, tous ces mots vous sont familier ?</p><p><a href="https://speakerdeck.com/gregoirehebert/with-symfony-4-dot-4-your-secrets-will-be-well-kept">https://speakerdeck.com/gregoirehebert/with-symfony-4-dot-4-your-secrets-will-be-well-kept</a></p><h2>La sécurité dans Symfony</h2><p>Approfondir la sécurité dans Symfony.</p><p><a href="https://speakerdeck.com/weaverryan/modern-security-with-symfonys-shiny-new-security-component">https://speakerdeck.com/weaverryan/modern-security-with-symfonys-shiny-new-security-component</a></p><h2>Composer 2.0</h2><p>L'outil qui vous aide au quotidien pour maintenir vos bibliothèques à jour.</p><p><a href="https://www.naderman.de/slippy/slides/2020-12-04-SymfonyWorld-Online-2020-Composer-2.pdf">https://www.naderman.de/slippy/slides/2020-12-04-SymfonyWorld-Online-2020-Composer-2.pdf</a></p><h2>Elastic Search</h2><p>On parle bien de production et conseils.</p><p><a href="https://jolicode.github.io/elasticsearch-php-conf/slides/symfonyworld2020.html">https://jolicode.github.io/elasticsearch-php-conf/slides/symfonyworld2020.html</a></p><h2>Le serialiseur</h2><p>Le composant Serialiser dévoile ses secrets.</p><p><a href="https://speakerdeck.com/dbrumann/serializer-demystified">https://speakerdeck.com/dbrumann/serializer-demystified</a></p><h2>Les semaphores</h2><p>Vous connaissez les threads linux ? Et bien découvrez ici comment gérer les sémaphores en PHP !</p><p><a href="http://slides.com/jderusse/lock-semaphore-sfworld">http://slides.com/jderusse/lock-semaphore-sfworld</a></p><h2>0.1 + 0.2 != 0.3</h2><p>Cela est étonnant, mais c'est pourtant vrai !</p><p><a href="https://speakerdeck.com/bitone/why-0-dot-1-plus-0-dot-2-equals-0-dot-3-or-the-mysterious-world-of-floating-point-numbers">https://speakerdeck.com/bitone/why-0-dot-1-plus-0-dot-2-equals-0-dot-3-or-the-mysterious-world-of-floating-point-numbers</a></p><h2>Internationalizer vos projets</h2><p>Les bonnes pratiques à mettre en place pour internationaliser une application Symfony.</p><p><a href="https://speakerdeck.com/welcomattic/internationalize-your-symfony-application-the-right-way">https://speakerdeck.com/welcomattic/internationalize-your-symfony-application-the-right-way</a></p><h2>HTTP2</h2><p>Et promouvoir son utilisation.</p><p><a href="https://speakerdeck.com/brunohsouza/the-modern-and-fast-httpclient">https://speakerdeck.com/brunohsouza/the-modern-and-fast-httpclient</a></p><h2>Cypress for Symfony</h2><p>Tests en bout à bout pour les développeurs symfony.</p><p><a href="https://speakerdeck.com/leichteckig/symfony-meets-cypress-e2e-testing-for-symfony-developers">https://speakerdeck.com/leichteckig/symfony-meets-cypress-e2e-testing-for-symfony-developers</a></p><h2>Dropping ACID</h2><p>Comment designer son schéma en ecommerce, et beaucoup de sources à l'appui : Magento, Sylius, Spryker.</p><p><a href="https://speakerdeck.com/alcaeus/dropping-acid-schema-design-for-e-commerce-63ba690b-7eb0-4033-8176-c1aafd9bb24f?slide=3">https://speakerdeck.com/alcaeus/dropping-acid-schema-design-for-e-commerce-63ba690b-7eb0-4033-8176-c1aafd9bb24f?slide=3</a></p><h2>PHP et minecraft</h2><p>Minecraft !</p><p><a href="https://speakerdeck.com/thomasberends/php-plus-minecraft">https://speakerdeck.com/thomasberends/php-plus-minecraft</a></p><h2>Symfony Console</h2><p>Et ASCII Art !</p><p><a href="https://speakerdeck.com/el_stoffel/better-console-applications-symfonyworld-2020">https://speakerdeck.com/el_stoffel/better-console-applications-symfonyworld-2020</a></p><h2>Après la théorie, la pratique !</h2><p>C'est toujours un moment où j'apprends en détail de nouvelles choses et l'investissement sera toujours bénéfique !</p><h3>Darkwood est déployé sur PHP8 et Symfony 5.2</h3><p>Cette migration c'est faite tranquille, le gros du travail c'était en septembre : <a href="https://blog.darkwood.fr/article/darkwood-opensource">https://blog.darkwood.fr/article/darkwood-opensource</a><br />
Déjà, il faut passer sur PHP8 (sous mac) : <a href="https://stitcher.io/blog/php-8-upgrade-mac">https://stitcher.io/blog/php-8-upgrade-mac</a><br />
Puis monter les dépendances Symfony 5.2 et utiliser composer update.<br />
Conseil : --ignore--platform˗reqs=php à ne surtout pas reproduire à la maison !<br />
Appliquer les nouveautés qu'on veut : <a href="https://symfony.com/blog/symfony-5-2-curated-new-features">https://symfony.com/blog/symfony-5-2-curated-new-features</a>.<br />
Ensuite, un petit script pour éviter le copier coller : <a href="https://www.amitmerchant.com/how-to-upgrade-application-codebase-to-use-PHP-8-features-rector/">https://www.amitmerchant.com/how-to-upgrade-application-codebase-to-use-PHP-8-features-rector/</a><br />
Enfin quand tout est prêt, configurer le serveur : <a href="https://php.watch/articles/php-8.0-installation-update-guide-debian-ubuntu">https://php.watch/articles/php-8.0-installation-update-guide-debian-ubuntu</a>.<br />
Côté production, je dois encore faire cohabiter php7.3-fpm et php8.0-fpm car tous mes services installés ne sont pas tous mis à jour avec PHP8, et oui c'est OpenSource.
Je ne peux que recommander que de contribuer sur les dépendances qui vous font défaut.</p><p>L'installation de PHP 8.0 sur debian amd64 ressemble quelque chose à cela :</p><pre><code class="language-bash"># install php8.0 from https://php.watch/articles/php-8.0-installation-update-guide-debian-ubuntu
apt install apt-transport-https lsb-release ca-certificates wget -y
wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg 
sh -c 'echo &quot;deb https://packages.sury.org/php/ $(lsb_release -sc) main&quot; &gt; /etc/apt/sources.list.d/php.list'
apt update

apt-get install -y php8.0 php8.0-fpm php8.0-{bz2,curl,intl,mysql,readline,xml,gd}
</code></pre><h3>Darkwood utilise Caddy server</h3><p>Tout savoir comment utiliser Caddy server derrière un Cloudflare : <a href="https://sammckenzie.be/en/blog/using-caddy-with-cloudflare/">https://sammckenzie.be/en/blog/using-caddy-with-cloudflare/</a><br />
Configurer son Caddyfile : <a href="https://caddyserver.com/docs/quick-starts/caddyfile">https://caddyserver.com/docs/quick-starts/caddyfile</a><br />
Installer CaddyServer sur Linux : <a href="https://caddyserver.com/docs/install">https://caddyserver.com/docs/install</a><br />
Pour en savoir plus : <a href="https://caddyserver.com/docs/getting-started">https://caddyserver.com/docs/getting-started</a><br />
Symfony docker : <a href="https://github.com/dunglas/symfony-docker">https://github.com/dunglas/symfony-docker</a></p><p>L'installation de Caddy server sur debian amd64 ressemble quelque chose à cela :</p><pre><code class="language-bash"># from https://sammckenzie.be/en/blog/using-caddy-with-cloudflare/
curl -o /usr/bin/caddy -L https://caddyserver.com/api/download?os=linux&amp;arch=amd64&amp;p=github.com%2Fcaddy-dns%2Fcloudflare&amp;idempotency=55868885529780

echo &quot;export CLOUDFLARE_AUTH_TOKEN=MY_TOKEN&quot; &gt;&gt; ~/.bashrc
source ~/.bashrc

# from https://caddyserver.com/docs/install 
mkdir -p /etc/caddy
groupadd --system caddy
useradd --system \
    --gid caddy \
    --create-home \
    --home-dir /var/lib/caddy \
    --shell /usr/sbin/nologin \
    --comment &quot;Caddy web server&quot; \
    caddy
touch /etc/systemd/system/caddy.service
nano /etc/systemd/system/caddy.service

# from https://github.com/dunglas/symfony-docker
touch /etc/caddy/Caddyfile
nano /etc/caddy/Caddyfile
darkwood.fr {
    root * /var/www/darkwood.fr/darkwood.fr/public
    php_fastcgi 127.0.0.1:9000
    encode gzip
    file_server
    log {
		output file /var/log/caddy/darkwood.fr.log
	}
}

service caddy start
</code></pre><h2>Mais aussi ...</h2><ul><li>De Symfony 0.6 à Symfony 5 : <a href="https://skoop.dev/blog/2020/12/03/symfony-what-I-learned-from-the-framework/">https://skoop.dev/blog/2020/12/03/symfony-what-I-learned-from-the-framework/</a></li><li>PHPStan : <a href="://phpstan.org/blog/find-bugs-in-your-code-without-writing-tests">https://phpstan.org/blog/find-bugs-in-your-code-without-writing-tests</a></li><li>XDebug 3 : <a href="https://xdebug.org/announcements/2020-11-25">https://xdebug.org/announcements/2020-11-25</a></li><li>PHPStorm 2020.3 : <a href="https://www.jetbrains.com/fr-fr/phpstorm/whatsnew/">https://www.jetbrains.com/fr-fr/phpstorm/whatsnew/</a></li><li>Doctrine en PHP 8 : <a href="https://twitter.com/doctrineproject/status/1334856047648010241?s=20">https://twitter.com/doctrineproject/status/1334856047648010241?s=20</a></li><li>Symfony Cloud : <a href="https://symfony.com/blog/symfonycloud-php-8-is-available-right-now">https://symfony.com/blog/symfonycloud-php-8-is-available-right-now</a></li><li>Optimiser PHP ? Pas d'infos ici, mais voici l'essentiel à retenir ! <a href="https://twitter.com/BoineauV/status/1334806034435743744?s=20">https://twitter.com/BoineauV/status/1334806034435743744?s=20</a></li><li><a href="https://shop.symfony.com">https://shop.symfony.com</a> et <a href="https://elephpant.me">https://elephpant.me</a></li></ul><p>Spread love</p><p><img src="/blog/images/articles/symfony-world-2020/elephan-cake.jpg" alt="elephan-cake" /></p>
]]></content:encoded><link>https://blog.darkwood.com/article/symfonyworld-quoi-de-neuf</link><guid>https://blog.darkwood.com/article/symfonyworld-quoi-de-neuf</guid><enclosure url="http://darkwood.com/media/articles/5fcf6a50a8766161418367.jpg" /></item><item><title>Ce que j&#039;ai appris avec OBS</title><pubDate>Fri, 18 Dec 2020 22:18:50 +0000</pubDate><description><![CDATA[Le confinement nous a mené a faire beaucoup plus de conférences en ligne.
Et les occasions de se rencontrer à travers la caméra de votre ordinateur sont aujourd&#039;hui plus nombreuses.
Mais pourquoi parler de OBS ?
OBS dont son vrai nom : Open Broadcaster Soft...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/5fdd404003df1017036010.png" /></p><p>Le confinement nous a mené a faire beaucoup plus de conférences en ligne.<br />
Et les occasions de se rencontrer à travers la caméra de votre ordinateur sont aujourd'hui plus nombreuses.</p><p>Mais pourquoi parler de OBS ?</p><p>OBS dont son vrai nom : Open Broadcaster Software est un logiciel libre cross-plateforme et permet de réaliser le montage et le stream de vos vidéos.<br />
Il est téléchargeable sur <a href="https://obsproject.com/">https://obsproject.com/</a></p><h2>Fonctionnement</h2><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/ouverture.jpg" alt="ouverture.jpg" /></p><p>A l'ouverture, on remarque l'interface qui se comporte de la manière suivante :</p><h3>Scène</h3><p>Il s'agit de la superposition de vos différents logos, caméras, présentations que vous souhaitez diffuser.<br />
Vous pouvez créer en amont différentes scènes pour animer votre live.</p><h3>Source</h3><p>Il s'agit des composants de votre scène, votre webcam ou votre présentation, vous pourrez les organiser suivant votre besoin sur votre scène. Vous pourrez attribuer un ordre de priorité sur vos sources. Je liste les principales sources qui sont :</p><ul><li>Image : ajouter une image. Choisir un fichier en naviguant sur votre ordinateur.</li><li>Média : lire une vidéo.</li><li>Texte : ajouter du texte.</li><li>Navigateur : ajouter du contenu HTML qui est rendu sur la présentation.</li><li>Son : ajouter un son provenant de votre microphone, d'une carte son.</li><li>Afficher la capture : partager la totalité de votre écran en direct.</li></ul><p>Il est possible de cacher une source en cliquant sur l'icône de l'oeil. Cela peut être pratique pour préparer un effet pendant votre enregistrement.</p><h3>Filtres</h3><p>Les filtres permettent d'ajouter des effets de vidéo ou d'audio par rapport à vos sources existante.</p><p>Les filtres peuvent êtres combinés (tout comme pour les sources, cliquer sur l’œil situé à gauche pour activer ou désactiver le filtre).</p><p>Ils peuvent être appliqués plusieurs fois (par exemple pour faire disparaître plusieurs couleurs), mais il faut alors leur donner un nom différent.</p><p>La capture ci-dessus vous montre les filtres disponibles pour une source « image ».<br />
Le fonctionnement est identique aux Scènes et Sources : cliquer sur + pour ajouter un filtre, - pour en retirer un, les flèches permettant de modifier l’empilement pour les mêmes raisons de recouvrement qu’expliqué pour les Sources.</p><h2>Exemple de configuration</h2><p>Dans cet exemple, j'ai découpé le projet en 3 scènes  :</p><ul><li>Caméra et son de mon MacBook Pro.</li></ul><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/macbook.jpg" alt="macbook.jpg" /></p><ul><li>Caméra et son de mon iPhone.</li></ul><p>Pour cela j'utilise l'application <a href="https://obs.camera">https://obs.camera</a> certe payante, mais elle vous permettra d'avoir une qualité d'image meilleure que celle de mon MacBook Pro. Par ailleurs, vous pouvez utiliser la technologie NDI qui permet de se connecter &quot;sans fil&quot; à votre téléphone sur le même réseau.</p><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/iphone.jpg" alt="iphone.jpg" /></p><ul><li>Partage d'écran.</li></ul><p>Ici, j'utilise la caméra de mon MacBook Pro que j'ai redimensionné. J'ai ajouté une source &quot;Fenêtre&quot; afin de partager mon écran à l'audimat.</p><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/partage-ecran.jpg" alt="partage-ecran.jpg" /></p><h2>Paramètres</h2><p>Ce sont les préférences de OBS pour configurer la qualité de vos enregistrement ou stream</p><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/parametres.jpg" alt="parametres.jpg" /></p><h3>Menu Stream</h3><p>Il vous permet de choisir votre service de streaming : Twitch, Mixer, Youtube, Facebook, voire un service comme Restream, qui vous permet de streamer simultanément sur plusieurs plateformes.</p><p>Une fois le service défini, il faudra choisir un serveur. Pas la peine d’y toucher, laissez en Automatique (option recommandée). Si vous constatez des problèmes de stabilité lors de vos diffusions, et seulement à ce moment-là, dans ce cas vous pourrez tenter de définir un serveur manuellement, l’idéal étant, en théorie de prendre un serveur au plus proche de votre position géographique.</p><p>Enfin, il va falloir entrer votre clé de stream. Attention, cette clé est unique, donc ne la partagez jamais ! Pour trouver votre clé, rendez-vous dans les paramètres de votre plateforme de streaming. Sur les versions récentes d’OBS Studio, vous avez directement un lien qui vous y emmène, voire la possibilité de lier votre compte associé à la plateforme afin de récupérer automatiquement votre clé.</p><h3>Menu Vidéo</h3><p>Résolution de sortie (mise à l’échelle) : c’est la définition dans laquelle sortira votre stream, réglez donc une valeur inférieure ou égale à la résolution de base. Vous pouvez aussi taper une valeur qui n’est pas pré-définie, comme 1600×900 par exemple.</p><p>Filtrage de mise à l’échelle : c’est le filtre qui sera utilisé pour redimensionner votre stream si les deux résolutions précédentes sont différentes. Si vos résolutions sont égales, ce réglage n’aura aucun impact, normal. En revanche si vous jouez en 1080p et streamez en 720p par exemple, il faudra choisir un filtre de mise à l’échelle. Dans la liste déroulante, du haut vers le bas, on va simplement aller du plus rapide au plus qualitatif. Le Bicubic est le réglage le plus courant et est suffisant pour démarrer.</p><p>Les FPS, le fameux « frame rate » Les valeurs les plus courantes sont de 30 et 60 fps, mais rien ne vous empêche de tester des valeurs du type 50 fps afin de réduire la charge sur l’encodeur. Ici, on va rester sur 30 fps.</p><h3>Menu Audio</h3><p>Comme son nom l’indique, il va vous permettre de faire vos réglages de son, notamment sur la fréquence d’échantillonnage. Une préférence pour le 48 kHz, qui est légèrement plus qualitatif que le 44,1 kHz. Attention toutefois à bien attribuer la même valeur à votre périphérique audio par défaut, cela vous peut vous éviter quelques bugs de son.</p><h3>Menu Sortie</h3><p>Ici vous allez configurer la qualité de votre stream. Il y a plusieurs paramètres à prendre en compte comme notamment :</p><ul><li>L'encodeur.</li><li>Mise à l’échelle pour la sortie.</li><li>Contrôle du débit.</li></ul><h2>Plugins</h2><p>Les plugins sont des extensions que vous pouvez ajouter à OBS afin d'étendre l'utilisation que vous pouvez faire du logiciel. Vous pouvez retrouver ces plugins sur <a href="https://obsproject.com/forum/resources">https://obsproject.com/forum/resources</a></p><h3>Multi-platform stream</h3><p>OBS ne permet de streamer que sur une seule source à la fois. Par contre vous pourriez être amené à vouloir &quot;broadcaster&quot; sur plusieurs médias : Youtube, Facebook Live, Twitch. Ce plugin permet streamer sur différentes sources à la fois. Cependant il faudra vérifier que vous disposez d'une bonne connexion internet car vous allez multiplier votre débit d'upload proportionnellement au nombre de médias que vous allez ajouter. Autre chose, il faudra être clair quand à votre stratégie à adopter pour parler à votre audimat, car chaque plateforme possède son propre écosystème. Vous aurez alors différents type d'auditeurs.</p><p><a href="https://obsproject.com/forum/resources/multiple-rtmp-outputs-plugin.964">https://obsproject.com/forum/resources/multiple-rtmp-outputs-plugin.964</a></p><h3>Virtual cam</h3><p>Cette fonctionnalité est aujourd'hui native depuis la version 26. La caméra virtuelle est très interessante, car vous pourrez substituer votre caméra physique à celle crée par OBS. Ainsi, si vous utilisez Skype, Zoom, Steam ou un autre logiciel de chat par vidéo, vous pourrez choisir la source OBS et donc personnaliser le rendu de votre vidéo. Aussi, il ne faudra pas oublier d'activer la caméra virtuelle dans le menu &quot;Outils&quot; d'OBS.</p><p><img src="https://darkwood.fr/blog/images/articles/ce-que-j-ai-appris-avec-obs/skype.jpg" alt="skype.jpg" /></p><p>Il faut noter cependant que certains logiciels interdissent l'utilisation de la caméra virtuelle OBS. Il est possible de contourner ce problème en désactivant la signature du logiciel en question.</p><p>Plus informations technique ici : <a href="https://github.com/johnboiles/obs-mac-virtualcam/issues/131">https://github.com/johnboiles/obs-mac-virtualcam/issues/131</a></p><h3>NDI</h3><p>La technologie NDI permet partager votre stream entre vos différents appareil sur le même réseau. Cela peut être utile par exemple pour configurer un Ordinateur dédié au jeu et un autre Ordinateur dédié au stream.</p><p>Un article interessant à ce sujet à lire est disponible ici : <a href="https://www.obs.live/articles/2019/5/1/how-to-stream-with-two-pcs-using-obs-studio-and-the-ndi-plugin">https://www.obs.live/articles/2019/5/1/how-to-stream-with-two-pcs-using-obs-studio-and-the-ndi-plugin</a></p><p>Information du plugin : <a href="https://github.com/Palakis/obs-ndi">https://github.com/Palakis/obs-ndi</a></p><h2>Streamer sur Twitch</h2><p>Cette section est spécifique si vous souhaitez vous constituer un audimat propre à Twitch.</p><h3>StreamLab</h3><p>Le site <a href="https://streamlabs.com">https://streamlabs.com</a> est utile par exemple pour récupérer le flux du chat Twitch directement en tant que source sur OBS. Mais d'autres fonctionnalités sont utile comme la gestion de alertes ou d'embellir votre contenu avec des widgets.</p><h3>MooBot</h3><p>Le site <a href="https://moo.bot">https://moo.bot</a> vous permet de créer un Robot qui vous permettra d'automatiser la gestion de votre chat pour faire des actions récurrentes.</p><h3>Mais aussi</h3><ul><li>Vous pouvez consulter le meetup de Codeur en Scene : <a href="https://www.twitch.tv/videos/838509366">https://www.twitch.tv/videos/838509366</a></li><li>Un article très détaillé sur un setup Twitch : <a href="https://medium.com/@suzhinton/my-twitch-live-coding-setup-b2516672fb21">https://medium.com/@suzhinton/my-twitch-live-coding-setup-b2516672fb21</a></li></ul><h2>Améliorez la qualité de vos vidéos</h2><p>Il est important de garder un oeil sur la qualité de la vidéo que l'on produit. Ainsi je vous donne quelques liens à consulter. Cela vous permettra d'apprendre avec quelques techniques simple comment améliorer drastiquement l'image ou la voie que vous enregistrer :</p><ul><li>La chaîne de Pascal Martin : <a href="https://www.youtube.com/watch?v=GcJ6yGgQ_0E">https://www.youtube.com/watch?v=GcJ6yGgQ_0E</a></li><li>La chaîne de Grégoire Hébert: <a href="https://www.youtube.com/watch?v=4V34wwTD9TU">https://www.youtube.com/watch?v=4V34wwTD9TU</a></li></ul><h2>Streamer en tant que DJ</h2><p>Pour finir, je donne des stream de musique avec ma platine DJ Pionner. Vous pouvez consulter le dépot OpenSource que j'ai mis à disposition. Je partage mon setup qui se constitue aujourd'hui de :</p><ul><li>Une scène d'introduction avec un countdown, une animation, le logo et lle partage des réseaux sociaux.</li><li>Une scène de live stream avec ma platine Pionner.</li></ul><p>Retrouvez le détail du projet sur <a href="https://github.com/matyo91/dj-stream">https://github.com/matyo91/dj-stream</a><br />
Retrouvez ma chaine Twitch de DJ <a href="https://www.twitch.tv/djmatyo91">https://www.twitch.tv/djmatyo91</a></p><h2>Conclusion</h2><p>Voilà pour ma part ce que j'ai appris à ce jour sur OBS. Ce logiciel est facile à apprendre, mais difficile à maîtriser. J'ai l'impression de toujours apprendre quelque chose de nouveau à chaque fois que je l'utilise. Aussi c'est limite un véritable métier à plein temps si vous souhaitez devenir professionnel sur ce sujet.</p><p>J'espère qu'avec le temps j'arriverais à mieux m'accomoder tant sur les aspects technique de fond et de forme.</p><p>Bien entendu, n'hésitez pas à me donner votre avis par rapport au contenu de cet article. J'espère qu'il vous sera utile.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/ce-que-jai-appris-avec-obs</link><guid>https://blog.darkwood.com/article/ce-que-jai-appris-avec-obs</guid><enclosure url="http://darkwood.com/media/articles/5fdd404003df1017036010.png" /></item><item><title>PHP Railway Flow Based Programming</title><pubDate>Thu, 25 Mar 2021 16:27:56 +0000</pubDate><description><![CDATA[
La présentation liée à l&#039;article :

Le code source lié à l&#039;article :
https://github.com/darkwood-fr/flow
Cet article à pour but d&#039;introduire le concept, ainsi que de voir comment faire son implémentation en PHP.
Il faut préciser que cet article se base sur...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63a1e38f5f29d227024642.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/mxxdhGsaIjY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p>La présentation liée à l'article :</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/3f66a4b2cc5c4bf3ac285008295bfe47" title="PHP Railway Flow Based Programming" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px;"></iframe></div><p>Le code source lié à l'article :</p><p><a href="https://github.com/darkwood-fr/flow">https://github.com/darkwood-fr/flow</a></p><p>Cet article à pour but d'introduire le concept, ainsi que de voir comment faire son implémentation en PHP.</p><p>Il faut préciser que cet article se base sur les travaux menés par <a href="https://anton-mishchuk.medium.com/railway-flow-based-programming-with-flowex-ef04fd338e41">Anton Mishchuk</a>.<br />
Ce qui m'intéresse ici est d'introduire ce concept puis nous verrons à la fin de l'article comment on peut implémenter cela en PHP.</p><h2>Quel est la problématique ?</h2><p>Lorsque l'on parle de programmation au sens conventionnel, on se réfère en général à une approche orienté objet ou fonctionnelle.</p><ul><li>Le code est représenté sous une forme procédural et séquentielle. Dans cette approche, le parallélisme n'est pas quelque chose de natif lorsque l'on conçoit un programme. Le parallélisme sera en général l'object d'une problématique en fin de projet en vue d'optimiser l'execution du code pour prévoir les montées en charges.</li><li>Le code sera plus souvent représenté sous une forme hiérarchique structurelle, alors qu'on pourrait en avoir une représentation de flux d'entrée et sortie de données.</li><li>Le code doit être simple a représenter visuellement.</li></ul><p>Avant d'introduire le concept, nous avons besoin d'introduire deux autres concepts sous-jacents : le Flow Based Programming et le Railway Oriented Programming.</p><h2>Flow Based Programming</h2><p>Le Flow Based Programming (FBP) est un paradigme de programmation qui a été introduit par <a href="https://jpaulm.github.io/fbp">J. Paul Rodker Morrison</a> dans les années 1960. Il a ensuite été implémenté dans différents langages (Javascript, PHP, C) par <a href="https://github.com/bergie">Henri Bergius</a>. Le principe du FBP est d'exprimer un modèle d'application en terme de graphe de processus indépendants pour lesquels les données sont échangées à travers les connections. L'interêt est d'exprimer un problème en terme de transformations de flux de données.</p><p>Par exemple, prenons le cas d'une usine de production de bouteilles. Une bouteille vide va d'abord passer par une étape <em>remplissage</em>. Ensuite, lorsque l'opération est finie, la même bouteille passe par l'étape <em>d'encapsulation</em> pour fermer hermétiquement le contenu. Et enfin, la bouteille sera <em>labellisée</em> dans la dernière étape et prête à la consommation.</p><p>Dans l'approche FBP, il y a deux manière de voir ce système. Premièrement l'approche dite <em>basse</em> dite <em>business logic</em> dans laquelle nous nous intéressons à chacun de nos composants (ou processus) de manière unitaire. Chaque composant est doté d'une ou plusieurs entrées ainsi que d'une ou plusieurs sorties. Le rôle de chaque composant sera alors de traiter les données d'entrées (input) et de renvoyer leur valeur de retour en sortie (output). Chaque composant est libre d'être implémenté dans n'importe quel langage de programmation.</p><p>Deuxièmement, l'approche dite <em>haute</em>. Dans cette approche, on parle alors de logique de communication die : <em>communication logic</em>. C'est à dire que l'on va représenter notre flow de données en assemblant les composants les uns avec les autres par les connections du graphe. Il est aussi possible d'utiliser le même composant à différents endroits. Les données circulant dans un tel graphe sont appelées <em>Information Packet</em>. Par ailleurs, un tel graphe ainsi constitué peut être finalement aussi assimilé à une grosse boite noire doté lui aussi d'entrée et de sortie. Ainsi il est possible d'être consistant à tout niveau d'échelle, puisque l'on peut créer de nouveaux graphes à partir de graphes fraichement crées.</p><p>Quels sont les avantages à ce système :</p><ul><li>Le parallélisme devient naturel. En effet, si un composant venait à avoir une surcharge de données à traiter, il suffit simplement de dupliquer ce même compostant, à savoir <em>scaler</em>, pour augmenter la capacité de traitement. Ce phénomène est appelé couramment <em>back-pressure</em> lorsque trop d'information packet saturent le traitement d'un composant du graphe.</li><li>Chaque composant peut facilement être testé de manière unitaire par rapport au processus qu'il doit effectuer.</li><li>Il n'y a pas de problème de mémoire partagée et de lock. C'est évident puisque les composants sont indépendants les uns des autres.</li><li>La création d'un graphe de donnée est simple à représenter visuellement. On parle alors de programmation visuelle, voire <em>no-code</em>.</li></ul><h2>Railway Oriented Programming</h2><p>Maintenant nous allons voir le Railway Oriented Programming et son design pattern.
Afin d'expliquer le concept, partons sur un exemple. Imaginons un processus constitués de différentes étapes : Il faut récupérer une requête utilisateur, puis vérifier que les données reçue sont valide, ensuite mettre à jour la base de données d'utilisateur avec ces nouvelles données. Lorsque la base de donnée est à jour, nous envoyons un email de vérification. Enfin on retourne le résultat de la requête à l'utilisateur qui en a fait la demande.</p><p>Dans ce cas de figure, en programmation objet classique, nous allons communément écrire une fonction qui fera ce travail. Mais qu'en est-il de la gestion des erreurs, que ce passe-t-il si les données de la requête ne sont pas valides, alors on ajoute une condition pour traiter ce cas de figure. Que ce passe-t-il si il y a un problème de connection à la base de données ? On encapsule le code dans un try-catch. Et si l'utilisateur n'existe pas en base ? Il faut aussi traiter ce cas de figure par l'ajout d'une condition. Est ce que l'email de vérification a bien été envoyé ? Dans ce cas de figure on ajoute une procédure pour logger les résultats.
On remarque à travers cet exemple que lorsque le cahier des charges évolue. Ce que l'on avait écrit de simple à la base peut devenir rapidement compliqué et difficile à maintenir et à tester dans le temps.</p><p>Le Railway Oriented Programming est une manière fonctionnelle pour gérer les erreurs. En effet, l'idée consiste de créer notre programme à travers une imbrication de différents <em>Rails</em>. Pour chaque Rail, nous allons avoir deux parties : celle fonctionnelle qui va traiter l'information et celle qui gère les cas d'erreurs. Nous allons pouvoir composer notre programme par un assemblage de <em>Rails</em>. Le processus s'execute alors normalement et dès qu'il existe une erreur, on l'envoie directement en fin de chaine. Dans cette approche, il est possible de composer tout programme à travers différents Rails qui peuvent être assemblés les uns les autres et testés de manière indépendante et unitaire.</p><h2>Railway Flow Based Programming</h2><p>Enfin, nous allons parler du Railway Flow Based Programming. Qu'est ce que c'est ? Et bien c'est la résultante des deux concepts vu précédemment. Nous allons voir pas à pas, comment le définir.</p><p>Toujours avec un exemple, nous reprenons notre assemblage de Rails pour lesquels nous allons définir des opérations simple comme : AddOne, MultByTwo, MinusThree.
A ces rails, nous allons ajouter de part et d'autre un <em>Producer</em> qui est un processus charger de produire l'information. Nous concatenons notre assemblage de rails, puis un système d'Error pour la gestion d'erreur. Et enfin un <em>Consumer</em> qui se charge de traiter l'information produite. A cela, nous aurons un <em>Supervisor</em> qui se chargera d'englober tout ce système, c'est à dire d'instancier les différents composants mais aussi de les orquestrer.</p><p>Comment cela fonctionne ? Comme vu dans le FBP, nous allons introduire un <em>Client</em> qui va envoyer une <em>Information Packet</em> a <em>Producer</em>. Cette information packet sera alors traitée et transformée dans le système à travers les différents rails, pour enfin être retournée par le client via le <em>Consumer</em>.</p><p>Ce qu'il est interessant, c'est de donner la possibilité d'avoir plusieurs Clients qui font une ou plusieurs demandes en instantané. Chaque client va envoyer une ou plusieurs Information Packet dans le réseau et se verra retourner le résultat de leur demande.</p><p>Si l'on prend un cas d'usage plus avancée, nous pourrions dire que l'opération <em>MulByTwo</em> est une opération couteuse. Ainsi, si plusieurs <em>Clients</em> venaient à faire trop de demande en envoyant de nombreuses Informations Packets, nous nous retrouvons alors face à un phénomène déjà évoqué dit de <em>back pressure</em>. C'est à dire que le composant <em>MulByTwo</em> se retrouve saturé par le nombre de d'Information Packet à traiter. La circulation de l'information à travers tout le réseau devient bloquante. Dans ce cas là nous allons <em>scaler</em>, c'est à dire augmenter le nombre d'instances possibles pour l'opération <em>MultByTwo</em> afin qu'il n'y ai plus ce phénomène de goulot d'étranglement, et ainsi fluidifier la demande à traiter. A noter qu'il est aussi possible de rendre scalable le système de traitement des erreurs.</p><p>Quel est l'apport de cette représentation :</p><ul><li>La structure de donnée décrite dans l'information packet sera explicite.</li><li>Il est facile de savoir où se situe l'avancement du traitement de notre information packet dans un système linéaire.</li><li>La parallélisation du système est native et simple à configurer.</li><li>Le programme est facile à maintenir et réutiliser puisque chaque rail du système est vu comme un composant indépendant et réutilisable.</li></ul><h2>Implémentation en PHP</h2><p>Avant de parler de l'implémentation en PHP, vous pourrez noter qu'il existe déjà une implémentation en Elixir par Anton Mishchuk. Ce qui est interessant ici c'est que Elixir est plus approprié que PHP étant donné que c'est un langage fonctionnel et prévu pour être scalable, où chaque processus peut être lancé de manière indépendante. Ici en PHP, les différents Rails partagent la même mémoire et si un processus venais à planter, c'est tout le système qui échoue.</p><p>Comment représenter cette notion de message ? Regardons la documentation de Symfony Messenger. Il s'avère que le schema général correspond exactement à ce que l'on cherche à faire. Nous pouvons assimiler une enveloppe à une IP. Le <em>Supervisor</em> est composé du <em>Producer</em> assimilé au <em>Receiver</em>, le <em>Consumer</em> assimilé au <em>Sender</em> et les différents <em>Rails</em> et le rail <em>Error</em> assimilé au <em>Handler</em>. Le <em>Client</em> est l'émetteur et récepteur de l'information finale.</p><p>On vient de voir et définir la partie message d'information. Mais comment représenter la partie asynchrone ? En PHP nous allons utiliser les Générateurs.  Quel est le rapport entre les Générateurs et l'asynchrone ? Pour résumer, un Générateur, en plus d'être un itérateur, nous allons avoir 3 autres méthodes qui nous permettent d'envoyer une valeur <em>send</em>, lancer une exception <em>throw</em> et récupérer le résultat final <em>getReturn</em>. Dans un très bon article de <a href="https://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html">Nikita Popov</a> il défini ce qu'on appelle les co-routines en PHP. Effectivement les coroutines permettent à l'aide d'un event loop qui sera pris en charge par le <em>Supervisor</em> afin d'attendre finalement les différentes itérations de l'execution d'un générateur lors de la rencontre du mot clef <em>yield</em> pour une opération bloquante. L'event loop va alors prendre la main afin d'attendre que cette opération bloquante se libère, lorsque le résultat est finalement retourné, l'event loop utilisera la méthode <em>send</em> du Générateur afin de continuer l'execution et ainsi accéder à son prochain yield ou la valeur de retour. Ainsi, il est possible de mettre en place une opération de type asynchrone grâce à l'utilisation des générateurs en tant que co-routine. Pour faciliter l'intégration, j'ai utilisé la librairie Amp qui integrè déjà ces notions.</p><p>Avec ces deux éléments, nous avons toutes les briques pour construire notre système de Railway Flow Based Programming en PHP. Le plus simple est d'aller consulter le code associé à cet article, d'installer le projet et executer les exemples.</p><p><a href="https://github.com/darkwood-fr/flow">https://github.com/darkwood-fr/flow</a></p><p>Il faut noter cependant qu'il faut différencier le parallélisme et l'asynchrone. Avec le projet en Elixir <a href="https://github.com/antonmi/flowex">https://github.com/antonmi/flowex</a> qui implémente le concept, il y aura des différences avec PHP. En effet, Elixir est un langage adapté aux problématiques de threads car il a été construit sur cette approche. A la différence de PHP qui est une execution mono-thread, l'usage des co-routines fera que toute l'execution se fera en mémoire partagée. En PHP, dans notre cas, si un Rail venait à planter suite à une fuite mémoire par exemple, alors c'est tout le système qui plante. Ce ne sera pas le cas en Elixir.</p><h2>Avantages</h2><p>Les avantages que l'on peut trouver à l'implémentation du Railway Flow Based Programming en PHP sont diverses :</p><ul><li>On conçoit des systèmes qui utilisent nativement la scalabilité dès la phase de conception.</li><li>Ce peut être une bonne base pour garder une cohérence avec l'équipe en représentant le projet à travers des rails à assembler les uns des autres et en avoir une représentation visuelle.</li><li>Il n'y a pas de problèmes de lock. En effet les co-routines ne sont pas des processus parallèles, mais ils &quot;simulent&quot; ce parallélisme mais l'execution reste complètement séquentielle.</li><li>Ce concept peut très bien être transposé avec une approche dev-ops. C'est à dire en containérisant le concept (par exemple : utiliser RabbitMQ ou construire une approche serverless). Ici, un avantage d'utiliser le langage de programmation c'est de garder la main de cet assemblage au niveau du code sans à avoir a apprendre d'autres notions supplémentaire.</li><li>Il faut aussi comparer différentes approches en terme de performance. S'il on regarde des tests d'execution de code php selon différentes approches tel que décrites dans ce blog : <a href="https://divinglaravel.com/asynchronous-php">https://divinglaravel.com/asynchronous-php</a>. L'utilisation des co-routines peut être aussi bénéfique. On peut aussi se poser la question de quelle sera le choix de l'architecture à mettre en place en fonction de son projet et des besoins à valider.</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/php-railway-flow-based-programming</link><guid>https://blog.darkwood.com/article/php-railway-flow-based-programming</guid><enclosure url="http://darkwood.com/media/articles/63a1e38f5f29d227024642.png" /></item><item><title>Symfony Live Online 2021</title><pubDate>Fri, 09 Apr 2021 17:04:40 +0000</pubDate><description><![CDATA[Cette année, ce n&#039;est pas une, mais quatre conférences Symfony qui ont lieu en ligne :
https://live.symfony.com
Alors oui, en tant qu&#039;indépendant et sans financement autre que personnel, je vais pas le cacher, mais je ne vais pas pouvoir assister aux quatre...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/60708e2f6cd5a583242837.jpg" /></p><p>Cette année, ce n'est pas une, mais quatre conférences Symfony qui ont lieu en ligne :</p><p><a href="https://live.symfony.com">https://live.symfony.com</a></p><p>Alors oui, en tant qu'indépendant et sans financement autre que personnel, je vais pas le cacher, mais je ne vais pas pouvoir assister aux quatre conférences.</p><p>J'ai fait un choix judicieux de ne participer qu'à une seule. Et quoi de meilleur finalement de profiter de la conférence en Français en présence des acteurs clef du framework Symfony. Cocorico ! Et sans jeux de mots, c'est littéralement assister à la conférence comme à la maison.</p><p>C'est donc Symfony Live French Online qui a retenu mon attention. Mais les autres conférences <a href="https://live.symfony.com/2021-germany">Allemande</a>, <a href="https://live.symfony.com/2021-spain">Espagnol</a> et <a href="https://live.symfony.com/2021-world">Monde</a> sont sans doute aussi interessante et permettent de découvrir de nouveaux speakers autres que Français.<br />
C'est aussi une manière comme une autre de participer au soutient de la communauté Symfony <a href="https://symfony.com/sponsor">https://symfony.com/sponsor</a></p><h2>Qu'avons nous au programme ?</h2><p>Il suffit de se rendre sur le planning en ligne : <a href="https://live.symfony.com/2021-france/schedule">https://live.symfony.com/2021-france/schedule</a>.<br />
Encore une fois, on remarque qu'il faudra faire des choix, étant donné qu'il y a deux scènes : une SensioLabs et une Blackfire.io.<br />
Cependant, Symfony Online offre la possibilité de revoir toutes les conférences et ceci gratuitement pour tous les inscrits à l'évènement.</p><p>Au delà de la qualité des présentations, j'ai suivi :</p><ul><li>la keynote d'introduction <a href="https://connect.symfony.com/profile/fabpot"><em>par Fabien Potencier</em></a>.</li><li>les présentations sur AWS avec le Serverless <a href="https://connect.symfony.com/profile/marie.minassyan"><em>par Marie Minasyan</em></a> et la présentation du client <a href="https://async-aws.com">AsyncAws</a><a href="https://connect.symfony.com/profile/jderusse"><em>par Jérémy Derussé</em></a>. Il faut aussi garder en tête qu'utiliser les Services Amazon, c'est aussi être dépendant d'un environnement propre et fermé de l'entreprise.</li><li>l'introduction de la nouvelle initiative UX Symfony avec <a href="https://speakerdeck.com/dunglas/pedal-to-the-metal-introducing-symfony-turbo">Symfony Turbo</a><a href="https://connect.symfony.com/profile/dunglas"><em>par Kévin Dunglas</em></a> permettant la fonctionnalité de Single Page Apps à notre application Symfony, mais sans avoir à écrire de JavaScript. A la manière des ESI, on a l'équivalent en posant des tags <em>turbo-frame</em> dans le templating twig.  Par ailleurs, il est possible de coupler avec Mercure ce qui permet de <em>streamer</em> en temps réel ces changements d'état cet fois ci avec le tag <em>turbo-stream</em>.</li><li>les smarts tips <a href="https://connect.symfony.com/profile/nicolas-grekas"><em>par Nicolas Grekas</em></a> concernant des fonctionnalités cachés et utile dans le code Symfony.</li><li>la présentation des <a href="https://speakerdeck.com/guikingone/cypress-le-e2e-moderne-doit-encore-apprendre-du-passe">tests E2E avec Cypress</a><a href="https://connect.symfony.com/profile/guikingone"><em>par Guillaume Loulier</em></a> son introduction et ce que l'on peut apprendre face a Behat et Panther.</li><li>la présentation des tests E2E avec affichage dynamique avec <a href="https://connect.symfony.com/profile/weaverryan"><em>par Ryan Weaver</em></a> avec Panther et Foundry. Au delà de la présentation, j'ai apprécié l'accent, le discourt à l'américaine et l'enthousiasme qui en dégage.</li></ul><p>Pendant cette journée, Il était aussi possible d'utiliser la fonction <em>Networking</em> afin de faire un chat roulette avec un membre inscrit, ce qui m'a permis de discuter avec de nouvelles personnes dans la communauté Symfony. Pour comparer avec <a href="https://workadventu.re">Workadventure</a> plus orienté avec une carte d'interaction en mode RPG en deux dimensions, c'était une autre manière de discuter avec des personnes en privilégiant l'aléatoire des rencontres.</p><p>Mais aussi, j'ai pu rejoindre les stands des <a href="https://live.symfony.com/2021-france/sponsors">sponsors</a> afin d'avoir des détails techniques sur les présentations et d'ouvrir la conversation sur des sujets variés.</p><h2>Session de clôture</h2><p>Ce fut une journée chargée d'informations pour l'écosystème Symfony.
C'était aussi une occasion de retrouver la communauté Symfony en tant que personne et de pouvoir échanger concrètement.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/symfony-live-online-2021</link><guid>https://blog.darkwood.com/article/symfony-live-online-2021</guid><enclosure url="http://darkwood.com/media/articles/60708e2f6cd5a583242837.jpg" /></item><item><title>Hackathon no-code de la French Tech Grande Provence</title><pubDate>Fri, 24 Sep 2021 04:42:11 +0000</pubDate><description><![CDATA[
Le 22 et 23 septembre 2021 s&#039;est déroulé le Hackathon No-code organisé par la French Tech Grande Provence.
L&#039;occasion pour Darkwood de faire un retour d&#039;expérience sur ces deux journées riches en rencontres.
Introduction
La French Tech, à l’initiative du g...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63b82b49c244e974979381.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/rkl1uhpXQb0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div><p>Le 22 et 23 septembre 2021 s'est déroulé le Hackathon No-code organisé par la <a href="https://lafrenchtech-grandeprovence.fr">French Tech Grande Provence</a>.</p><p>L'occasion pour Darkwood de faire un retour d'expérience sur ces deux journées riches en rencontres.</p><h2>Introduction</h2><p>La French Tech, à l’initiative du gouvernement, est un grand mouvement de mobilisation pour favoriser la croissance et le
rayonnement des startups françaises, tant en France qu’à l’international.</p><p>Créée en 2013 à Avignon initialement sous le nom de La Culture Tech, la French Tech Grande Provence fédère l’ensemble
des acteurs du territoire mobilisés autour de cette démarche. Elle a été relabellisée Communauté French Tech en 2019. Son
ambition est de créer les conditions favorables à l’émergence, au développement et à la pérennisation des startups à fort
potentiel de croissance et plus largement des initiatives innovantes sur son territoire.</p><p>Au programme, 48h pour imaginer et développer des solutions tech qui facilite le développement de l'économie circulaire grâce au secteur de la logistique.</p><p>En s'appuyant uniquement sur des logiciels No-code pour innover durant ce hackathon, a pour but de promouvoir une technologie plus inclusive et qui facilite et accélère les processus d'innovation.</p><p>Ce hackathon à également pour objectif de montrer aux entrepreneurs, entreprises, étudiants et acteurs public le potentiel qu'offre le No-code en terme d'innovation et de digitalisation.</p><p>Durant 48h, plus de 60 participants réunis en équipe de 4 personnes vont donc imaginer des solutions innovantes pour l'économie circulaire et la logistique. L’objectif sera de tirer parti des possibilités offertes par le numérique, l’exploitation de la donnée et les outils no-code.</p><h2>La thématique</h2><p>L'enjeu est de taille : quelles innovations créer pour concilier cela face aux enjeux environnementaux que nous connaissons ? La logistique au travers de l'économie circulaire a un rôle important à jouer pour répondre à ces défis.</p><p>Pour cela l'organisation propose de se pencher sur 3 challenges :</p><ul><li>Comment faciliter ou mutualiser la chaine logistique au profit de la gestion et la valorisation des déchets des entreprises (introduction terre EFC)</li><li>Quelles solutions logistiques adaptées pour faciliter et développer le système de consigne</li><li>Comment faciliter ou mutualiser la chaine logistique pour développer l'économie circulaire dans le secteur agricole?</li></ul><h2>Déroulement du programme</h2><p>C'est grâce à l'utilisation de la plateforme <a href="https://hopin.com">Hopin</a> que l'évènement est organisé. Toutes les participations se font 100% en ligne à travers différentes animations :</p><ul><li>1 hackathon no-code sur la logistique</li><li>1 table ronde No-code for good</li><li>1 table ronde le No-code et la transformation digitale des PME et Grands comptes</li><li>des live demo</li><li>des formations au no-code gratuites</li><li>des sessions de networking</li><li>des stands</li><li>la radio live No-code France pour couvrir l'événement</li><li>les sessions de pitch et la remise des prix du hackathon</li><li>des rencontres avec la communauté No-code française</li></ul><p>L'application <a href="https://www.mural.co">Mural</a> a été utilisée pendant la durée des rencontres, notamment à fin de constituer les équipes. Il était amusant de voir les +100 curseurs de souris en simultanés pour que chaque participant choisisse un encart à son nom et se place à une des tables constituées. Mais au final cela s'est bien déroulé.</p><h2>L'équipe</h2><p>Finalement mon choix a porté sur <a href="https://lpcressources.fr">Créacycle</a> : Une solution numérique innovante pour développer l'économie circulaire en proposant un outil de travail pour fluidifier les échanges entre les entreprises et les particulier contre le gaspillage et pour la revalorisation des déchets.</p><p>Ainsi j'ai rejoint une équipe de 3 personnes constituée de Marion, Emina et de moi même avec le joli nom de : &quot;Les no-petites choses&quot;.</p><p>A l'aide de l'outil <a href="https://www.notion.so">Notion</a> nous avons facilement crée un document en édition partagée afin que chacun puisse contribuer à l'écriture de la documentation du projet.</p><p>Nous avons fait un premier brainstorming afin de lister les fonctionnalités que l'on souhaite mettre en avant :</p><ul><li>carte géo-localisée des acteurs</li><li>que peut ton faire avec les produits</li><li>jeu interactif</li><li>galerie photo des matières</li><li>formulaire pour inscription de demande</li><li>messagerie sécurisée entre le porteur et les personnes qui proposent</li><li>catalogue de matière</li></ul><p>Nous avons pensé à utiliser plusieurs outils à l'aide de la présentation qui nous a été faite et nos connaissances sur le sujet :</p><ul><li>site internet et mobile : <a href="https://www.weebly.com">www.weebly.com</a> ou <a href="https://www.glideapps.com">www.glideapps.com</a> ou <a href="https://dorik.com">dorik.com</a></li><li>création de formulaires : <a href="http://typeform.com">typeform.com</a></li><li>administration de base de données <a href="https://airtable.com">airtable.com</a></li><li>automatisation : <a href="https://zapier.com">zapier.com</a></li><li>enregistrement vidéo : <a href="https://loom.com">loom.com</a></li></ul><p>Et finalement dessiner la formulation de notre challenge à réaliser :<br />
Comment pourrait-on faire pour créer un catalogue de matières issues du réemploi, permettant d'optimiser les flux sur le territoire ?</p><h2>Développement</h2><p>C'était l'occasion de découvrir les outils no-code et réaliser les défis proposés et prévu pour cette occasion. Grâce à l'aide des mentors présents tout au long des 2 jours, nous avons reçu des conseils avisés pour répondre à certains points ou interrogations afin de nous débloquer et pouvoir avancer dans la réalisation du projet.</p><h2>Solution</h2><p>Notre équipe a choisi de développer un catalogue de matières brutes, d'utilisation intuitive et collaborative.</p><p>Cette solution inclut :</p><ul><li>une landing page : <a href="https://creacycle.dorik.io">https://creacycle.dorik.io</a></li><li>un formulaire de prise de rdv : <a href="https://1pi9d7ydsg8.typeform.com/to/BfC3J5ER?typeform-source=creacycle.dorik.io">https://1pi9d7ydsg8.typeform.com/to/BfC3J5ER?typeform-source=creacycle.dorik.io</a></li><li>une application mobile : <a href="https://creacycle.glideapp.io">https://creacycle.glideapp.io</a></li></ul><h2>Retour d'expérience</h2><p>Pour ma part, je tiens à féliciter l'équipe d'organisation du Hackathon. Le programme était clair et les supports adaptés pour faire des rencontres connectées.<br />
Je tiens à remercier l'équipe avec Marion, Emina pour la collaboration dynamique et juste, ce que l'on a réussit à réaliser. Je suis curieux de savoir comment va évoluer ce projet porteur de sens et prometteur.<br />
J'ai été étonné de voir ce qu'il est possible de faire en a peine 48h et comparer avec des méthodes de développement traditionnelles qui nécessitent souvent plus de technicité. Dans cette approche pouvoir sortir rapidement un Minimum Viable Product fonctionnel.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/hackathon-no-code-de-la-french-tech-grande-provence</link><guid>https://blog.darkwood.com/article/hackathon-no-code-de-la-french-tech-grande-provence</guid><enclosure url="http://darkwood.com/media/articles/63b82b49c244e974979381.png" /></item><item><title>Les Monades et leur utilisation en PHP</title><pubDate>Thu, 30 Sep 2021 05:48:21 +0000</pubDate><description><![CDATA[
La présentation liée à l&#039;article :

A l&#039;occasion du meetup AFUP de Rennes, je vous introduit dans cet article les monades et leur utilisation en PHP.
Pourquoi les monades ?
Une nouvelle façon de programmer avec des &amp;quot;effets&amp;quot;.
Une autre raison sera...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63867f18c8b72213833486.jpeg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/0M6MhUpra9o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p>La présentation liée à l'article :</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/55e152d58f7248e6a682667ce37a2522" title="Monads and usage in PHP" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px;"></iframe></div><p>A l'occasion du <a href="https://www.meetup.com/fr-FR/AFUP-Rennes/events/280769219">meetup AFUP de Rennes</a>, je vous introduit dans cet article les monades et leur utilisation en PHP.</p><h2>Pourquoi les monades ?</h2><p>Une nouvelle façon de programmer avec des &quot;effets&quot;.</p><p>Une autre raison serait à cause du paradox de Crockford's qui est vue comme une &quot;malédiction&quot; :<br />
Lorsque vous avez pleinement compris ce qu'est une Monad, vous perdez l'habilité d'expliquer ce concept à d'autres personnes. En référence au <a href="https://www.youtube.com/watch?v=dkZFtimgAcM">talk de 2012 Douglas Crockford: Monads and Gonads</a></p><h2>Un peu d'histoire</h2><p><a href="https://homepages.inf.ed.ac.uk/wadler/">Philip Wadler</a> commence, en 1992, un article qui se révélera décisif dans l'application des monades à la programmation fonctionnelle : <a href="https://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf">Monads for functional programming</a></p><p>Depuis, l'usage des monades s'est répandu dans plusieurs langages, et en particulier dans Haskell, auquel elles ont apporté une réponse élégante pour les entrées/sorties et pour le contrôle d'exécution.</p><h2>Partons sur un example</h2><p>Nous allons partir d'un exemple simple qui consiste à écrire une fonction qui évalue des expressions. Pour support nous utiliserons le langage Haskell, un langage de programmation fonctionnel crée en 1990, il n'est pas nécessaire de connaitre ce language pour l'exemple.</p><p>Partons d'un type de données pour laquelle on va évaluer une expression qui peut être soit une valeur entière, soit une division entre deux expressions représenté sous cette forme :</p><pre><code>Data Expr = Val Int | Div Expr Expr
</code></pre><p>Maintenant division l'espace en deux : ce que l'on peut écrire en notations mathématiques et l'équivalent en Haskell</p><p>On aurait les équivalences suivantes :</p><ul><li>1 (entier) équivaut à Val 1 (Haskell)</li><li>6 / 2 (entier) équivaut à Div (Val 6) (Val 2) (Haskell)</li><li>6 / ( 3 / 1 ) (entier) équivaut à Div (Val 6) (Div (Val 3) (Val 1)) (Haskell)</li></ul><p>Ce qui nous intéresse est de savoir comment écrire un programme qui évalue ces expressions.
On écrit alors une fonction d'évaluation qui prend une Expression en entrée et une Valeur entière en sortie.</p><pre><code>eval :: Expr -&gt; Int
eval (Val n) = n
eval (Div (Expr x) (Expr y)) = eval(x) / eval(y)
</code></pre><p>Il est facile de construire une fonction récursive pour évaluer le résultat. Cependant nous avons un problème car le programme peut crasher étant donné que la division par zéro est indéfinie.</p><p>Que peut-on faire pour résoudre ce problème, on défini une version &quot;safe&quot; de l'opérateur de division qui ne permet pas de faire crasher le programme. On défini alors la fonction safediv :</p><pre><code>safediv :: Int -&gt; Int -&gt; MayBe Int
safediv (Int n) (Int m) = if m == 0 then Nothing else Just(n / m)
</code></pre><p>Le type de la fonction est Int vers Int vers &quot;peut être Int&quot; représenté par Maybe. Ici Maybe peut recevoir deux types de constructeurs : Nothing ou Just
Dans cette représentation, le programme ne crash plus. Nous pouvons réécrire notre fonction d'évaluation comme ci :</p><pre><code>eval :: Expr -&gt; Maybe
eval (Val n) = Just(n)
eval (Div (Expr x) (Expr y)) = case eval(x) at 
  Nothing -&gt; Nothing
  Just n -&gt; case eval(y) of
    Nothing -&gt; Nothing
    Just m -&gt; safediv (n m)
</code></pre><p>Le programme ne crash plus, mais il devient plus compliqué à écrire. Comment faire pour le simplifier ? On peut identifier des patterns au niveau de l'évaluation des cas. On va alors abstraire ces patterns :</p><pre><code>case [m] as Maybe of 
  Nothing -&gt; Nothing
  Just x -&gt; [f] as function x
</code></pre><p>Ce qui se traduit de cette manière en language Haskell avec le symbole de sequence &gt;&gt;=</p><pre><code>m &gt;&gt;= f case m of 
  Nothing -&gt; Nothing
  Just x -&gt; f x

</code></pre><p>On peut simplifier notre fonction eval</p><pre><code>eval :: Expr -&gt; Maybe Int
eval (Val n) = return n
eval (Div (Expr x) (Expr y)) = eval(x) &gt;&gt;= (ƛn -&gt; 
                               eval(y) &gt;&gt;= (ƛm -&gt; 
                               safediv n m))
</code></pre><p>Mais on peut faire encore plus simple grâce à la notation &quot;do&quot; de Haskell</p><pre><code>eval :: Expr -&gt; Maybe Int
eval (Val n) = return n
eval (Div (Expr x) (Expr y)) = do n &lt;- end x
                                  m &lt;- end y
                                  safediv n m
</code></pre><p>Nous avons écrit de manière élégante le programme initial mais sans avoir de crash.
Ce que nous venons de voir ici, c'est de découvrir la Monade Maybe :</p><pre><code>return :: a -&gt; Maybe a
   &gt;&gt;= :: Maybe a -&gt; (a -&gt; Maybe b) -&gt; Maybe b
</code></pre><p>Les monades apportent les idées suivantes :</p><ul><li>les utiliser en tant que framework pour écrire d'autres effets.</li><li>un support pour la programmation pure avec effets.</li><li>l'utilisation d'effets par l'utilisation de types explicites.</li><li>des fonctions pour n'importe quel type d'effet.</li></ul><h2>Comment les représenter</h2><p>Dans la programmation fonctionnelle, on parle de fonctions pures, c'est à dire une fonction pour laquelle nous pouvons :</p><ul><li>passer des arguments par valeur</li><li>avoir une valeur de retour</li><li>ne pas utiliser de variables globales, ni d'appel à l'aide du mot clef <code>$this</code> ou du mot clef <code>static</code></li><li>facilement tester grâce aux tests unitaires</li><li>mettre en cache les valeurs de retours selon les valeurs d'entrée grâce à la mémoïsation.</li></ul><p>Les langages fonctionnels ont comme autre propriété la transparence référentielle. Ce terme recouvre le principe simple selon lequel le résultat du programme ne change pas si on remplace une expression par une expression de valeur égale. Ce principe est violé dans le cas de procédures à effets de bord puisqu'une telle procédure, ne dépendant pas uniquement de ses arguments d'entrée, ne se comporte pas forcément de façon identique à deux instants donnés du programme.</p><p>Par exemple :</p><ul><li>file_get_contents($filename) n'assure pas de retourner le même contenu si le fichier a été édité</li><li>mysql_query($query) ne renvoie pas les mêmes données, car elles dépendent de l'état de la base de données</li><li>time() : renvoie une valeur dynamique en fonction du temps</li><li>rand() : retourne une valeur aléatoire</li></ul><p>C'est un concept qui a été popularisé par la communauté Haskell pour lequel il faut apprendre la théorie mathématique sur les Catégories.
On pourrait parler des monades de manière algébrique.<br />
Cela signifie que toute monade donne lieu à la fois à une catégorie (appelée catégorie de Kleisli) et à un monoïde dans la catégorie des foncteurs (des valeurs aux calculs), avec la composition monadique comme opérateur binaire et l'unité comme identité.</p><p>Un foncteur n’est rien d’autre qu’une fonction qui applique une autre fonction à des objets dotés d’une structure et qui préserve cette structure. Par analogie avec la théorie des catégories, les objets ici sont des morphismes, en l’occurrence Maybe Int en Haskell pour lesquels fmap conserve bien leur structure de Maybe. Un foncteur est donc toujours relatif à un type de données générique. En Haskell, les foncteurs sont explicites. Ils sont définis par le type algébrique Functor et Maybe est une instance de ce type et spécifie donc comment fmap s’applique à elle. On dit alors, par extension, que Maybe est un foncteur.</p><p>Une monade n’est pas cette fois-ci un morphisme comme le sont les foncteurs et les foncteurs applicatifs mais plutôt une construction, un type algébrique abstrait, reposant sur les foncteurs et qui est défini par les propriétés suivantes :</p><ul><li>il existe une correspondance qui à tout type générique relie un type monadique. Autrement dit, par simplification, un constructeur qui à une valeur retourne une monade avec cette valeur. Dans notre exemple, fmap compute retourne une monade avec un tel constructeur (la fonction compute curryfiée)</li><li>il existe une opération de composition interne associative entre monades sous forme d’un foncteur, donc qui préserve la structure monadique. Dans notre exemple, il s’agit de <code>&gt;&gt;=</code></li><li>il existe un élément neutre, appelé identité. Dans le cas des Maybe a, c’est Nothing.<br />
Une monade est une application aux catégories (en gros, dans notre cas, aux foncteurs) ce que sont les monoïdes en algèbre (qui sont des ensembles munis d’une loi de composition interne associative et d’un élément neutre). D’où le nom de monade.</li></ul><p>Pour l'instant, ne nous soucions pas trop de ce qu'est une Monade. Cela devrait devenir relativement évident alors que nous jouons avec quelques-unes. Au lieu de cela, pour nos besoins, pensez simplement à une Monade comme un conteneur d'état, où différentes Monades font des choses différentes à cet état.</p><h2>Un peu de théorie</h2><p>Définition formelle :
Une monade peut se voir comme la donnée d'un triplet constitué des trois éléments suivants.</p><ul><li>Un constructeur de type appelé type monadique, qui associe au type <code>t</code> le type <code>Mt</code></li><li>Une fonction nommée <code>unit</code> ou <code>return</code> qui construit à partir d'un élément de type sous-jacent <code>a</code> un autre objet de type monadique <code>Ma</code>. Cette fonction est alors de signature <code>t -&gt; Mt</code>.</li><li>Une fonction bind, représentée par l'opérateur infixe <code>&gt;&gt;=</code>, associant à un type monadique et une fonction d'association un autre type monadique. Il permet de composer une fonction monadique à partir d'autres fonctions monadiques. Cet opérateur est de type <code>&gt;&gt;=: Mt (t -&gt; Mu) -&gt; Mu</code>.</li></ul><p>En composant la fonction <code>&gt;&gt;=</code> (dite fonction de liaison) avec la fonction <code>return</code>, on peut appliquer n'importe quelle fonction <code>g : t -&gt; t</code> à une monade de type <code>Mt</code>. En ce sens une monade de type <code>Mt</code> est un type algébrique qui dérive du type <code>t</code>.</p><p>Axiomes :
La définition précédente s'accompagne de plusieurs axiomes. L'opérateur <code>return</code> agit comme une sorte d'élément neutre pour <code>&gt;&gt;=</code>.</p><ul><li>composition à gauche par <code>return</code> (≡ désigne l'égalité structurelle) :
<code>(return x) &gt;&gt;= f ≡ fx</code></li><li>composition à droite par <code>return</code> :
<code>m &gt;&gt;= return ≡ m</code></li><li>associativité :
<code>(m &gt;&gt;= f) &gt;&gt;= g ≡ m &gt;&gt;= ƛx</code></li></ul><h2>Quelles sont les applications ?</h2><p>Pour un langage impur, c'est à dire permettant toute sorte d'effet de bord dans les fonctions, les monades ne sont pas d'une nécessité évidente, bien qu'elles puissent offrir une solution élégante et rapide à certaines catégories de problèmes.</p><p>En revanche, pour un langage fonctionnel pur, c'est à dire ne permettant aucun effet de bord, et aucun contrôle d'exécution implicite, les monades offrent une construction permettant d'enrichir les capacités des fonctions. Expliquons cela par un exemple : dans un langage pur, une fonction de type Int → Int → Int sera capable de prendre deux entiers pour en composer un autre. Point. C'est à dire que cette fonction ne pourra lire absolument aucun état du programme, ne pourra accéder ni à un fichier, ni à l'heure courante, ni même à un nombre aléatoire. Elle ne pourra pas non plus logger dans un terminal, ou écrire un rapport d'exécution dans une variable.</p><p>La signature de cette fonction a un sens très strict quant à ses capacités : elle peut lire deux entiers, et les utiliser pour en produire un autre. Elle est donc pure, et cela lui confère entre autres une propriété essentielle, le déterminisme. Appelée avec les mêmes arguments, elle produira inlassablement le même résultat, quel que soit l'état de son environnement d'exécution (programme, heure, fichiers, entrées de l'utilisateur etc).</p><p>Une autre catégorie couramment rencontrée est celle des fonctions monadiques, qui forment une généralisation des fonctions ordinaires. Pour plus d'informations à ce sujet, les applications avec la catégorie de Kleisli est bien détaillée sur cette article : <a href="https://www.atikteam.com/fr/blog/page/Programmation-Fonctionnelle-et-Theorie-des-Categories#la-cat%C3%A9gorie-de-kleisli">https://www.atikteam.com/fr/blog/page/Programmation-Fonctionnelle-et-Theorie-des-Categories#la-cat%C3%A9gorie-de-kleis</a></p><h2>Des exemples d'application</h2><ul><li>la monade Identité</li></ul><p>MonadPHP : <a href="https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html#Getting-Start">https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html#Getting-Start</a></p><ul><li>la monade <code>Failable</code></li></ul><p>En cas de succès, on construira Ok a, et en cas d'échec, on construire Failed &quot;Motif de l'erreur&quot;. Oui, vous reconnaissez peut-être ici le principe des exceptions. Sauf que dans notre cas, le contrôle d'exécution n'est pas interrompu, et le type de retour est explicite, permettant une vérification statique complète des appels, donc un code beaucoup plus sûr et rapide.</p><ul><li>la monade <code>Maybe</code>
L'utilisation la plus simple des monades consiste à encapsuler un objet de type existant dans un objet portant plus d'information.</li></ul><p>Par exemple en langage Haskell, une monade de type <code>Maybe(t)</code> est ou bien un objet de type <code>t</code> normal, ou bien la valeur <code>Nothing</code>. Cela permet de traiter de façon élégante les opérations interdites.</p><p>Exemple avec la monade Option <a href="https://github.com/schmittjoh/php-option">https://github.com/schmittjoh/php-option</a></p><ul><li>la monade <code>List</code></li></ul><p>Le cas de getGrandParentName : <a href="https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html#Another-Practical-Examp">https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html#Another-Practical-Examp</a></p><ul><li>la monade <code>Logger</code></li></ul><p><a href="https://www.atikteam.com/fr/blog/page/Les-Monades-Dans-La-Programmation-Fonctionnelle#tenir-un-journal-dactivit%C3%A9-avec-la-monade-logger">https://www.atikteam.com/fr/blog/page/Les-Monades-Dans-La-Programmation-Fonctionnelle#tenir-un-journal-dactivit%C3%A9-avec-la-monade-logger</a></p><ul><li>la monade <code>IO</code></li></ul><p>Une autre utilisation fondamentale des monades est la gestion des entrées/sorties dans un programme purement fonctionnel, c'est-à-dire sans effets de bord.</p><ul><li>il y a plusieurs bibliothèques remarquables sur l'utilisation des monades en PHP :
<ul><li><a href="https://github.com/ircmaxell/monad-php">https://github.com/ircmaxell/monad-php</a> : Monad, Identity, Maybe, Chain, Deferred, ListMonad, Promise</li><li><a href="https://github.com/schmittjoh/php-option">https://github.com/schmittjoh/php-option</a> : Option, LazyOption, Some, None</li><li><a href="https://github.com/GrahamCampbell/Result-Type">https://github.com/GrahamCampbell/Result-Type</a> : Result, Success, Error</li><li><a href="https://github.com/whsv26/functional">https://github.com/whsv26/functional</a> : Option (do notation), Some, None, Either</li><li><a href="https://github.com/Innmind/Immutable">https://github.com/Innmind/Immutable</a> : Maybe, Either, RegExp</li><li><a href="https://github.com/marcosh/lamphpda">https://github.com/marcosh/lamphpda</a> : Identity, Either, Maybe, IO</li><li><a href="https://github.com/darkwood-fr/railway-fbp">https://github.com/darkwood-fr/railway-fbp</a> : Rail</li></ul></li></ul><h2>En conclusion</h2><p>Les monades apportent une boite à outil (ou framework) qui permet de programmer avec <code>effets</code>. Elles supportent la programmation pure, dans le sens ou elles permettent de convertir un comportement impure en comportement pure grâce aux <code>effets</code>. Un autre point important est de pouvoir utiliser les <code>effets</code> de manière explicitement <code>typée</code>, et donc de pouvoir préciser quel <code>effet</code> ou <code>side-effet</code> un programme pourra être confronté par l'écriture du type de données. Une dernière idée est de pouvoir écrire n'importe quelle fonction en utilisant les <code>effect</code> que l'on pourrait appeler <code>effet de polymorphisme</code>, comme par exemple composer les <code>effets</code> vu comme séquence d'effets.</p><p>Les monades sont une des plus importantes découverte de l'informatique depuis les années 1980. Si vous souhaitez en savoir plus, le meilleur serait de les utiliser et mettre en pratique les différentes ressources citées dans cet article.</p><h2>Ressources liées à l'article</h2><ul><li>Articles :
<ul><li>Wikipedia :
<ul><li>Monade en Français : <a href="https://fr.wikipedia.org/wiki/Monade_(informatique)">https://fr.wikipedia.org/wiki/Monade_(informatique)</a></li><li>Monade en Anglais : <a href="https://en.wikipedia.org/wiki/Monad_(functional_programming)">https://en.wikipedia.org/wiki/Monad_(functional_programming)</a></li><li>Programmation fonctionnelle en Français : <a href="https://fr.wikipedia.org/wiki/Programmation_fonctionnelle">https://fr.wikipedia.org/wiki/Programmation_fonctionnelle</a></li><li>Programmation fonctionnelle en Anglais : <a href="https://en.wikipedia.org/wiki/Functional_programming">https://en.wikipedia.org/wiki/Functional_programming</a></li><li>Haskell programming langage : <a href="https://fr.wikipedia.org/wiki/Haskell">https://fr.wikipedia.org/wiki/Haskell</a></li></ul></li><li>Introducing monads + MonadPHP :
<ul><li>Blog : <a href="https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html">https://blog.ircmaxell.com/2013/07/taking-monads-to-oop-php.html</a></li><li>Dépot Github : <a href="https://github.com/ircmaxell/monad-php">https://github.com/ircmaxell/monad-php</a></li><li>Article similaire : <a href="https://blog.emptyq.net/a?ID=00004-b2ebfe61-2306-4a38-b20b-c2618fe0ef5f">https://blog.emptyq.net/a?ID=00004-b2ebfe61-2306-4a38-b20b-c2618fe0ef5f</a></li></ul></li><li>Why monads are useful : <a href="https://jameswestby.net/tech/why-monads-are-useful.html">https://jameswestby.net/tech/why-monads-are-useful.html</a></li><li>Les monades dans la programmation fonctionnelle : <a href="https://www.atikteam.com/fr/blog/page/Les-Monades-Dans-La-Programmation-Fonctionnelle">https://www.atikteam.com/fr/blog/page/Les-Monades-Dans-La-Programmation-Fonctionnelle</a></li><li>Promise is neither a Functor nor an Applicative nor a Monad <a href="https://stackoverflow.com/questions/45712106/why-are-promises-monads">https://stackoverflow.com/questions/45712106/why-are-promises-monads</a></li><li>Monads and Monoids : <a href="https://bartoszmilewski.com/2017/09/06/monads-monoids-and-categories">https://bartoszmilewski.com/2017/09/06/monads-monoids-and-categories</a></li></ul></li><li>PHP
<ul><li>Le cas d'utilisation avec la syntaxe Yield : <a href="https://github.com/whsv26/functional/blob/14957faba58044deab7ab23fd7f00466e98445e9/doc/Monads.md">https://github.com/whsv26/functional/blob/14957faba58044deab7ab23fd7f00466e98445e9/doc/Monads.md</a></li><li><a href="https://github.com/ircmaxell/monad-php">https://github.com/ircmaxell/monad-php</a></li><li><a href="https://github.com/schmittjoh/php-option">https://github.com/schmittjoh/php-option</a></li><li><a href="https://github.com/GrahamCampbell/Result-Type">https://github.com/GrahamCampbell/Result-Type</a></li><li><a href="https://github.com/whsv26/functional">https://github.com/whsv26/functional</a></li><li><a href="https://github.com/darkwood-fr/railway-fbp">https://github.com/darkwood-fr/railway-fbp</a></li></ul></li><li>Slides
<ul><li>Functional programming slides : <a href="https://fr.slideshare.net/Mittie/monads-from-definition">https://fr.slideshare.net/Mittie/monads-from-definition</a></li><li>Monads in Java and slides : <a href="https://fr.slideshare.net/mariofusco/monadic-java">https://fr.slideshare.net/mariofusco/monadic-java</a></li></ul></li><li>YouTube
<ul><li>What is a monad : <a href="https://www.youtube.com/watch?v=t1e8gqXLbsU">https://www.youtube.com/watch?v=t1e8gqXLbsU</a></li><li>Go mad for monads : <a href="https://www.youtube.com/watch?v=F5fUgXFSH0Q">https://www.youtube.com/watch?v=F5fUgXFSH0Q</a></li><li>functional PHP : <a href="https://www.youtube.com/watch?v=M3_xnTK6-pA">https://www.youtube.com/watch?v=M3_xnTK6-pA</a></li><li>Douglas Crockford: Monads and Gonads : <a href="https://www.youtube.com/watch?v=dkZFtimgAcM">https://www.youtube.com/watch?v=dkZFtimgAcM</a></li></ul></li><li>Articles
<ul><li>getting started GitHub resources : <a href="https://github.com/marcelgsantos/getting-started-with-fp-in-php">https://github.com/marcelgsantos/getting-started-with-fp-in-php</a></li><li>relationship with Either monad : <a href="https://fsharpforfunandprofit.com/rop">https://fsharpforfunandprofit.com/rop</a></li><li>Foncteurs, Foncteurs Applicatifs et Monades <a href="https://www.moquillon.fr/index.php/post/2018/01/06/Fonctor%2C-Fonctors-Applicatifs-et-Monads">https://www.moquillon.fr/index.php/post/2018/01/06/Fonctor%2C-Fonctors-Applicatifs-et-Monads</a></li></ul></li><li>Twitter
<ul><li>Ocramius <a href="https://twitter.com/Ocramius/status/1432135367017353220">https://twitter.com/Ocramius/status/1432135367017353220</a></li><li>Pierstoval <a href="https://twitter.com/Pierstoval/status/1432237084580925443">https://twitter.com/Pierstoval/status/1432237084580925443</a></li></ul></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/les-monades-et-leur-utilisation-en-php</link><guid>https://blog.darkwood.com/article/les-monades-et-leur-utilisation-en-php</guid><enclosure url="http://darkwood.com/media/articles/63867f18c8b72213833486.jpeg" /></item><item><title>Vie privée Numérique</title><pubDate>Mon, 08 Nov 2021 08:39:50 +0000</pubDate><description><![CDATA[
Cet article traite de notre empreinte numérique, des données que l&#039;on est mené partager ou enregistrer sur Internet. L&#039;idée ici est de faire un constat, puis de montrer un exemple d&#039;installation de son poste et de ses outils numériques pour allier théorie...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63867e7e9314b008912121.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/bGUyHWImAqQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p>Cet article traite de notre empreinte numérique, des données que l'on est mené partager ou enregistrer sur Internet. L'idée ici est de faire un constat, puis de montrer un exemple d'installation de son poste et de ses outils numériques pour allier théorie et pratique. A la lecture de l'article, il y a un partage de liens visant des services informatique ou <a href="https://fr.wikipedia.org/wiki/Software_as_a_service">SAAS</a>. Le sujet ici, n'est pas forcément de faire la promotion de tel ou tel service ou d'en favoriser un plutôt qu'un autre, car il est possible de trouver des alternatives aux services, mais aussi chaque service a sa particularité et sa façon de penser lorsqu'on est mené à l'utiliser.</p><p>Le mois dernier, j'ai été pas mal confronté à la redefinition de ma vie privée numérique. En effet, cette dynamique était surtout liée au besoin de me sécuriser, protéger mes données personnelles, mon emprunte numérique, sécuriser mes comptes internets et dans se sens sécuriser mon environnement informatique et numérique.</p><p>Prenons un cas d'exemple simple. Lorsque ou quelqu'un marche va faire ses courses dans un marché. Cette personne capte en continue tout un tas d'information de données sensorielle (les yeux et la vision, le nez avec l'odorat, la bouche avec le gout, les oreilles et l'ouie, le toucher avec les doigts), mais aussi de données culturelles comme le langage en discutant avec d'autres commercants ou passants. En une matinée de marché, cette personne pourrait très bien monter un blog et le publier sur internet pour parler de son expérience, ou bien de prendre des photos et faire une publication sur les réseaux sociaux et rien de l'empêche dans l'absolu. Il y a plusieurs points à remarquer. Le premier est le fait de capter de l'information, dans se sens il est difficile de savoir quelles sont les informations privées et quelles sont les informations publiques qui en ressortent. Dans privées, je pense à des informations qui sont propres à la personnes comme parler de sa semaine avec un passant que l'on connait. Dans public, je pense aux informations telles que les enseignes des différents commercants qui permettent d'identifier leur activité. Il y a alors une frontière plutôt ambigue dans la classification des données d'ordre publiques ou privées. Dans une autre manière de voir les choses, la personne a techniquement tous les droits de capter ces informations. Un autre point concerne donc l'acquisition des données et donc cela peut être vu plus comme des capteurs, plus on est muni de capteurs et plus l'acquisition peut être diverse et variée, dans l'exemple, j'ai omis le fait par exemple de prendre des photos, et couremment maintenant géolocalisées, sur son téléphone. Le dernier point est donc l'intension. La personne rentre du marché a cumulé un nombre incroyable de données. L'intention de cette personne est ici de faire une publication de son expérience. Et l'intension à mon sens est la frontière de : qui a l'information et qui fait quoi de l'information. Par exemple, dans certaines structures d'entreprises, avoir l'information sur des collègue peut être aussi vu comme avoir une donnée de plus sur les autres, et décider de donner ou pas ces informations a des répercutions sur l'échange, mais aussi la connaissance, et la vie privée. Si cette personne décide donc de publier un blog sur son expérience du marché, quelque part, elle peut omettre des droits a l'image ou de donner des détails privatif d'autres personnes. Idéalement la publication d'un blog ouvert à des personnes inconnues devrait se porter sur des informations à titre publique uniquement. Un dernier point concerne le traitement des données, il y a une différence entre publier son blog sur un se rveur pour lequel on contrôle ses données, et publier un blog sur des plateformes de réseau sociaux, quelque part, on fait travailler des plateformes et nos données restent sur des serveurs qui ne nous appartiennent pas.</p><p>Juste par cet exemple, il y a un gros travail à faire sur différentes échelles. Et donc, le mois dernier a été consacré, pour ma part, à repenser ce qu'est ma vie privée et comment je peux la définir. Il est simple de contacter une personne, a partir du moment où quelqu'un a accès à un numéro de téléphone, une adresse email. La question est donc, comment se prémunir pour que je sois en mesure d'être assurer de parler virtuellement à des proches en toute sécurité et confiance, en utilisant des systèmes de cryptographies de bout en bout pour éviter <a href="https://fr.wikipedia.org/wiki/Attaque_de_l%27homme_du_milieu">l'attaque de l'homme du milieu</a> mais aussi de limiter l'impact d'usupation de mon identité grâce à l'utilisation de mot de passe et <a href="https://fr.wikipedia.org/wiki/Double_authentification">authentification à deux facteurs</a> tout en me prémunissant que n'importe qui est accès à mon identité et donc des données qui restent sur internet comme mon adresse email, les <a href="https://fr.wikipedia.org/wiki/Cookie_(informatique)">cookies</a> que j'accèptes sur les sites internets, celle que j'enregistre dans les base de données des sites internet en sauvegardant les informations de mon profil. Et comment réduire cette emprunte pour que les personnes puissent m'identifier, cela fait référence à la possibilité de faire du multi-compte voire des faux comptes en vue de virtualiser son identitées, être atteignable via différents canneaux virtuels, et donc d'être moins sujet à atteinte.</p><p>Cepandant il est possible de faire du multi-compte, comme par exemple proposer différents profils ou faux profils virtuels qui nous identifierait. Cela peut s'avérer énergie-vore et au final on pourrait passer plus de temps à vitualiser son image, plutôt que finalement proposer une seule image propre et réelle qui serait protégée à son unique cercle de connaissance et dans se sens réduire notre emprunte carbone sur Internet. Un interet que j'ai trouvé à faire du multi-compte serait plutôt de prendre l'exemple d'être identifié comme possédant plusieurs facettes, c'est à dire que l'on pourrait définir plusieurs profils nous représentant. En exemple si l'on prend le cas d'une personne qui aime faire de l'aquarelle les soirs et du poney le weekend, du coup cette personne pourrait alors être conduite à dissocier ces deux activités à travers des profils spécialisés qui l'identifieraient. Pour parler de poney à cette personne, il est donc plus approprié de la contacter avec son profil 'poney' et vice versa pour parler d'aquarelle.</p><p>Si l'on creuse cette idée de multi-facette, on retrouve les problématiques de vie privée à travers des réseaux sociaux tels que, pour ne pas le citer, Facebook. En effet, il y a dix ans, Facebook était le précuseur pour connecter les identités des persones. Avec l'accroissement des canneaux d'informations, publiber un publication sur Facebook, c'est potentiellement exposer cette information à toutes les personnes de notre réseau. Et cela ne peut pas forcément être adapté car je n'ai pas forcément envie que tout le monde voit certaines de mes publications. Un solution serait alors de restreindre la portée de chaque publication, ce qui est possible sur Facebook, cepandant, cela peut être aussi prenant (time consuming). Du coup, de nouveaux services se sont développés tels que <a href="https://slack.com">Slack</a> ou <a href="https://discord.com">Discord</a> pour la messagerie instantanés ou <a href="https://mastodon.social">Mastodon</a> un réseau social décentralisé. Ces services ont en commun le fait de décentraliser l'information, notemment en constituant des communautées. Et il y a donc plus de sens d'intégrer plusieurs communautés, pour lesquel il sera possible de partager de manière plus ciblée des informations.</p><p>Après la théorie, la pratique, et partir de cette base, et le mois passé dernier, j'ai expérimenté le fait de réinstaller mon ordinateur, c'est à dire que je l'ai entièrement formaté puis remis un système d'exploitation à neuf. J'ai listé brièvement les étapes que j'ai réalisées et les différents outils que j'ai installé au fur et à mesure qui vont dans le sens de ce je qualifie de &quot;protection de la vie privée&quot;.</p><ul><li>Formater le disque dur avant de réinstaller le système<br />
Lors du formatage du disque dur, il faut penser à cocher la case : &quot;formater plusieurs fois&quot; afin que physiquement le disque dur grave de vrai zéro et éventuellement évite à un individu mal intentionné de retrouver les données précédentes qui n'ont pas été vraiment effacée. Une vidéo à ce sujet peut être vue sur la chaine d'Underscore : <a href="https://www.youtube.com/watch?v=R9RHIa22yms">https://www.youtube.com/watch?v=R9RHIa22yms</a>
Il est aussi possible d'ajouter l'option de crypter le disque dur ce qui permet de sécuriser les données physique. Dans ce cas, il est recommandé d'écrire le mot de passe sur un papier par exemple, au moins d'avoir une trace du mot de passe, sinon il ne sera plus possible de récupérer ses données dans le cas d'oubli du mot de passe.</li><li>Installer une distribution : Debian ou Ubuntu (interface)</li></ul><p class="image"><img src="{{ asset('/blog/images/articles/vie-privee-numerique/linux-introduction.png') }}" alt="Linux introduction" height="100px" class="center" /></p>
Etant sur Mac depuis des années, je pense à migrer sur un système Linux. En effet les système Linux sont a mon sens ceux qui sont les plus transparents pour la vie privée. Etant donné que j'ai réinstallé le système sur MacOs, j'évite de me connecter aux services Apple tel que iCloud. A l'installation, j'igniore tout ce qui n'est pas requis à la configuration. Une autre chose se serait le cas d'utiliser Eternet au lieu du wifi voir de masquer l'accessibilité à son ordinateur à travers différents switch réseau. Et pourquoi pas spécifier le Client ID pour identifier son ID. Plus de détail sur la partie réseau ici : [https://www.techwalla.com/articles/what-is-a-dhcp-client-id](https://www.techwalla.com/articles/what-is-a-dhcp-client-id). Pour identifier son ordinateur sur le réseau, il faut marquer l'adresse Mac et différents outils sur le terminal peuvent aider à avoir des informations : ipconfig, ifconfig, nslookup
- Générer un couple de clef Privée / Public  
En effet, la clef publique et privée est utile pour éviter l'attaque [l'attaque de l'homme du milieu](https://fr.wikipedia.org/wiki/Attaque_de_l%27homme_du_milieu) mais aussi pour signer des messages et assurer à d'autres personnes que vous êtes bien la personne qui a écrit des messages. Un bon livre sur le sujet est [Histoire des codes secrets de Simon Singh](https://www.goodreads.com/review/show/3526124452) qui raconte l'histoire de l'évolution des codes et notement relate de Bob et Alice qui s'échangent des messages en toute sécurité.
Liens utiles à ce sujet :
	- [https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)  
	- [https://docs.ovh.com/fr/dedicated/creer-cle-ssh-serveur-dediees/](https://docs.ovh.com/fr/dedicated/creer-cle-ssh-serveur-dediees/)  
	- ```$ ssh-keygen -t ed25519 -a 256 -C "your_email@example.com"```  
- Gestion des mots de passe  
Les mots de passes sont incontournables, car ils sont utilisés pour se connecter à ses comptes internet. Le meilleur moyen de protéger son mot de passe est sans doute d'utiliser un papier et un crayon et de noter un chaine assez long de caractère. Une autre manière est aussi d'avoir un moyen mémotechnique de retenir son mot de passe en utilisant par exemple la première lettre de mots d'un livre. Dans mon cas, je stoque les mots de passe sous forme de fichier textuel et que j'enregistre dans un disque dur virtuel qui sera protégé par un mot de passe maître.
	- Avec l'utilitaire de disque, créer un disque virtuel exemple 100Mo avec l'utilitaire de disque et mettre un mot de passe maître, au besoin le changer tous les 72 jours.  
	- Optionnellement Installer Keepass : [https://keepass.info](https://keepass.info), EnPass : [https://www.enpass.io](https://www.enpass.io)  
		- Utiliser le NIP pas le touch ID.  
		- How organize your life using a Password Manager : [https://www.enpass.io/blog/how-to/organize-your-life-using-a-random-password-generator/](https://www.enpass.io/blog/how-to/organize-your-life-using-a-random-password-generator/)  
		- Manuel du générateur de mot de passe [https://www.enpass.io/docs/manual-desktop/passgen.html](https://www.enpass.io/docs/manual-desktop/passgen.html)  
	- En ligne de commande, utiliser OpenSSL pour générer des mots de passes  
	- Choisir un mot de passe maître.  
	- Cacher ce mot de passe encodé dans une image par la stenographie : [https://betterprogramming.pub/hide-data-within-an-image-507f571aab89](https://betterprogramming.pub/hide-data-within-an-image-507f571aab89)  
	- Si le mot de passe maître venaît à être compromis, alors en génénérer un nouveau.  
	- S'engager à modifier son mot de passe maître tous les 72 jours et dans le même sens re-générer tous les mots de passes à partir du mot de passe maître.  
	- Authentification double avec un mot de passe : [https://www.youtube.com/watch?v=ZXFYT-BG2So](https://www.youtube.com/watch?v=ZXFYT-BG2So)  
		- Web application qui se base sur l'algorithme RFC 6238 pour générer un ["one time password"](https://en.wikipedia.org/wiki/Time-based_One-Time_Password) toute les 30 secondes : [https://totp.app](https://totp.app)  
		- Github listant des application et plateformes pour utiliser des "One time password" [https://github.com/freeotp](https://github.com/freeotp)  
		- Idéalement un seul bon mot de passe fort peut suffire à ne pas utiliser la double authentification.  
- Installer Signal  
Pour cette partie, il existe différentes messageries, mais dans mon cas, j'utilise signal. Les messages sont chiffrés de bout en bout. Il est aussi important de valider l'identiées des personnes à qui l'on parle lorsqu'on les rencontre et à ce moment là échanger nos clefs d'identification. Cela assure à chacun des partie que l'identitée est bien confirmée.
	- Configurer le NIP, changer d'identifiant si celui venait à être compromis.  
	- Désactiver dans les réglages les accusés de reception, cela est dans les deux sens c'est à dire que vous ne verrez plus les accusés reception des personnes à qui vous écrivez. Mais l'avantage est aussi de   ne pas forcément laisser de trace sur la lecture des message.
	- Par défaut, signal attend 3 heures avant d'interdire de supprimer des messages pour tout le monde. Cela est pas trop mal dans le sens où cela force les participants à être rigoureux dans l'écriture des   messages. Passé 3 heures, il n'est plus possible de supprimer ou éditer les anciens message et donc conserver un historique de conversation sur.
- Installer un Navigateur.  
Sur internet, il existe beaucoup de navigateurs, j'utilisais Brave précédement, mais à mon sens [Librewolf](https://librewolf-community.gitlab.io/install/), un fork de [Firefox](https://www.mozilla.org/fr/firefox/new/) est assez axé sur les problématique de vie privée.
	Conditions de vie privée : [https://www.mozilla.org/fr/privacy/firefox/](https://www.mozilla.org/fr/privacy/firefox/)
	Search Preferences :
	- Préférer le moteur de recherche par défaut comme Quant (Europe) ou DuckDuckGo  
	- Check Search Shotcuts for : Quant, Bookmarks, Tabs, History  
	Privacy & Security Preferences :
	- Check Strict Protection  
	- Always do not Track  
	- Delete cookies and site data when Firefox is closed and add site exceptions si nécessaire.  
	- Add language of your choice : [https://addons.mozilla.org/en-US/firefox/language-tools/](https://addons.mozilla.org/en-US/firefox/language-tools/)  
		- Language issue described here : [https://gitlab.com/librewolf-community/browser/windows/-/issues/64](https://gitlab.com/librewolf-community/browser/windows/-/issues/64)  
	- Ne pas sauvegarder les logins et mots de passe dans les trousseaux de clef, mais préferer les copier coller directement.  
	- Bloquer toutes les permissions telles que l'accès à la Location, Camera, Microphone, Notifications, Autoplay, Virtual Reality. Les réactiver si besoin à l'utilisation.  
	- Ne pas envoyer de données statistique technique de plantage de FireFox à Mozilla. Théoriquement ces données sont anonymisée, donc ce n'est pas forcément une obligation. Mais cela fait tout de même partie de   données envoyée.
	- Naviguer en HTTPS uniquement et interdire HTTP.  
	Tabulation : about:support plein de trucs techniques
	- chercher des extensions : [https://addons.mozilla.org/en-GB/firefox/search/?promoted=recommended&sort=users&type=extension](https://addons.mozilla.org/en-GB/firefox/search/?promoted=recommended&sort=users&type=extension)  
	- Pour activer les extensions, aller dans la tabulation : about:addons et voici quelques extensions recommandées par la team.  
		- uBlock Origin : [https://github.com/gorhill/uBlock](https://github.com/gorhill/uBlock)#ublock-origin  
		- AdBlocker Ultimate : [https://adblockultimate.net](https://adblockultimate.net)  
		- Ghostery – Privacy Ad Blocker : http://www.ghostery.com  
		- Decentraleyes [https://decentraleyes.org](https://decentraleyes.org)  
		- DuckDuckGo Privacy Essentials : [https://duckduckgo.com/app](https://duckduckgo.com/app)  
		- Privacy Badger : [https://privacybadger.org](https://privacybadger.org)  
		- Youtube Audio : [https://github.com/animeshkundu/youtube-audio](https://github.com/animeshkundu/youtube-audio)  
		Optionnals
		- Greasemonkey : [https://addons.mozilla.org/fr/firefox/addon/greasemonkey/](https://addons.mozilla.org/fr/firefox/addon/greasemonkey/)  
		- I don't care about cookies : [https://www.i-dont-care-about-cookies.eu/](https://www.i-dont-care-about-cookies.eu/)  
		- Emoji : [https://www.saveriomorelli.com/projects/emoji/](https://www.saveriomorelli.com/projects/emoji/)  
		- ScrollAnywhere : [https://fastaddons.com](https://fastaddons.com)  
	- [https://apps.apple.com/app/duckduckgo-privacy-browser/id663592361](https://apps.apple.com/app/duckduckgo-privacy-browser/id663592361) private browser for iOS  
- Avoir une boite email respectueuse de la vie privée.  
A ce jour, j'ai trouvé que le service de [https://protonmail.com](https://protonmail.com) me convient. Il y a une offre gratuite, mais je suis rapidement passé sur l'offre payante afin notement de disposer de domaine customisable.
	- nettoyer ses emails : [https://app.clean.email](https://app.clean.email)  
	- choisir une boite email responsable de la vie privée : [https://clean.email/alternatives-to-gmail](https://clean.email/alternatives-to-gmail)  
	- import export contacts : [https://protonmail.com/import-export](https://protonmail.com/import-export)  
- Installer un VPN respecteux de la vie privée, regarder les offres en cours et comparer  
J'utilise NordVPN, mais je songe à passer sur [Proton VPN](https://protonvpn.com) ou [Mozilla VPN](https://www.mozilla.org/en-GB/products/vpn/)
- Installer Git  
Git est un outil en ligne de commande plus spécifique au monde du développement informatique, mais comme il m'est indispensable, je l'ajoute dans la liste. Configurer son email et son nom de manière globale : [https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/setting-your-commit-email-address](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-email-preferences/setting-your-commit-email-address)
- Intaller un logiciel de prise de note.  
Pour ma part j'utlise Joplin et j'avais déjà fait des articles à ce sujet. J'ai activé la synchronisation avec mon serveur NexCloud avec WebDav pour laquelle j'ai utilisé un mot de passe maître servant à encrypter mes données.
- Installer un logiciel de gestion de fenêtre Windows Managment  
j'utilise Rectangle sur Mac qui me permet facilement de manier les disposition de mes fenêtre juste avec le clavier.
- Installer un logiciel de messagerie, pour ma part j'utilise [https://www.thunderbird.net](https://www.thunderbird.net)  
Avec Proton, il est possible d'utiliser [Proton Mail Bridge](https://protonmail.com/bridge/) pour sécuriser la connection entre Thunderbird et Proton Mail.
- Installer un outil de Cloud afin de synchroniser ses données personnelles et professionnelles en toute sécurité.  
Pour ma part, j'utilise [NextCloud](https://nextcloud.com) qui me permet de faire la synchronisation de mes notes, ainsi que de mes fichiers.
- Installer un IDE  
Pour développer, j'utilise [VSCodium](https://vscodium.com) qui est un fork de VSCode, sans la partie envoie des données d'utilisation pour Microsoft. Et à l'ouverture de VSCodium, j'installe aussi l'outil en ligne de commande 'codium' que l'on peut retrouver en tant que script dans la Command Palette.
- Cloud Provider  
Pour ma part, j'utilise maintenant OVH comme Cloud Provider, et pour le moment je suis sur l'offre VPS à 3 euros par mois, suffisante pour mon utilisation. Cela me permet d'héberger mes différents services tels que mon site internet [Darkwood](https://darkwood.fr), mais aussi mon outil d'automation [Uniflow.io](https://uniflow.io), ainsi qu'un logiciel de comptabilité [Dolibarr](https://www.dolibarr.org), un service de statistiques [Matomo](https://fr.matomo.org), un service de visoconférence [Jitsi](https://jitsi.org/).
	- OVH : [https://www.ovh.com/fr/](https://www.ovh.com/fr/) and buy a VPS [https://www.ovhcloud.com/fr/vps/](https://www.ovhcloud.com/fr/vps/) (lowest cost)  
		- First steps with VPS : [https://docs.ovh.com/fr/vps/debuter-avec-vps/](https://docs.ovh.com/fr/vps/debuter-avec-vps/)  
		- Add SSH key to server : [https://docs.ovh.com/fr/dedicated/creer-cle-ssh-serveur-dediees/](https://docs.ovh.com/fr/dedicated/creer-cle-ssh-serveur-dediees/)  
		- Secure your VPS : [https://docs.ovh.com/fr/vps/conseils-securisation-vps/](https://docs.ovh.com/fr/vps/conseils-securisation-vps/)  
		- GESTION, FACTURATION, ASSISTANCE : [https://www.ovh.com/manager/](https://www.ovh.com/manager/)  
		- OBTENIR DE L'AIDE: [https://www.ovh.com/fr/support/knowledge/](https://www.ovh.com/fr/support/knowledge/)  
		- D'autre part, une importante communauté d'utilisateurs est accessible via notre forum et nos mailing-listes : [https://www.ovh.com/fr/support/](https://www.ovh.com/fr/support/)  
		- Protection anti-dos : [https://www.ovh.com/fr/anti-ddos/](https://www.ovh.com/fr/anti-ddos/)  
- Avoir un nom de domaine propre pour s'exposer publiquement  
Acheter un nom de domaine est quelque chose qui peut couter à l'année, mais cela permet d'avoir un espace privé sur internet. Pour choisir un nom de domaine, ainsi qu'avoir un idée du coût à l'année le site [https://www.ovh.com/fr/domaines/](https://www.ovh.com/fr/domaines/) référence des coût par rapport à cette problématique.
	- Personnellement j'utilise le reverse proxy CloudFlare (ou un reverse proxy type Varnish : à compararer) pour masquer l'IP de mon serveur, mettre en cache de données et éviter des attaques.  
- Steamer et faire de vidéos  
J'utliser personnellement OBS, j'avais fait un article à ce sujet sur le blog : [Ce que j'ai appris avec OBS](https://blog.darkwood.fr/article/ce-que-jai-appris-avec-obs)
- Medias  
Section qui a moins à voir, mais les logiciels que j'utilise pour l'édition de médias
	- Dessin : [Krita](https://krita.org)  
	- Production de Musique: j'aime bien [Ableton Live](https://www.ableton.com/) pour la production et composition musicale.  
<ul><li>IOT
<ul><li>Toute clef USB doit être controllée dans un appareil isolé dédié à ca : <a href="https://hogo.eu">https://hogo.eu</a></li><li>Article de Elie on the internet sur le sujet : <a href="https://elie.net/publication/users-really-do-plug-in-usb-drives-they-find/">https://elie.net/publication/users-really-do-plug-in-usb-drives-they-find/</a></li></ul></li><li>Opensource Hosting : Gitlab (https://about.gitlab.com/company/) or Github (Microsoft)<br />
Pour le choix d'open sourcer ses données j'en saurais plus à se sujet lors de ma participation au <a href="https://www.sido-osxp.com">SIDO Paris</a> pour la conférence : <a href="https://www.sido-osxp.com/en/session/405fd218-1e28-ec11-ae72-a04a5e7d345e">Share your code and not your secrets</a><ul><li>An open platform for building developer portals : <a href="https://backstage.io">https://backstage.io</a></li></ul></li><li>Et possiblement trop de vie privée tue la vie privée, car éventuellement plus personne n'arrivera à vous contacter !</li></ul><p>Resources :</p><ul><li>Les coulisses des disques dur : <a href="https://www.youtube.com/watch?v=R9RHIa22yms">https://www.youtube.com/watch?v=R9RHIa22yms</a></li><li>Ten simple steps for keeping your laptop secure : <a href="https://elie.net/blog/privacy/ten-simple-steps-for-keeping-your-laptop-secure/">https://elie.net/blog/privacy/ten-simple-steps-for-keeping-your-laptop-secure/</a></li><li>Linux installation from scratch : <a href="https://wiki.archlinux.org/title/Installation_guide">https://wiki.archlinux.org/title/Installation_guide</a><ul><li>recommandation générales : <a href="https://wiki.archlinux.org/title/General_recommendations">https://wiki.archlinux.org/title/General_recommendations</a></li><li>liste de logiciels pouvant être utilisés dans un OS : <a href="https://wiki.archlinux.org/title/List_of_applications">https://wiki.archlinux.org/title/List_of_applications</a></li></ul></li><li>Graphical linux : <a href="https://wiki.archlinux.org/title/General_recommendations">https://wiki.archlinux.org/title/General_recommendations</a></li><li>Top linux distributions : <a href="https://distrowatch.com">https://distrowatch.com</a><ul><li>manjaro, Ubuntu, popos : ont des installeurs graphiques.</li><li>archlinux, il y a des script, ainsi qu'un installeur graphique pour automatiser ca.</li><li>Liste des programmes nécessaire à un système « minimaliste » : <a href="https://www.fr.linuxfromscratch.org/view/lfs-stable/prologue/package-choices.html">https://www.fr.linuxfromscratch.org/view/lfs-stable/prologue/package-choices.html</a></li></ul></li><li>Tailos <a href="https://tails.boum.org">https://tails.boum.org</a> : a été utilisé par Edouar Snowden et cela aide à assez bien sécuriser sa manière d'être anonyme sur internet en installant la distribution sur une clef USB par exemple.</li><li>Portage des différentes applications et jeux sur Linux : <a href="https://www.protondb.com">https://www.protondb.com</a></li><li>Navigateur internet Librewolf : <a href="https://librewolf-community.gitlab.io/">https://librewolf-community.gitlab.io/</a></li><li>Messagerie :
<ul><li>Elements : messagerie sécurisée pour discuter <a href="https://element.io">https://element.io</a></li><li>Signal : messagerie pour discuter américain : <a href="https://signal.org">https://signal.org</a></li><li>Telegram : messagerie russe : <a href="https://telegram.org/">https://telegram.org/</a></li></ul></li><li>Gestionnaire de mot de passe open source : Keepass XC</li><li>Editeur de texte opensource
<ul><li>Libreoffice <a href="https://fr.libreoffice.org/">https://fr.libreoffice.org/</a></li><li>Openoffice <a href="https://www.openoffice.org/fr/Telecharger/">https://www.openoffice.org/fr/Telecharger/</a></li></ul></li><li>Gestionnaire d'application : <a href="https://opengapps.org">https://opengapps.org</a></li><li>VPN
<ul><li>OpenVPN</li><li>Proton VPN : <a href="https://protonvpn.com/fr/">https://protonvpn.com/fr/</a></li></ul></li><li>Mail &amp; Messagerie
<ul><li>protonmail : <a href="https://www.heidi.news/innovation-solutions/protonmail-remporte-une-victoire-contre-la-surveillance-etatique">https://www.heidi.news/innovation-solutions/protonmail-remporte-une-victoire-contre-la-surveillance-etatique</a></li><li>Courrier postal.</li><li>Pigeon voyageur : <a href="https://en.wikipedia.org/wiki/IP_over_Avian_Carriers">https://en.wikipedia.org/wiki/IP_over_Avian_Carriers</a></li><li>Chiffrer ses messages à la main.</li><li>session pas de mail pas de num rien ca passe par tor</li><li>Signal chiffré de bout en bout, ne connais que le numéro de téléphone et qui tu cherches à contacter. <a href="https://medium.com/@justinomora/">https://medium.com/@justinomora/</a>  demystifying-the-signal-protocol-for-end-to-end-encryption-e2ee-ad6a567e6cb4</li><li>Decentralized network for communication standard : <a href="https://matrix.org/">https://matrix.org/</a></li><li>Share, freely and privately, peer to peer, decentralisée : <a href="https://jami.net">https://jami.net</a></li><li><a href="https://jitsi.org">https://jitsi.org</a>, <a href="https://framatalk.org">https://framatalk.org</a> utilise Jitsi.</li><li>Jabber : XMPP</li><li>Omemo logiciel d'échange en grille informatique (différent de pair à pair): <a href="https://fr.wikipedia.org/wiki/Omemo">https://fr.wikipedia.org/wiki/Omemo</a></li><li>Faire son propre serveur de mail : beaucoup de bots, ne pas se planter sur les DNS</li><li>Protocol de messagerie avec des pigeons : <a href="https://en.wikipedia.org/wiki/IP_over_Avian_Carriers">https://en.wikipedia.org/wiki/IP_over_Avian_Carriers</a></li></ul></li><li>Hébergement
<ul><li><a href="https://www.ovh.com">https://www.ovh.com</a> (france)</li><li><a href="https://www.gandi.net">https://www.gandi.net</a> (france)</li><li><a href="https://www.infomaniak.com/fr">https://www.infomaniak.com/fr</a> (suisse)</li></ul></li><li>Héberger son Opensource
<ul><li>Bypassing required reviews using GitHub Actions : <a href="https://medium.com/cider-sec/bypassing-required-reviews-using-github-actions-6e1b29135cc7">https://medium.com/cider-sec/bypassing-required-reviews-using-github-actions-6e1b29135cc7</a></li><li>GitHub Copilot : ce que reprochent les développeurs à l’assistant de programmation : <a href="https://www.blogdumoderateur.com/github-copilot-reproches-developpeurs/">https://www.blogdumoderateur.com/github-copilot-reproches-developpeurs/</a></li><li>Popular NPM Package Hijacked to Publish Crypto-mining Malware : <a href="https://thehackernews.com/2021/10/popular-npm-package-hijacked-to-publish.html">https://thehackernews.com/2021/10/popular-npm-package-hijacked-to-publish.html</a></li></ul></li><li>Développement de sites internet et sécurité
<ul><li>Bac à sable à outil pour tester les failles de sites internet <a href="https://owasp.org/www-project-juice-shop/">https://owasp.org/www-project-juice-shop/</a></li><li>Plateforme qui indexe les failles de sites internet : <a href="https://leakix.net">https://leakix.net</a></li><li>PENETRATION TESTING PRACTICE LAB - VULNERABLE APPS / SYSTEMS : <a href="https://www.amanhardikar.com/mindmaps/Practice.html">https://www.amanhardikar.com/mindmaps/Practice.html</a></li></ul></li><li>Vie privée, sécurité et gouvernance : <a href="https://www.onetrust.fr/">https://www.onetrust.fr/</a></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/vie-privee-numerique</link><guid>https://blog.darkwood.com/article/vie-privee-numerique</guid><enclosure url="http://darkwood.com/media/articles/63867e7e9314b008912121.png" /></item><item><title>Self-host n8n with AWS Lightsail, pm2 and caddy server</title><pubDate>Wed, 12 Jan 2022 01:15:02 +0000</pubDate><description><![CDATA[
Cette vidéo explique pas à pas comment héberger soi même n8n avec AWS Lightsail, pm2 et Caddy serveur.
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63867f328245f285622657.jpeg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/ts9UPAJDGsM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div><p>Cette vidéo explique pas à pas comment héberger soi même n8n avec AWS Lightsail, pm2 et Caddy serveur.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/self-host-n8n-with-aws-lightsail-pm2-and-caddy-server</link><guid>https://blog.darkwood.com/article/self-host-n8n-with-aws-lightsail-pm2-and-caddy-server</guid><enclosure url="http://darkwood.com/media/articles/63867f328245f285622657.jpeg" /></item><item><title>Crypto Tracker</title><pubDate>Thu, 10 Feb 2022 23:44:30 +0000</pubDate><description><![CDATA[Dans cet article nous allons parler de Bitcoin et de crypto-monnaie.
Et de la création du projet Crypto Tracker.
Cet article n&#039;a pas de vocation à donner des conseils en investissement, faites vos propres recherches.
Le projet est consultable à l&#039;adresse su...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/62ea5127d098f011595561.png" /></p><p>Dans cet article nous allons parler de Bitcoin et de crypto-monnaie.<br />
Et de la création du projet <code>Crypto Tracker</code>.<br />
Cet article n'a pas de vocation à donner des conseils en investissement, faites vos propres recherches.</p><p>Le projet est consultable à l'adresse suivante : <a href="https://github.com/darkwood-fr/crypto-tracker">https://github.com/darkwood-fr/crypto-tracker</a></p><h2>Bitcoin</h2><p>Nous entendons beaucoup parler de Bitcoin. A la base, Bitcoin est une technologie qui permet de résoudre le problème de <code>double transaction</code>. Bitcoin est pour schématiser un Grand live de compte qui est consultable par n'importe qui. Cependant, pour écrire une nouvelle transaction dans ce Grand livre de compte, elle doit être validée et inscrite dans ce qui est communément appelé un <code>bloc</code>. La mise en quinconce des blocs les uns après les autres est communément appelé la <code>blockchain</code> ce qui représente ce Grand livre de compte. Pour valider un nouveau bloc, des <code>mineurs</code> doivent résoudre un algorithme complexe qui s'appelle <code>preuve de travail</code>. La blockchain est alors validée par un phénomène de consensus. Il est cependant difficile pour un seul mineur de fausser la blockchain, car il faudrait acquérir au moins plus de la moitié de la puissance des machines du réseau pour altérer le consensus qui a permis de valider le bloc suivant. C'est pour cela que l'on parle de réseau décentralisé, nous avons à disposition un Grand live de compte, en libre d'accès et dont tout le monde peut se fier.</p><h2>Crypto Tracker</h2><p>J'ai toujours suivit Bitcoin de loin, car Bitcoin depuis sa création est un écosystème spéculatif dans lequel des personnes ont investit des moyens et de l'argent pour faire vivre cette fameuse Blockchain. Lorsque l'on parle de Bitcoin, on ne parle pas de monnaie, mais de crypto-monnaie. Mais depuis l'arrivée des services autour de cette technologie, les <code>smarts contracts</code> tel que l'on en entend parler avec Ethereum, ou les projets Web3 qui prônent le déploiement de services décentralisés, alors investir dans ces actifs donne plus de sens. On peut faire un équivalent avec internet qui est devenu un incontournable aujourd'hui, car de nombreux services sont présents aujourd'hui sur la toile alors que ce n'était qu'un simple réseau d'échange textuel pour les militaires dans les années 1980. Bitcoin reste à ce jour un actif spéculatif, car des problématiques comme la preuve de travail en font une technologie nocive pour l'environnement, bien qu'aujourd'hui le réseau évolue pour réduire l'emprunte carbone en introduisant la <code>preuve d'interêt</code>. Et Bitcoin n'est pas une monnaie validée par les états se qui se traduit que l'achat de bitcoin ou d'une autre crypto monnaie constitue un achat risqué de la même manière que l'on investit de l'argent pour acheter des actions d'une entreprise. Ainsi Bitcoin est soumis à l'imposition dès lors que vous vendez vos crypto-monnaies en argent réel ou que vous achetez des produits ou service de consommation grâce à la crypto monnaie.</p><p>C'est la raison pour laquelle, je me suis intéressé à traquer mon investissement en crypto monnaie. Et dans le cas présent, on parle de portefeuille d'actifs numérique. Ce procédé a deux avantages. Le premier est de tenir un état des comptes de toutes les transactions réalisées sur les plateformes d'échanges et donc de connaître la représentation totale de son actif équivalent d'une valeur de monnaie réelle. C'est finalement un peu comme si vous consultez vos comptes en banque, sauf que dans le cas présent, c'est à vous de faire et tenir le report de toutes les transactions. Le deuxième est de remplir sa feuille d'imposition afin de noter les plus ou moins values réalisées lors de la revente des actifs. Et ce dernier point est, au yeux de la loi Française, obligatoire. Il m'est donc quelque part nécéssaire de réaliser ce projet.</p><p>La formule pour calculer ses plus ou moine value est la suivante :</p><p><code>prix de cession – (( prix total d’acquisition * prix de cession ) / valeur du portefeuille)</code></p><p>Pour expliquer les termes, le prix de cession est le prix auquel vous avez vendu vos crypto monnaie en argent réel. Le prix total d'acquisition est la valeur total que vous avez investi dans l'achat de vos crypto monnaie. La valeur du portefeuille est la valeur de l'ensemble de vos crypto-monnaie convertie en devise d'argent réel.</p><p>Ainsi j'ai crée le projet <a href="https://github.com/darkwood-fr/crypto-tracker">Crypto Tracker</a> pour suivre mon portefeuille numérique. Cela m'a permis de développer une architecture équivalente, dans les grande lignes, de ce que j'ai connu sur Symfony mais cette fois ci en NodeJs :</p><ul><li>typée grâce à l'utilisation de <code>Typescript</code>.</li><li>reproduisant le modèle vue contrôleur avec l'utilisation d'une base de donnée grâce à <code>TypeOrm</code>.</li><li>utilisant un système d'injection de dépendance grâce à <code>typedi</code>.</li><li>mettant à disposition une Api de type OpenAPI grâce à <code>tsoa</code>.</li></ul><p>Ce travail m'a permis de découvrir la bibliothèque <code>ccxt</code> qui se veut uniformiser les plateformes d'échanges, comme par exemple consulter les prix des actifs, voir de développer un bot pour acheter et vendre sa crypto-monnaie à l'aide d'un système d'API proposé par chacune des plateformes. Après avoir étudié tous les formats de chaque plateformes dont je voulais exporter les transactions, et de manière générale, j'ai pu en déduire une modélisation simple de la base de données afin de pouvoir traquer et insérer tous les enregistrements.</p><p>Evidement, il existe de nombreux projets similaire au mien. Mais une bonne partie n'est pas disponible en OpenSource et propose des offres payantes. Par ailleurs en vous inscrivant dessus, vous vous exposer à finalement donner vos données sur vos finances personnelles. Et pour les autres projets en OpenSource, ceux ci ne répondent pas forcément à mes besoins et ne se positionnent pas forcément sur toutes les plateformes d'échanges que je souhaite intégrer. Je suis évidement intéressé sur vos différents retours, et cela me permettra de continuer à itérer et améliorer l'existant.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/crypto-tracker</link><guid>https://blog.darkwood.com/article/crypto-tracker</guid><enclosure url="http://darkwood.com/media/articles/62ea5127d098f011595561.png" /></item><item><title>Utiliser VSCode à distance</title><pubDate>Sun, 16 Oct 2022 10:05:46 +0000</pubDate><description><![CDATA[En tant que développeur et plus précisément pour PHP, j&#039;ai été amené à utiliser PHPStorm en IDE principal. Cependant, Microsoft a redoré son image et se rapproche plus des développeurs en ayant acquéri Github, mais aussi en fournissant un IDE opensource. Ce...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/634c2b557c6c4159971218.jpeg" /></p><p>En tant que développeur et plus précisément pour PHP, j'ai été amené à utiliser PHPStorm en IDE principal. Cependant, Microsoft a redoré son image et se rapproche plus des développeurs en ayant acquéri Github, mais aussi en fournissant un IDE opensource. Cet éditeur c'est VSCode, il est modulaire, cross-platforme et est aussi intégré dans Github. Il faut néamoins revoir son usage, car passer d'un IDE à un autre requière de nouvelles dispositions et habitudes à l'usage. Possiblement un point supplémentaire sur le choix de mon adoption est qu'il est gratuit, alors que PHPStorm nécéssite une license mais mieux packagé dans son écosystème. Il faudra alors naviguer judicieusement dans <a href="https://marketplace.visualstudio.com/VSCode">les extensions du marketplace</a> pour customiser son environnement de développement.</p><p>Dans mon cas, j'utilise un ordinateur de travail sur Ubuntu faisant office de serveur, celui-ci me permet de faire tourner mes services de développement sous Docker. Et c'est là que j'ai découvert le développement à distance pour pouvoir travailler depuis cette machine depuis un autre ordinateur, en l'occurence sur Mac.</p><p>En pratique comment cela fonctionne : la documentation est disponible <a href="https://code.visualstudio.com/docs/remote">VS Code Remote Development</a></p><p><img src="/blog/images/articles/utiliser-vscode-a-distance/architecture.png" alt="architecture" /></p><p>Il y a deux extensions officielle de Microsoft à installer :</p><ul><li><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh">Remote - SSH</a> est l'extension qui permet de configurer et se connecter en SSH sur le serveur distant.</li><li><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh-edit">Remote - SSH: Editing Configuration Files</a> est l'extension qui permet de personnaliser sa configuration à distance en introduisant un onglet intermédiaire <code>Remote</code> entre <code>User</code> et <code>Workspace</code> dans les réglages de VisualStudio. Les règles de surcharge des réglages sont alors <code>Workspace</code> =&gt; <code>Remote</code> =&gt; <code>User</code>.</li></ul><p><img src="/blog/images/articles/utiliser-vscode-a-distance/configurations.png" alt="configurations" /></p><p>Ensuite, il faut pouvoir se connecter en ssh sur la machine distante. J'utilise l'authentification en clef privée, aussi il est interessant de sauvegarder les hôtes via le fichier <code>config</code> de configuration SSH. Cela permet alors de retrouver ces raccourcis dans le <code>Remote explorer</code> et facilement ajouter des projets.</p><p><img src="/blog/images/articles/utiliser-vscode-a-distance/remote-explorer.png" alt="remote-explorer" /></p><p>Si vous utilisez une passphrase sur votre clef SSH, il peut être utile de forwarder l'agent SSH dans le fichier de configuration SSH</p><pre><code>Host myhost.com
  ForwardAgent yes
</code></pre><p><img src="/blog/images/articles/utiliser-vscode-a-distance/ssh-connected.png" alt="ssh-connected" /></p><p>Un des avantages à l'usage est de pouvoir déléguer la charge de calcul sur une machine externe et de pouvoir basculer d'un ordinateur à l'autre ce qui nécessité moins de ressource. Dans mon cas de figure, l'environnement sur MacOS avec VSCode et un navigateur pour le développement.</p><p>Niveau interface, on peut travailler comme si l'on était en local. Même le terminal est connecté sur le serveur distant, ce qui permet d'executer des commandes directement dessus.</p><p><img src="/blog/images/articles/utiliser-vscode-a-distance/ui.png" alt="ui" /></p><p>Par contre, difficile d'accéder aux fichier distants, on a seulement l'option de téléchargement disponible en menu contextuel. Pour cela j'ai installé sur le serveur Ubuntu le service samba pour lequel j'ai accordé les permission d'écriture (remplacer <code>an_user</code> par votre utilisateur)</p><pre><code>$ apt-get install samba
$ sudo smbpasswd -a an_user (MOT DE PASSE)
$ sudo nano /etc/samba/smb.conf
[an_user]
comment = User an_user
path = /home/an_user
valid users = an_user
public = no
writable = yes
$ sudo service smbd reload # on reload du service Samba
</code></pre><p><img src="/blog/images/articles/utiliser-vscode-a-distance/smb-connect.png" alt="smb-connect" /></p><p>Pour être encore plus indépendant de la machine, on pourrait aussi considérer allumer le serveur à distance grâce au NetBoot, voir se configurer et se connecter sur un serveur dédié virtuel.</p><p>N'hésitez pas à partagez vos suggestions.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/utiliser-vscode-a-distance</link><guid>https://blog.darkwood.com/article/utiliser-vscode-a-distance</guid><enclosure url="http://darkwood.com/media/articles/634c2b557c6c4159971218.jpeg" /></item><item><title>NoCode avec le projet Capsule Corp</title><pubDate>Fri, 06 Jan 2023 12:33:08 +0000</pubDate><description><![CDATA[
Ca(psule) Airtable | Integromat | Make | Seninblue
Adresse du projet : https://capsule-corp.softr.app
Le concept du projet est de réaliser un MVP afin de vérifier la capacité à interconnecter des outils No-Code

Airtable (https://airtable.com) : permet de...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/63b82b78391f9834578116.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/6uaJEdotMB8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div><h2>Ca(psule) Airtable | Integromat | Make | Seninblue</h2><p>Adresse du projet : <a href="https://capsule-corp.softr.app/">https://capsule-corp.softr.app</a></p><p>Le concept du projet est de réaliser un MVP afin de vérifier la capacité à interconnecter des outils No-Code</p><ul><li>Airtable (<a href="https://airtable.com/">https://airtable.com</a>) : permet de créer une base de donnée flexible</li><li>Softr (<a href="https://www.softr.io/">https://www.softr.io</a>) : permet de mettre à disposition une landing dynamique connectée à Airtable</li><li>Make (<a href="https://make.com">https://make.com</a>) : permet d’automatiser et d’interconnecter des services</li><li>Sendinblue (<a href="https://sendinblue.com">https://sendinblue.com</a>) : permet de gérer des campagnes de mailing automatique.</li></ul><h2>Fonctionnement du MVP</h2><p>Il est important de bien structurer les données, pour cela un espace <strong>Capsule</strong> a été crée sur <strong>Airtable</strong> et découpé en 5 tables</p><ul><li><em>APOD</em> : recueil la liste des &quot;picture of the day&quot; de la NASA ainsi qu’une vue spécifique pour afficher l’image du jour</li><li><em>News</em> : recueil la liste des articles d’actualité sur l’espace</li><li><em>Leads</em> : recueil la liste des inscriptions par email à la newsletter</li><li><em>Leads Form</em> : recueil les demandes d’inscription / désinscription à la newsletter via un formulaire Airtable : <strong>Mettez à jour vos préférences</strong></li><li><em>Contact</em> : La table de soumission des inscriptions au formulaire de contact.</li></ul><p>Afin de dynamiser la remontée de données, plusieurs scénarios ont été crées sur <strong>Make</strong></p><ul><li><em>APOD Sync</em> : Une requête est lancée vers L’api n°1 de la NASA <a href="https://api.nasa.gov/">https://api.nasa.gov</a> et les données sont enregistrées sur la table <em>APOD</em> de Airtable. Le scénario se lance quotidiennement.</li><li><em>News Sync</em> : Une requête est lancée vers L’api n°2 des news <a href="https://newsapi.org/docs/get-started">https://newsapi.org</a> avec une recherche sur le mot clef <em>space</em> et sont enregistrés de manière unique dans la table <em>News</em> de Airtable. Le scénario se lance quotidiennement.</li><li><em>Newsletter Email Subscribe</em> : Un webhook attend l’envoie des données du formulaire d’inscription à la newsletter. L’email sera ajouté aux enregistrements de la table <em>Leads</em> ainsi que dans la liste NASANEWS de Sendinblue</li><li><em>Manage Newsletter Email Subscription</em> : Lorsqu’un utilisateur soumets le formulaire Airtable. Le hash correspondant à l’enregistrement du <em>Lead</em> est trouvé et est mis à jour sur Airtable. Ensuite l’email est mis à jour dans la liste NASANEWS de Sendinblue selon le souhait de l’utilisateur à s’inscrire ou désinscrire des newsletters.</li><li><em>Send Daily Newsletter</em> : Un aggrégat des actualités de la table <em>News</em> est réalisé et un email est envoyé avec le connecteur Sendinblue pour chacun des emails ajoutés dans la liste NASANEWS</li><li><em>Contact form submission</em> : Un webhook attend l’envoie des données du formulaire d’inscription au formulaire de contact. Ceux ci seront ajoutés à la table <em>Contact</em> sur Airtable.</li></ul><p>Pour réaliser l’envoie de mail, deux templates ont été ajouté sur <strong>Sendinblue</strong></p><ul><li><em>Welcome Email</em> : Ce template affiche un message de bienvenue. Dans la partie automation, un mail est automatiquement envoyé dès lors qu’une nouvelle inscription s’ajoute dans la liste NASANEWS des contacts.</li><li><em>Daily News</em> : Ce template affiche une liste d’article. C’est grâce à l’automatisation <em>Send Daily Newsletter</em> qu’il est possible d’envoyer dynamiquement les données des derniers articles en paramètre du template et cela pour chaque contact dans la liste NASANEWS.</li></ul><p>Pour tester les envois d’email, <a href="https://temp-mail.org/">https://temp-mail.org</a> permet de générer dynamiquement une adresse mail aléatoire et de réceptionner les messages.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/nocode-avec-le-projet-capsule-corp</link><guid>https://blog.darkwood.com/article/nocode-avec-le-projet-capsule-corp</guid><enclosure url="http://darkwood.com/media/articles/63b82b78391f9834578116.jpg" /></item><item><title>Changer de gestionnaire de mot de passe</title><pubDate>Sat, 18 Mar 2023 23:15:26 +0000</pubDate><description><![CDATA[Un gestionnaire de mot de passe est un utilitaire, une application ou un service qui vous permet de mémoriser et organiser vos mots de passe.
Aujourd&#039;hui, j&#039;utilise déjà un gestionnaire de mot de passe Enpass. Cet utilitaire est bien pratique car je peux au...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/641817b14659d743156058.jpeg" /></p><p>Un gestionnaire de mot de passe est un utilitaire, une application ou un service qui vous permet de mémoriser et organiser vos mots de passe.</p><p>Aujourd'hui, j'utilise déjà un gestionnaire de mot de passe <a href="https://www.enpass.io">Enpass</a>. Cet utilitaire est bien pratique car je peux aussi synchroniser mes données de façon sécurisée via mon serveur où j'ai hébergé <a href="https://nextcloud.com">Nextcloud</a>. J'ai même acheté la version premium afin de pouvoir l'utiliser pleinement sur mobile, car la version lite ne permet que d'utiliser les 10 premiers mots de passes.</p><h2>Pourquoi changer de gestionnaire de mot de passe ?</h2><p>Bien que cet utilitaire fait son boulot, une problématique qui revient au quotidien est pour ma part de l'ordre de l'utilisabilité.
En effet, Enpass c'est avant tout une application que vous installez sur votre ordinateur, il faut que celle ci soit ouverte pour interagir et déverouiller la session installée sur votre Navigateur via <a href="https://www.enpass.io/downloads">l'extension</a>. Il faut avoir le client de bureau ouvert, puis de valider l'étape de connection entre le client et l'extension navigateur. Cette opération revient assez régulièrement pendant mes journées, puisque EnPass se verrouille au bout de 5 minutes (réglage par défaut), il faut alors renouveler le processus à chaque fois que je souhaite remplir automatiquement mes identifiants de connections et cela m'est très pénalisant.</p><p><img src="/blog/images/articles/changer-de-gestionnaire-de-mot-de-passe/enpass-client-connect.png" alt="enpass-client-connect" /></p><h2>Comparons les solutions existantes</h2><p>Cela commençais à me préoccuper et c'est vrai que je commençais à avoir le sujet de changer à nouveau de gestionnaire de mot de passe. Cela n'est pas mince affaire étant donné que choisir un autre gestionnaire de mot de passe est quelque chose qui prend du temps, dans le sens où il faut s'assurer que ces données restent bien sous son contrôle et éviter une fuite de tous ses mots de passes sur le web, qu'il faut faire une migration de l'ancien vers le nouveau et être satisfait du nouveau gestionnaire de mot de passe. J'étais tombé il y a quelques semaines justement sur <a href="https://twitter.com/gchampeau/status/1621507185560911873">un Tweet de Guillaume Champeau sur le sujet</a></p><div class="d-flex justify-content-center"><blockquote class="twitter-tweet"><p lang="fr" dir="ltr">Vous auriez des recommandations de bons gestionnaires de mots de passe européens ?</p>&mdash; Guillaume Champeau (@gchampeau) <a href="https://twitter.com/gchampeau/status/1621507185560911873?ref_src=twsrc%5Etfw">February 3, 2023</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div><p>Après avoir lu les réponses des internautes sur le sujet il en ressort pas mal de solutions :</p><ul><li>Ton cerveau : Non, ce n'est pas une solution que j'ai retenue, j'ai pas assez de mémoire pour retenir tous les mots de passes selon les sites que j'utilise.</li><li>Le bloc note : ok, c'est super sécurisé et biodégradable, mais cela ne correspond pas à mes attentes pour remplir les formulaires automatiquement et puis je préfère avoir une version numérique de mes mots de passes.</li><li><a href="https://keepass.info">Keepass</a> : je dirais ok pourquoi pas, car c'est tout de même la solution libre qui a fait ses preuves dans le monde Linux depuis des années. Le problème pour ma part c'est que je n'en voit pas une utilisation uniformisée, le stockage est normalisé, mais pour les clients (Desktop cross-platforme et Mobile) il y a de tout. Il n'y a pas une seule façon d'utiliser le logiciel : compter 7 applications différentes pour iPhone ! Et énormément de <a href="https://keepass.info/plugins.html">plugins</a> à installer au cas par cas. Pour ma part, je souhaite une solution uniforme clef en main.</li><li><a href="https://www.dashlane.com">Dashlane</a> : Globalement <a href="https://www.dashlane.com/fr/pricing">il faut payer</a> pour juste utiliser plusieurs appareils synchronisés, le code n'est pas OpenSource et on ne sait pas trop où sont stockées nos données.</li><li><a href="https://www.lesspass.com">Lesspass</a> : Ok sur le principe, un mot de passe maître pour les avoir tous. Mais dans mon utilisation, je préfère des mots de passes dédiés pour chaque sites, que se passe-t-il par exemple si je dois changer de mot de passe sur un site passé une période ? Puis comment je sauvegarde des notes sécurisées ? Je préfère tout de même une utilisation avec une base de données.</li><li><a href="https://www.icloud.com/">iCloud</a> : Oui c'est vrai que ca m'a fait sourire, j'aime bien Apple, mais pas de là à leur confier la gestion de mes mots de passes puis cette utilisation n'est que valable sur les appareils Apple, j'ai aussi besoin d'avoir un support sur d'autres plateformes.</li><li><a href="https://www.mozilla.org">Firefox</a>, <a href="https://www.google.com/intl/fr_fr/chrome">Google Chrome</a> : Pour ce point j'ai coché la case dans les préférences pour ne pas stoquer de mots de passes dans mon navigateur. C'est fini la synchronisation des mots de passes sur navigateur, ces données ne vous appartiennent pas et sont stoquées sur des serveurs.</li><li><a href="https://cozy.io">Cozy Cloud</a> : C'est vrai que j'ai hésité, et je ne connais pas, mais j'utilise déjà <a href="https://nextcloud.com">Nextcloud</a> pour l'hébergement de fichiers et <a href="https://joplinapp.org">Joplinapp</a>. Il y aurait en plus une synchro des comptes bancaires avec Cozy Bank. Je connais pas assez et peut être cela est bien, mais peut être que je préfère une solution dédiée à la gestion de mots de passes.</li><li><a href="https://www.enpass.io">Enpass</a> : Le gestionnaire de mot de passe que j'utilise déjà de manière courante et dont je souhaite évoluer pour les raisons d'UX que j'ai évoquées en introdution. D'ailleurs je suis étonné que peu de personne n'en parle vraiment.</li><li><a href="https://1password.com">1password</a> : Le gestionnaire de mot de passe que j'utilisait avant de passer sur Enpass. Je pense qu'a l'époque c'était encore gratuit.</li><li><a href="https://proton.me">Proton</a> : Quelqu'un a lancé un Proton Privacy et le compte officiel a répondu qu'il serait surement sur le coup. J'utilise Proton comme messagerie actuelle, mais j'imagine que leur offre portera sur un usage centralisé sur leur serveur. A voir ce qu'il auront à proposer, pour le moment je préfère rester sur un gestionnaire de mot de passe où je contrôle mes données.</li><li><a href="https://bitwarden.com">Bitwarden</a> : On y arrive, une des solutions les plus cités et pour le coup je m'y suis interessé de plus près. En vrai, ce pourrait être une solution retenue, cepandant en regardant le <a href="https://github.com/bitwarden/server">code github</a> pour l'auto-hebergement, c'est fait en C# et pour ma part, il faudrait installer les outils microsoft sur mon serveur pour compiler l'application nativement. Il c'est plus simple de passer par docker pour installer l'outil, cepandant, cela crée un overhead que je ne souhaite pas.</li><li><a href="https://github.com/dani-garcia/vaultwarden">Vaultwarden</a> : Oui pourquoi pas c'est l'alternative &quot;non-officielle&quot; de Bitwarden écrite en Rust. Mes félicitation au(x) développeur(s) qui en a(ont) fait une application à part entière, mais ce serait tout de même plus cool si cela était intégré à Bitwarden.</li><li><a href="https://www.passbolt.com">Passbolt</a> : Ce serait l'équivalent de Bitwarden, cepandant pour un usage orienté en entreprise sur la gestion fine des droits lorsque je compare les plans entre <a href="https://bitwarden.com/pricing">Birtwarden</a> et <a href="https://signup.passbolt.com/pricing/pro">Passbolt</a>. Par ailleurs Bitwarden est encrée au US alors que Passbolt est Européen, mais les deux sont compilant RGPD.</li></ul><p>Mon choix est porté sur Passbolt.</p><h2>Installation</h2><p>Côté serveur, l'installation serveur auto-hébergée est disponible sur un <a href="https://help.passbolt.com/hosting/install">large panel de plateforme</a> et le code est écrit en PHP. Derrière l'installation automatique, c'est aussi Nginx qui est utilisé, cependant, mon serveur utilise <a href="https://caddyserver.com/">Caddy</a> qui a la particularité par exemple d'utiliser une configuration simplifiée et de gérer automatiquement les certificats SSL. J'ai choisi de faire l'installation <a href="https://help.passbolt.com/hosting/install/ce/from-source.html">&quot;From source&quot;</a>. En suivant les pré-requis, il a fallut que j'ajoute l'extension <a href="http://php.net/manual/en/gnupg.installation.php">PHP-GnuPG</a> sous Debian et PHP-FPM avec la commande</p><pre><code class="language-bash">$ apt-get install -y php8.1 php8.1-fpm php8.1-{bz2,curl,intl,mysql,readline,xml,gd,mbstring,zip,bcmath,gnupg}
</code></pre><p>Puis que j'ajoute une configuration propre à Caddy-serveur</p><pre><code>$ nano /etc/caddy/Caddyfile

[nom-de-domaine].[ext] {
    root * /var/www/[nom-de-domaine].[ext]/webroot
    php_fastcgi 127.0.0.1:9000
    encode gzip
    file_server
    log {
        output file /var/log/caddy/[nom-de-domaine].[ext].log
    }
}
</code></pre><p>Ensuite, j'installe le dépot du serveur par une simple commande Git</p><pre><code class="language-bash">$ cd /var/www
$ git clone git@github.com:passbolt/passbolt_api.git
</code></pre><p>Et comme expliqué dans <a href="https://help.passbolt.com/hosting/update/source.html">la mise à jour de Passbolt</a>, je vérifie les droits de mes dossiers et je sélectionne la dernière version tagué qui a été releasé par l'équipe. A l'heure où j'écris l'article, c'est la version <code>v3.12.0</code></p><pre><code>$ git checkout tags/v3.12.0
</code></pre><p>Puis je vérifie que tout est bon par la commande</p><pre><code class="language-bash">$ bin/cake passbolt healthcheck
</code></pre><p>Au passage, n'oubliez pas de créer vos clefs JWT avec la commande</p><pre><code class="language-bash">$ bin/cake passbolt create_jwt_keys
</code></pre><p>Elles sont utiles par exemple lorsque vous souhaitez vous connecter depuis l'application mobile. Dans le cas contraire, vous aurez un message <code>HTTP Forbiden</code> à la connection mobile si vous oubliez de faire cette étape.</p><p>Enfin, je me connecte à l'interface de l'administration depuis l'url du serveur <code>https://[nom-de-domaine].[ext]</code>. Et j'ai l'affichage d'accueil pour finir la configuration.</p><p><img src="/blog/images/articles/changer-de-gestionnaire-de-mot-de-passe/web-installer-getting-started.jpg" alt="enpass-client-connect" /></p><p>Concernant les étapes propre à l'installation, vous pouvez les <a href="https://help.passbolt.com/hosting/install/ce/debian/debian.html">retrouver directement sur le site</a>. Vous devez aussi avoir un serveur SMTP sous la main, car les emails sont utilisés pour vous connecter depuis d'autres ordinateurs.<br />
Aussi par rapport à la migration de Enpass vers Passbolt, elle n'est pas gérée à l'heure actuelle. Cependant, j'ai pu modifier l'export CSV de Enpass afin de me conformer aux exemple de <a href="https://help.passbolt.com/faq/start/import-passwords">format d'import attendu par Passbolt</a>.<br />
Ce que j'aurai aussi aimé ce serait d'avoir accès à l'écriture de notes cryptées, mais cette feature est déjà prévue dans <a href="https://www.passbolt.com/roadmap">la roadmap du projet</a>.<br />
J'aimais bien l'auto soumission du formulaire de connection avec Enpass, j'espère qu'elle arrivera aussi sur Passbolt.</p><p>Vous pouvez aussi activer la fonctionnalité auto-fill depuis votre mobile</p><p class="d-flex justify-content-center"><img src="/blog/images/articles/changer-de-gestionnaire-de-mot-de-passe/mobile-autofill.jpg" alt="mobile autofill" style="height: 677px"></p><p>Enfin, il faut aussi penser à mettre en place <a href="https://help.passbolt.com/hosting/backup/from-source.html">le système de backup</a> au cas où votre serveur venait à tomber en panne, ce qui vous ferait perdre tous vos mots de passe et a priori, ce n'est pas désiré.</p><p>Et vous, utilisez vous un gestionnaire de mot de passe et si oui, lequel ? Vos retours sur le sujet sont les bienvenus.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/changer-de-gestionnaire-de-mot-de-passe</link><guid>https://blog.darkwood.com/article/changer-de-gestionnaire-de-mot-de-passe</guid><enclosure url="http://darkwood.com/media/articles/641817b14659d743156058.jpeg" /></item><item><title>Y-Combinator en PHP</title><pubDate>Tue, 25 Apr 2023 23:18:32 +0000</pubDate><description><![CDATA[
La présentation liée à l&#039;article :

Présentation du Y-Combinator
Pour faire un peu d&#039;auto-promotion, j&#039;avais présenté un talk sur le Railway-Flow-Based-Programming récemment renommé en Flow. C&#039;est un système de pipeline qui fait s&#039;emboiter les processus le...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/644847085e6b4091653490.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/QSS_ZcO8Q1g" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe></div><p>La présentation liée à l'article :</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/237a83878db248e8a7163e5e07a21f61" title="Y-Combinator in PHP" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;" data-ratio="1.78343949044586"></iframe></div><h2>Présentation du Y-Combinator</h2><p>Pour faire un peu d'auto-promotion, j'avais présenté un talk sur le Railway-Flow-Based-Programming récemment renommé en Flow. C'est un système de pipeline qui fait s'emboiter les processus les uns après les autres. Sans rentrer trop dans les détails, je vous invite à revoir <a href="/article/php-railway-flow-based-programming">le talk que j'avais donné à l'AFUP Rennes</a>. Il me manquait quelque chose dans cette conception qu'il manquait à ce modèle. C'est ce qu'on l'on retrouve dans tous les langage de programmation objet et ici c'est de savoir comment introduire de la récursivité. C'est ce que propose le Y-Combinator, c'est à dire comment introduire de la récursivité dans un langage qui n'a pas de mécanisme de recursion.</p><p>Alors pourquoi se poser une telle question alors qu'on a déjà des notions de récursivité en PHP. Ici on a un exemple itératif et fonctionnel de cette récursivité si je prends pour exemple la fonction de factorial.</p><p>Et bien dans cet exemple, si je prend un système de pipe schématisé sous cette forme et encodée en PHP, je n'ai pas cette notion de récursivité. En effet, sur ce simple schéma, je vais aller de haut en bas mais jamais je pourrais avoir une manière de revenir en arrière grâce à une forme de récursivité. C'est cette notion qui manque dans cette notation afin de pouvoir écrire n'importe quel type de programme.</p><p>Avant de parler de ce concept, nous allons devoir introduire le concept sous-jacent qu'est le Lambda Calculus. On va alors parler de trois choses : qu'est ce que c'est, pourquoi c'est utile et d'où est ce que ce concept viens. On va d'abord s'intéresser aux origines du Lambda Calculus.</p><p>Voici Alozon Church qui était un mathématicien dans l'université de Princeton aux États Unis. Il est la personne qui a inventé le lambda-calculus. Ce qui l'intéressait était de savoir quelle est la notion de fonction dans le domaine du calcul informatique.</p><p>Ce qui est interessant c'est qu'il a été le superviseur de Alan Turing, vous connaissez sans doute, c'est la personne qui a inventé la machine de Turing qui est la base de toute l'informatique. Ce qui est remarquable c'est que La machine de Turing est un modèle à état et le concept fonctionnel Lambda-Calculus sont tous les deux des modèles équivalents. C'est ce qu'on appelle la thèse Church-Turing.</p><p>Pour Church, une fonction est une boite noire qui ne permet pas de regarder à l'intérieur. Ce qu'elle fait c'est de prendre des inputs puis d'en sortir des output. Dans notre cas, nous avons <code>X</code> en entrée et la boite noire va produire <code>X+1</code>. Aussi on introduit la notation lambda qui représente ce fonctionnement. Ici on a la représentation <code>λ x . x + 1</code> traduit sous la forme lambda de <code>X</code> produit <code>X + 1</code>. Et on peut substituer avec des variables, si je prends 5, alors 5 appliqué à <code>(λ x  . x + 1)</code> devient <code>(λ x . x + 1) (5) = 5 + 1 = 6</code>.</p><p>Maintenant on peut aussi prendre l'exemple avancé avec deux entrée X et Y. Et a travers la boite noire, on va produire X+Y par exemple. Deux points important ici :</p><ul><li>nous avons des fonctions dite boite noire pour lesquels nous ne pouvons pas savoir comment elles fonctionnent à l'intérieur. Dit d'une autre manière on peut mettre quelque chose en entrée et voir quel sera le résultat en sortie.</li><li>nous avons des fonction pures, c'est à dire qu'elle n'ont pas d'état interne, tout se produit lorsque l'on introduit des paramètres en entrée qui ressortent les mêmes résultats.</li></ul><p>Dans le lambda-calcul, on retrouve des éléments concernant les déclarations de variables, une manière de construire des fonctions et finalement un écosystème qui reste inclus dans lui même. Tout ce qui sera dérivé du lambda-calcul sera construit à partir de ce propre language.</p><p>Quels sont les cas simple appliqués au lambda calculus.
Ici, comment je code true ? Comment je code false ?</p><p>En PHP classique, on aurait une implémentation tel qu'on la connait habituellement avec un if.
Alors comment va-t-on représenter cette forme dans la notation lambda ? Une idée ?
Dans la notation lambda, c'est pas exactement cela, comme on se place dans un environnement fonctionnel, il faut traduire qu'un élément est transformé en vrai ou faux selon l'application de la fonction lambda.</p><p>Ce qui nous donne sans rien inventer, en lambda, true et false est représenté de la sorte :</p><p><code>True  = λ x . λ y . x</code> et <code>False = λ x . λ y . y</code></p><p>Pour traduire, si l'on a deux elements x et y en entrée, alors pour true, on ne produit que x. De même pour false, avec deux elements x et y en entrée, alors on ne produit que y.</p><p>On pourrait avoir une représentation traduite de la sorte en PHP. Je vais décrire une fonction true et false qui prennent en argument deux éléments que l'on assimile à x et y et l'on retourne respectivement x et y en résultat.</p><p>De même comment implémente-t-on la la négation à savoir not ?</p><p>En PHP classique, nous aurions une variable booléenne et on applique l'opérateur &quot;point d'exclamation&quot; devant la variable qui applique la négation de la valeur et est affectée à la variable $not.</p><p>En lambda-calculus, on va avoir la représentation suivante :</p><p><code>Not  = λ b . b False True</code></p><p>Cette représentation je ne l'ai pas inventée et n'est pas intuitive à comprendre au premier abord, nous allons la décomposer et voir ensemble comment elle s'applique.</p><p>Lorsqu'on applique une valeur True à la représentation, alors on va l'appliquer cette valeur en interpretant b en True ce qui nous donne True False True. Cependant, nous avons vu plus haut que True était <code>λ x . λ y . x</code>
En appliquant cette représentation à False et True en paramètre, on obtient alors x qui se substitue à False et y qui se substitue à True. Or le résultat est x, donc on obtient tout simplement False.</p><p>Si on devait représenter not en PHP, alors on obtiendrait $not une fonction de paramètre attendant un boolean <code>$true</code> ou <code>$false</code> et prend en argument <code>$true</code> et <code>$false</code>. Ici on a les fonction <code>$true</code> et $false que nous avons énuméré dans les définitions précédentes.</p><p>Maintenant que l'on a défini des éléments du langage Lambda, revenons à cette notion de récursivité et prenons un exemple de la fonction récursive Factorielle. La récession est l'idée de définir des éléments en terme d'eux même.
La manière dont fonctionne Factorial est de donner un nombre comme par exemple 3. Et il y aura un décompte de 3 à 1 en multipliant tous les nombres entre eux. Par définition, si je prends la factorielle de 3, on aura Factorielle de <code>3</code> est <code>3 * 2 * 1 = 6</code>
On peut alors se demander comment définir cette fonction. Il se trouve que la fonction Factorial a une définition simple et naturelle grâce à la recursion, c'est à dire définir une fonction en terme d'elle même.</p><p>Autrement dit, on peut écrire la factorielle de n'importe quel nombre n étant :</p><ul><li>1 si n est 1</li><li>n * fac(n - 1) si n est plus grand que 1</li></ul><p>C'est la multiplication du nombre n par le factoriel de son prédécesseur.Nous venons de définir une fonction récursive, car Factorial est alors définie en terme d'elle même.</p><p>Voici un exemple simple de son execution, afin de mieux comprendre comment cela fonctionne.
Ce qui nous donne en décomposant la factorielle en executant de manière récursive.</p><p><code>Fac(3) = 3 * Fac(2) = 3 * 2 * Fac(1) = 3 * 2 * 1 = 6</code></p><p>Nous venons de voir que la clef de la recursion est de définir une fonction qui se définie à travers elle même. La question est maintenant de savoir comment on défini la recursion dans un langage qui n'a pas d'éléments de langage sur la recursion. Pour cela on va se placer dans la plus simple des définitions que l'on pourrait penser, ce serait d'écrire une représentation de la fonction Loop, un fonction qui s'appelle elle même.</p><p>On peut partir du principe en lambda que Loop va s'appliquer à elle même et donc Loop = Loop.
Si l'on essaye d'executer cette fonction, quelle serait la valeur de Loop, en se référent à sa c'est simplement Loop, donc l'application de Loop, nous mêne à Loop et c'est de cette manière que l'on construit la récursivité.
Comment peut-on alors encoder cette définition en représentation dans le langage lambda calculus?</p><p>Pour donner la solution, on calcule</p><p><code>Loop = ( λ x . x . x ) ( λ x . x . x )</code></p><p>La clef derrière cette formule est &quot;self-application&quot;. C'est l'idée d'appliquer quelque chose à elle même, et dans notre cas, appliquer une fonction à elle même.
Encore une fois cette formule qui sort un peu du chapeau peut s'expliquer pas à pas.
La première chose à observer est que l'on a deux fonctions ici et dans notre cas, deux copies de la même fonction. Si nous regardons la fonction à gauche et celle à droite, ce sont exactement les deux mêmes fonctions.</p><p>Ce que l'on va faire ici est d'appliquer la fonction al elle même. C'est l'idée du &quot;self-application&quot; que l'on vient de mentionner et c'est la clef pour faire de la récession dans un langage qui n'a pas de recursion. Que donne l'execution ? Si l'on se place en tant que fonction, la première fonction prend un input, comme x et dit ce qu'elle va produire comme résultat avec x. Dans notre cas, la fonction prend un x et en produit deux copies côtes à côtes. Dans le cas présent, x est représenté par <code>( λ x . x . x )</code> en tant qu'argument de la fonction <code>( λ x . x . x )</code>. Si on applique <code>( λ x . x . x )</code> en argument à elle même, alors on va substituer deux fois les x dans la formule à la valeur <code>( λ x . x . x )</code>.</p><p>Ainsi la formule devient</p><p><code>Loop = ( λ x . ( λ x . x . x ) . ( λ x . x . x ) ) = ( λ x . x . x ) ( λ x . x . x )</code></p><p>Et Loop est égale à la valeur précédente, on a bien cette notion de récursivité.
Nous venons de vois que l'on retombe sur exactement la même représentation vu plus haut. Et à nouveau, on peut executer le processus à l'infini, si on ré-applique la fonction avec elle même, on retombe de manière infinie sur le même résultat. De cette manière nous venons de définir cette idée de boucle.</p><p>De manière plus générale, nous allons chercher une représentation de la fonction qui s'appelle récursivement elle même ? Dans notre cas, nous souhaitons trouver une formule de la forme</p><p><code>Y ( f ) = f ( Y ( f ) ) = f ( f ( f ( f ( ... ) ) ) )</code></p><p>Que fait cette définition, nous pouvons voir dans un premier temps que <code>Y ( f )</code> est récursive, car <code>Y ( f )</code> est définie dans les terme de sa propre définition <code>Y ( f )</code>. Mais, ce n'est pas seulement une boucle à travers <code>Y ( f )</code>, mais une boucle à travers f. Donc si on étend son execution on aura l'appel infini <code>f ( f ( f ( f ( ... ) ) ) )</code>. C'est ce qu'on appelle la récession général, c'est le pattern le plus général que vous pouvez trouver. Et toute fonction peut être encodée en terme de celle ci. Donc, si nous pouvons définir Y dans le lambda calculus, alors nous pouvons définir n'importe quelle fonction récursive.</p><p>Quelle valeur on va trouver dans Y pour la fonction Loop ?</p><p>Pour cela on va reprendre un peu ce qu'on a mentionné plus haut avec Loop. On va chercher <code>Loop = Y ( λ x . x )</code> qui en s'executant devient <code>( λ x . x ) ( Y ( λ x . x ) )</code> et boucle sur elle même en devenant elle même et garde la même forme à savoir <code>( λ x . x ) ( Y ( λ x . x ) )</code></p><p>Qu'en est-il pour la fonction factoriel Fac en fonction de Y ?</p><p>Si je reprends la fonction factorielle, on aura un résultat qui ne s'invente pas, c'est <code>Fac = Y ( λ f . λ n . ? )</code> et ce qu'on trouve dans &quot;?&quot; c'est <code>max(n , 1) * fac( n - 1 )</code>. Alors on écrira la factorielle dans sa représentation récursive <code>Fac = Y ( λ f . λ n . max(n , 1) * fac( n - 1 ) )</code></p><p>De manière générale, toute fonction récursive s'écrit sous la forme</p><p><code>Y = λ f ( λ x . f ( x  x ) ) ( λ x . f ( x  x ) )</code></p><p>C'est une définition possible parmi toutes les définitions de Rec dans le langage du lambda calculus. Et c'est quelque chose que l'on appelle Y-Combinator. Ce qui est remarquable, c'est que l'on retrouve dans sa définition des éléments de Loop en terme de structure, c'est l'idée que l'on retrouve avec le principe de &quot;self-application&quot;. Rec n'est pas récursive, mais encode la récursion.</p><p>Maintenant revenons en PHP. voici le code PHP de la fonction Y-combinator qui prend une fonction $F en paramètre, et $Y est la fonction Y-Combinator en PHP qui aura la définition suivante</p><p><code>$Y = fn(Closure $f) =&gt; $U(fn(Closure $x) =&gt; $f(fn(Closure $y) =&gt; $U($x)($y)));</code></p><p>Mais ce n'est qu'une des représentation en PHP que l'on peut en faire, il existe aussi un autre dépôt loophp qui décrit le Y-combinator d'une manière tout aussi élégante en programmation orientée objet. A noter que dans ce dépôt, on va retrouver d'autres types de lambda-calculus, je vous invite à regarder le dépôt : https://github.com/loophp/combinator</p><p>Un autre dépôt qui est interessant est celui de igorw. Lui va définir le langage lambda en PHP et on peut écrire directement les fonctions comme $true, $false, $not, $fact ou $Y que l'on a vu précédemment.</p><p>Fun fact. Savez vous d'où vient la société Y-Combinator ? C'est une société qui aide à entreprendre, car elle itère la création de société.</p><p>Ressources liées à l'article</p><ul><li>articles
<ul><li>Lambda-calcul : <a href="https://fr.wikipedia.org/wiki/Lambda-calcul">https://fr.wikipedia.org/wiki/Lambda-calcul</a></li><li><a href="http://matt.might.net/articles/implementing-a-programming-language">Matt Might: 7 lines of code, 3 minutes</a></li><li><a href="http://codon.com/programming-with-nothing">Tom Stuart: Programming with Nothing</a></li><li><a href="http://www.pps.univ-paris-diderot.fr/~krivine/articles/lazymach.pdf">Jean-Louis Krivine: A call-by-name lambda-calculus machine</a></li><li><a href="http://pop-art.inrialpes.fr/~fradet/PDFs/HOSC07.pdf">Rémi Douence, Pascal Fradet: The Next 700 Krivine Machines</a></li><li><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.6772">Xavier Leroy: The Zinc Experiment</a></li><li><a href="http://homepages.cwi.nl/~tromp/cl/LC.pdf">John Tromp: Binary Lambda Calculus and Combinatory Logic</a></li><li><a href="http://www.ioccc.org/2012/tromp/hint.html">John Tromp: Binary Lambda Calculus interpreter for IOCCC</a></li><li><a href="http://zeroturnaround.com/rebellabs/parsing-lambda-calculus-in-scala">Erkki Lindpere: Parsing Lambda Calculus in Scala</a></li><li><a href="https://github.com/sdiehl/bnlc">Binary Lambda Calculus in Python</a></li><li><a href="https://github.com/ympbyc/Carrot">Krivine Machine in Scheme</a></li><li><a href="https://github.com/tromp/AIT">Algorithmic Information Theory in Haskell</a></li><li><a href="http://en.wikipedia.org/wiki/Lambda_calculus">Lambda Calculus - Wikipedia</a></li><li><a href="http://en.wikipedia.org/wiki/Binary_lambda_calculus">Binary Lambda Calculus - Wikipedia</a></li><li><a href="http://en.wikipedia.org/wiki/De_Bruijn_index">De Bruijn index - Wikipedia</a></li><li><a href="https://phpbuilder.com/lambdas-in-php">https://phpbuilder.com/lambdas-in-php</a></li><li>Language explanation : <a href="https://tgdwyer.github.io/lambdacalculus">https://tgdwyer.github.io/lambdacalculus</a></li><li>Magic function call trampoline : <a href="http://blog.jpauli.tech/2016-09-16-php-7-magic-function-call-trampoline-html">http://blog.jpauli.tech/2016-09-16-php-7-magic-function-call-trampoline-html</a></li></ul></li><li>PHP
<ul><li><a href="https://github.com/igorw/lambda-php">https://github.com/igorw/lambda-php</a></li><li><a href="https://github.com/loophp/combinator">https://github.com/loophp/combinator</a></li><li>implementation + test
<ul><li><a href="https://github.com/loophp/combinator/blob/master/src/Combinator/Y.php">https://github.com/loophp/combinator/blob/master/src/Combinator/Y.php</a></li><li><a href="https://github.com/loophp/combinator/blob/master/spec/loophp/combinator/Combinator/YSpec.php">https://github.com/loophp/combinator/blob/master/spec/loophp/combinator/Combinator/YSpec.php</a></li><li><a href="https://gist.github.com/dvapelnik/540ac98462a821800837">https://gist.github.com/dvapelnik/540ac98462a821800837</a></li></ul></li></ul></li><li>Javascript
<ul><li><a href="https://github.com/willclarktech/lambda-calculus">https://github.com/willclarktech/lambda-calculus</a></li><li><a href="https://github.com/Muzietto/es6-lambda-calculus">https://github.com/Muzietto/es6-lambda-calculus</a></li></ul></li><li>YouTube
<ul><li>Essentials: Functional Programming's Y Combinator - Computerphile : <a href="https://www.youtube.com/watch?v=9T8A89jgeTI">https://www.youtube.com/watch?v=9T8A89jgeTI</a></li><li>A Flock of Functions: Combinators, Lambda Calculus, &amp; Church Encodings in JS - Part II : <a href="https://www.youtube.com/watch?v=pAnLQ9jwN-E">https://www.youtube.com/watch?v=pAnLQ9jwN-E</a></li></ul></li><li>Twitter
<ul><li><a href="https://twitter.com/ympbyc">@ympbyc</a></li><li><a href="https://twitter.com/smdiehl">@smdiehl</a></li><li><a href="https://twitter.com/PolDellAiera">PolDellAiera</a></li></ul></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/y-combinator-en-php</link><guid>https://blog.darkwood.com/article/y-combinator-en-php</guid><enclosure url="http://darkwood.com/media/articles/644847085e6b4091653490.png" /></item><item><title>Chunk computing en PHP</title><pubDate>Wed, 28 Aug 2024 08:48:26 +0000</pubDate><description><![CDATA[
La présentation liée à l&#039;article :

Le chunking est une technique polyvalente utilisée dans divers domaines, notamment la psychologie cognitive et l&#039;informatique, pour améliorer l&#039;efficacité, améliorer les performances et simplifier les tâches complexes. C...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66ceea45c0da2469809018.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/JBx4bjB8HIM?si=SYbkbqdu1DHb7Lzq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>La présentation liée à l'article :</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/eaa47bb60fcf4d90805048eaa85f52f3" title="Chunk Computing in PHP" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;" data-ratio="1.78343949044586"></iframe></div><p>Le chunking est une technique polyvalente utilisée dans divers domaines, notamment la psychologie cognitive et l'informatique, pour améliorer l'efficacité, améliorer les performances et simplifier les tâches complexes. Cet article se penche sur les principes du chunking, en offrant des exemples pratiques et des aperçus sur sa mise en œuvre dans la technologie et l'apprentissage.</p><h2>Pourquoi ?</h2><p>Le chunking a été développé pour répondre aux limites inhérentes au traitement cognitif et à la mémoire humaine. En décomposant les informations en unités plus petites et gérables, le chunking permet un traitement mental plus efficace et un rappel plus facile. En technologie, ce concept se traduit par la gestion de grands ensembles de données ou de tâches complexes en les divisant en morceaux plus petits et plus digestes, améliorant ainsi l'efficacité du traitement et réduisant les erreurs.</p><h2>Qu'est-ce que le « chunking » ?</h2><p>En technologie, un « chunk » est un segment discret de données qui est transféré, traité ou stocké en tant qu'unité. Les chunks sont utilisés dans divers systèmes, notamment les bases de données, les communications réseau et les opérations de stockage, pour décomposer de grands ensembles de données en morceaux plus petits et plus gérables. Cette approche simplifie la gestion des données, améliore la vitesse de traitement et améliore les performances globales du système.</p><h2>Principaux points à retenir</h2><p>Le concept de découpage, lorsqu'il est compris comme une méthode de décomposition d'informations complexes en parties plus simples, peut être résumé comme suit :</p><ul><li>Le découpage permet une compréhension, un traitement et une mémorisation plus faciles des informations complexes.</li><li>Il est essentiel pour améliorer l'apprentissage et la rétention de la mémoire en organisant les informations de manière logique.</li><li>Le découpage est une technique polyvalente applicable dans divers domaines, de la psychologie cognitive au traitement des données en technologie.</li></ul><p>Si « morceau » fait référence à autre chose, comme un personnage d'un film ou d'un livre, ou à un concept dans un contexte différent, j'aurais besoin de ces informations pour fournir des conclusions plus spécifiques.</p><h2>Importance</h2><p>Le concept de « morceau » en technologie est crucial car il sous-tend des stratégies efficaces de gestion et de traitement des données. En divisant des fichiers ou des ensembles de données volumineux en morceaux plus petits et gérables, les systèmes peuvent optimiser l'utilisation de la mémoire, accélérer le traitement des données et améliorer la récupération des erreurs. En réseau, le découpage facilite la transmission de données plus fluide et plus fiable, tandis qu'en programmation, il facilite le développement de code modulaire, rendant la maintenance et le débogage plus faciles à gérer.</p><h2>Explication</h2><p>Les découpages font partie intégrante de divers processus technologiques, servant de méthode fondamentale pour traiter, stocker et transférer efficacement des données. Dans le stockage de données, les découpages permettent la distribution de fichiers volumineux sur différents emplacements, optimisant les temps de récupération et protégeant les données. La programmation bénéficie du découpage en permettant des structures de code modulaires, qui simplifient le débogage et améliorent l'efficacité du développement. Dans les communications réseau, le découpage garantit que les gros paquets de données sont divisés en morceaux gérables, réduisant ainsi le risque de perte de données pendant la transmission. Le thème récurrent dans ces applications est que le découpage rend les tâches complexes de traitement des données plus efficaces et plus fiables.</p><h2>Exemples</h2><ul><li><p>Fractionnement de fichiers : dans les opérations sur fichiers, le terme « découpage » désigne un bloc de données transféré d'un emplacement à un autre. Les services de partage de fichiers tels que BitTorrent décomposent les fichiers volumineux en morceaux plus petits, ou « morceaux », pour faciliter une transmission de données plus rapide et plus efficace.</p></li><li><p>Streaming vidéo : sur des plateformes comme YouTube ou Netflix, les vidéos sont divisées en petits « morceaux ». Cela permet une diffusion plus fluide car chaque morceau est chargé et lu pendant que le suivant est en cours de chargement, évitant ainsi de devoir charger la vidéo entière avant le début de la lecture.</p></li><li><p>Traitement des Big Data : dans le Big Data, les ensembles de données sont souvent traités en « morceaux » pour plus d'efficacité. Par exemple, Apache Hadoop utilise une méthode de « découpage » pour rendre l'analyse de données à grande échelle plus gérable. Les données sont divisées en fragments plus petits ou « morceaux », chacun pouvant être traité en parallèle sur différentes machines d'un réseau pour accélérer le temps de traitement.</p></li><li><p>Formation sur le modèle d'IA : dans l'IA, les données sont divisées en lots plus petits pendant la formation, ce qui permet des mises à jour fréquentes, un apprentissage plus rapide et une gestion efficace d'ensembles de données volumineux.</p></li></ul><h2>En psychologie</h2><p>En psychologie, le découpage est le processus de regroupement d'éléments d'information individuels en unités plus grandes et cohérentes ou « morceaux », qui peuvent être facilement rappelés comme un seul élément. Par exemple, un maître d'échecs reconnaît et rappelle les modèles sur un échiquier comme des morceaux de configurations significatives plutôt que des pièces individuelles. Cette capacité à découper efficacement les informations est ce qui distingue souvent les experts des novices dans n'importe quel domaine.</p><h2>Comment le « chunking » peut-il m'aider à apprendre le développement logiciel ?</h2><p>Dans le développement logiciel, le chunking pourrait être utilisé pour apprendre divers concepts, tels que :</p><ul><li><p>Un modèle de conception comme le décorateur.</p></li><li><p>Une technique telle que l'utilisation de curl et de SSH pour identifier un problème de connectivité.</p></li><li><p>Un framework/une technologie comme Amazon ECS.</p></li></ul><p>Une fois maîtrisé, vous n'avez plus besoin de réfléchir aux étapes individuelles. Diagnostiquer un problème devient assez simple, car vous savez instinctivement où chercher.</p><h2>Dans la gestion de la mémoire</h2><p>Les systèmes logiciels modernes typiques allouent dynamiquement de la mémoire à partir de structures appelées tas. Des appels sont effectués vers des routines de gestion de tas pour allouer et libérer de la mémoire. La gestion des tas implique un certain temps de calcul et peut poser des problèmes de performances. Le découpage en morceaux fait référence à des stratégies visant à améliorer les performances en utilisant des connaissances spécifiques d'une situation pour regrouper les demandes d'allocation de mémoire associées. Par exemple, si l'on sait qu'un certain type d'objet sera généralement requis par groupe de huit, au lieu d'allouer et de libérer chaque objet individuellement (ce qui nécessite seize appels au gestionnaire de tas), on pourrait allouer et libérer un tableau de huit objets, réduisant ainsi le nombre d'appels à deux.</p><p>Voyons ce que cela signifie et comment le découpage peut aider à optimiser les performances.</p><ul><li><p>Allocation dynamique : dans de nombreuses applications logicielles, la mémoire n'est pas toujours allouée au démarrage. Au lieu de cela, elle est allouée de manière dynamique au fur et à mesure de l'exécution du programme, en fonction des besoins de l'application à un moment donné. Cette mémoire dynamique provient d'une zone appelée le tas. Cependant, la gestion de ce tas peut prendre du temps car chaque fois que le programme a besoin de plus de mémoire, il doit effectuer un appel au tas pour allouer ou libérer de l'espace.</p></li><li><p>Impact sur les performances : plus votre programme doit effectuer ces appels de gestion de tas souvent, plus votre système peut devenir lent. Chaque appel pour allouer ou libérer de la mémoire prend du temps et de la puissance de traitement, ce qui peut s'accumuler, surtout si votre programme effectue ces appels fréquemment.</p></li><li><p>Stratégie de segmentation : c'est là que la segmentation entre en jeu comme une stratégie intelligente pour réduire l'impact sur les performances. Au lieu d'effectuer un appel de gestion du tas chaque fois que vous devez allouer ou libérer de la mémoire pour un seul objet, la segmentation vous permet de regrouper les allocations de mémoire associées.</p></li><li><p>Exemple : Imaginez que vous avez un programme qui doit souvent créer et détruire plusieurs objets, disons 8 à la fois. Au lieu d'allouer et de libérer de la mémoire pour chaque objet individuellement (ce qui nécessiterait 16 appels de tas distincts, 8 pour allouer et 8 pour libérer), vous pouvez allouer de la mémoire pour les 8 objets en une seule fois et la libérer en une seule fois. Cela réduit le nombre d'appels de gestion du tas de 16 à seulement 2, réduisant considérablement la surcharge et accélérant votre programme.</p></li></ul><p>En appliquant la segmentation dans la gestion de la mémoire, votre programme peut gérer la mémoire plus efficacement, réduisant les délais et améliorant les performances globales du système. Cette approche est particulièrement bénéfique dans les applications hautes performances où chaque milliseconde compte.</p><h3>Itération traditionnelle</h3><p><img src="/blog/images/articles/chunk/range.png" alt="PHP Array" /></p><p>Lors du traitement de grands ensembles de données, l'itération traditionnelle peut entraîner des problèmes de consommation de mémoire importants :</p><ul><li>Utilisation élevée de la mémoire :</li></ul><p>Le chargement simultané de quantités massives de données dans la mémoire peut consommer une grande partie de la RAM disponible.</p><p>Si l'ensemble de données dépasse la mémoire disponible, cela peut entraîner un ralentissement considérable du système, voire un blocage.</p><ul><li>Dégradation des performances :</li></ul><p>Les systèmes peuvent recourir à l'utilisation de l'espace d'échange (en utilisant le stockage sur disque comme mémoire supplémentaire), qui est beaucoup plus lent que la RAM.</p><ul><li>Problèmes d'évolutivité :</li></ul><p>Les applications qui fonctionnent bien avec de petits ensembles de données peuvent ne pas évoluer correctement à mesure que les données augmentent.
Limite la capacité à traiter efficacement les données en temps réel ou en streaming.</p><h3>array_chunk : fractionnement d'un index simple Tableau</h3><p><img src="/blog/images/articles/chunk/array_chunk1.png" alt="PHP Array chunk 1" /></p><p>Sortie</p><p><img src="/blog/images/articles/chunk/array_chunk1_output.png" alt="PHP Array chunk 1" /></p><h3>array_chunk : Fractionnement d'un tableau associatif avec préservation Clés</h3><p><img src="/blog/images/articles/chunk/array_chunk2.png" alt="PHP Array chunk 2" /></p><p>Résultat</p><p><img src="/blog/images/articles/chunk/array_chunk2_output.png" alt="PHP Array chunk 2" /></p><h3>chunk_split</h3><p>La fonction chunk_split() en PHP est utilisée pour diviser une chaîne en morceaux plus petits et éventuellement ajouter un délimiteur (comme une nouvelle ligne ou un espace) après chaque morceau. Cela peut être utile pour formater la sortie, par exemple lorsque vous devez diviser une longue chaîne en parties gérables.</p><p><img src="/blog/images/articles/chunk/chunk_split.png" alt="PHP Array chunk split" /></p><p>Sortie</p><p><img src="/blog/images/articles/chunk/chunk_split_output.png" alt="PHP Array chunk split output" /></p><h3>Threaded::chunk</h3><p>La méthode Threaded::chunk() fait partie de l'extension pthreads en PHP, qui est utilisée pour le multithreading. Elle vous permet de diviser les données stockées dans un objet Threaded en morceaux plus petits et plus faciles à gérer, qui peuvent ensuite être traités indépendamment, souvent en parallèle par plusieurs threads. La méthode chunk() divise un objet Threaded en morceaux plus petits, cette méthode est particulièrement utile dans la programmation concurrente lorsqu'il s'agit de grands ensembles de données qui doivent être traités en plusieurs parties.</p><p><img src="/blog/images/articles/chunk/threaded_chunk.png" alt="PHP threaded chunk" /></p><p>Sortie</p><p><img src="/blog/images/articles/chunk/threaded_chunk_output.png" alt="PHP threaded chunk output" /></p><ul><li><p>Fractionnement des données en morceaux : la méthode chunk divise le contenu d'un objet Threaded en morceaux plus petits d'une taille spécifiée. Chaque morceau est un tableau contenant un sous-ensemble des éléments de l'objet Threaded d'origine. En divisant les données en morceaux, vous pouvez gérer et traiter efficacement de grands ensembles de données en parallèle, améliorant ainsi les performances et réduisant la complexité de la gestion de données volumineuses au sein d'un seul thread.</p></li><li><p>Classe DataProcessor : la classe DataProcessor gère la logique de fractionnement de l'ensemble de données en morceaux et de traitement de chaque morceau dans un thread distinct.</p></li><li><p>Concurrence et parallélisme : dans un environnement multithread, chaque fragment peut être traité par un thread distinct. Ce traitement parallèle permet une exécution plus rapide des tâches, en particulier lorsqu'il s'agit d'opérations liées au processeur, telles que Mathematical calculs ou opérations liées aux E/S, comme la lecture et l'écriture sur le disque ou la communication réseau. Plusieurs threads s'exécutent simultanément, chacun traitant un bloc de données différent. La méthode join garantit que le thread principal attend que tous les threads de traitement soient terminés avant de terminer l'exécution.</p></li><li><p>Création d'objets threadés : un objet threadé est créé contenant un grand ensemble de données d'entiers (de 1 à 100).</p></li><li><p>Création et exécution de threads : pour chaque bloc, un DataProcessingThread est créé et démarré. Ce thread traite chaque élément du bloc (par exemple, en mettant le nombre au carré) et imprime le résultat.</p></li><li><p>Efficacité de la mémoire : en traitant les données par blocs, vous évitez de charger l'ensemble de données en mémoire en une seule fois. Cela est particulièrement bénéfique lorsque vous travaillez avec de grands ensembles de données, car cela réduit la consommation de mémoire et minimise le risque d'erreurs de dépassement de mémoire.</p></li></ul><h3>fread</h3><p><img src="/blog/images/articles/chunk/fread.png" alt="PHP threaded chunk" /></p><p>Avantages :</p><p>Utilisation efficace de la mémoire : seule une petite partie du fichier est chargée en mémoire à la fois.
Gestion des fichiers volumineux : vous pouvez travailler avec des fichiers bien plus volumineux que la mémoire disponible.</p><h3>Utilisation de SplFileObject pour une gestion efficace des fichiers</h3><p>La classe SplFileObject fournit une méthode orientée objet pour gérer les fichiers et peut être particulièrement utile pour lire des fichiers volumineux ligne par ligne sans charger l'intégralité du fichier en mémoire.</p><p><img src="/blog/images/articles/chunk/SplFileObject.png" alt="PHP threaded chunk" /></p><p>Avantages :</p><p>Traitement ligne par ligne : une seule ligne est chargée en mémoire à la fois, ce qui la rend adaptée aux fichiers très volumineux.
Flexibilité : SplFileObject fournit divers indicateurs et méthodes pour une gestion efficace des fichiers.</p><h3>Fonctions de gestion de la mémoire</h3><p>PHP fournit plusieurs fonctions qui vous permettent de surveiller et de gérer l'utilisation de la mémoire dans vos scripts. Ces fonctions peuvent vous aider à écrire du code économe en mémoire, en particulier dans les processus ou scripts de longue duréequi gèrent des données volumineuses.</p><p><code>memory_get_usage()</code> Renvoie la quantité de mémoire, en octets, actuellement utilisée par votre script PHP.</p><p><img src="/blog/images/articles/chunk/memory_get_usage.png" alt="PHP threaded chunk" /></p><p><code>memory_get_peak_usage()</code> Renvoie l'utilisation maximale de la mémoire (quantité de mémoire la plus élevée utilisée) pendant l'exécution de votre script.</p><p><img src="/blog/images/articles/chunk/memory_get_peak_usage.png" alt="PHP threaded chunk" /></p><p><code>gc_collect_cycles()</code> Cette fonction force la collecte de tous les cycles de garbage existants. Le garbage collector de PHP nettoie les références circulaires en mémoire, mais parfois une intervention manuelle peut aider dans les scripts de longue durée.</p><p><img src="/blog/images/articles/chunk/gc_collect_cycles.png" alt="PHP threaded chunk" /></p><h3>Utilisation des générateurs</h3><p>Les générateurs PHP vous permettent d'itérer sur les données sans charger l'ensemble de données en mémoire en une seule fois. Ceci est particulièrement utile lorsque vous travaillez avec des sources de données ou des flux volumineux.</p><p><img src="/blog/images/articles/chunk/generators.png" alt="PHP threaded chunk" /></p><p>Avantages :</p><p>Efficacité de la mémoire : un seul élément est traité à la fois, ce qui réduit considérablement l'utilisation de la mémoire par rapport au chargement de l'ensemble de données en une seule fois.
Adapté aux grands ensembles de données : idéal pour les scénarios où vous devez traiter de grands ensembles de données ou des flux sans épuiser la mémoire.</p><h3>unset() et libération de mémoire</h3><p>En PHP, unset() est utilisé pour détruire une variable et libérer la mémoire qui lui est associée. Cela peut être particulièrement utile dans les scripts de longue durée où la mémoire doit être gérée activement.</p><p><img src="/blog/images/articles/chunk/unset.png" alt="PHP threaded chunk" /></p><p>Avantages :</p><p>Récupération de mémoire : gérez activement l'utilisation de la mémoire en libérant de la mémoire lorsque les variables ne sont plus nécessaires.
Empêche les fuites de mémoire : aide à éviter les fuites de mémoire dans les scripts de longue durée.</p><h3>loophp/collection : Chunk</h3><p>La classe Chunk de la bibliothèque Loophp Collection est conçue pour diviser une collection itérable en morceaux plus petits et de taille fixe. La classe implémente une opération immuable qui renvoie un générateur, qui produit des tableaux représentant des morceaux de la collection d'origine. Elle permet des tailles de morceaux dynamiques en utilisant un itérateur cyclique, ce qui permet d'avoir des tailles variables pour différents morceaux au sein de la même opération. Cette approche est particulièrement utile lors de la gestion de grands ensembles de données, permettant un traitement plus efficace en les divisant en morceaux gérables.</p><p><img src="/blog/images/articles/chunk/loophp_collection_chunk.png" alt="PHP threaded chunk" /></p><p>La classe Chunk dans ce code PHP est conçue pour diviser un itérable en morceaux de tailles variables. Elle renvoie une fermeture qui prend une série d'entiers représentant les tailles de morceaux et un itérable. Elle utilise un itérateur cyclique (Cycle) pour appliquer ces tailles de manière répétée pendant qu'elle traite l'itérable. Si une taille de morceau est atteinte, elle cède ce morceau et passe à la taille suivante. Ce processus continue jusqu'à ce que l'itérable entier soit consommé.</p><p>Exemple de cas d'utilisation
Supposons que vous ayez une liste d'éléments et que vous souhaitiez les diviser en morceaux avec des tailles qui se répètent dans un cycle, comme [2, 3, 2] :</p><p><img src="/blog/images/articles/chunk/loophp_collection_chunk_sample.png" alt="PHP threaded chunk" /></p><p>Sortie</p><p><img src="/blog/images/articles/chunk/loophp_collection_chunk_output.png" alt="PHP threaded chunk" /></p><p>Cet exemple illustre comment l'itérable est décomposé en morceaux de tailles 2, 3, 2, en répétant le motif selon les besoins.</p><h2>Dans la transmission de messages HTTP</h2><p>Le découpage en blocs est une fonctionnalité spécifique du protocole HTTP 1.1. Ici, la signification est opposée à celle utilisée dans la gestion de la mémoire. Il fait référence à la capacité de décomposer de gros messages en « blocs » plus petits et plus faciles à gérer. Il a été introduit dans HTTP/1.1, qui a été documenté pour la première fois dans la RFC 2068, publiée en janvier 1997. Le codage de transfert en blocs permet d'envoyer des données dans une série de blocs afin qu'un serveur puisse commencer à envoyer des données avant que la longueur complète du contenu ne soit connue. Il s'agissait d'une amélioration significative par rapport à HTTP/1.0, où la longueur du contenu devait être connue et envoyée avant que des données puissent être transmises.</p><h3>Qu'est-ce que le codage de transfert en blocs ?</h3><p>Le codage de transfert en blocs est un mécanisme de transfert de données dans HTTP/1.1 qui permet à un serveur d'envoyer une réponse en blocs générés dynamiquement sans avoir besoin de connaître la longueur finale du contenu avant la transmission. Cela est particulièrement utile pour diffuser des fichiers volumineux ou des données en temps réel, où la taille totale du contenu peut ne pas être connue au début de la réponse.</p><h3>Pourquoi utiliser le codage de transfert en bloc ?</h3><p>Dans le protocole HTTP/1.0 antérieur, le serveur devait connaître la longueur totale du corps de la réponse avant de pouvoir commencer à envoyer des données. Cette exigence posait des problèmes, en particulier lorsqu'il s'agissait de contenu volumineux généré de manière dynamique. HTTP/1.1 a introduit le codage de transfert en bloc pour répondre à ces défis. Avec le codage de transfert en bloc, le serveur peut commencer à transmettre des parties de la réponse immédiatement, ce qui améliore les performances perçues et réduit la latence pour l'utilisateur final.</p><h3>Comment fonctionne le codage de transfert en bloc</h3><p>Dans le codage de transfert en bloc, le serveur envoie le corps de la réponse sous forme d'une série de blocs. Chaque bloc commence par la taille du bloc (en hexadécimal), suivi des données réelles et d'un CRLF (Carriage Return Line Feed) de fin. La fin du message est indiquée par un bloc d'une taille de « 0 ».</p><p>Exemple : 4\r\n Wiki\r\n 5\r\n pedia\r\n E\r\n en\r\n morceaux.\r\n 0\r\n \r\n</p><ul><li><code>4\r\nWiki\r\n</code> - Ce morceau fait 4 octets de long et contient la chaîne « Wiki ».</li><li><code>5\r\npedia\r\n</code> - Ce morceau fait 5 octets de long et contient la chaîne « pedia ».</li><li><code>E\r\n en\r\nchunks.\r\n</code> - Ce morceau fait 14 octets de long (E en hexadécimal) et contient la chaîne « en morceaux ».</li><li><code>0\r\n\r\n</code> - Il s'agit du dernier morceau, indiquant la fin du message.</li></ul><h3>Comment les clients gèrent le codage de transfert par blocs</h3><p>Lorsqu'un client (par exemple, un navigateur Web) reçoit une réponse par blocs, il lit chaque bloc en fonction de la taille fournie, le traite et continue la lecture jusqu'à ce qu'il rencontre un bloc de taille « 0 », signalant la fin des données. Ce processus permet aux clients de commencer à traiter les données reçues sans attendre la réponse complète, améliorant ainsi les performances perçues.</p><h3>Réponse par blocs et meilleures performances perçues</h3><p>Revenons en arrière et examinons pourquoi nous voudrions nous assurer que notre serveur envoie des blocs le plus tôt possible. Dans son livre « High Performance Browser Networking », Ilya Grigorik explique pourquoi l'utilisation du vidage HTTP peut améliorer les performances.</p><p>Le document HTML est analysé de manière incrémentielle par le navigateur, ce qui signifie que le serveur peut et doit vider le balisage du document disponible aussi souvent que possible. Cela permet au client de découvrir et de commencer à récupérer les ressources critiques dès que possible.</p><p>Cela est particulièrement vrai pour la partie <head> du document HTML qui déclare les feuilles de style dont la page a besoin. Plus tôt le navigateur sait quelles feuilles de style demander, plus tôt il peut les télécharger et commencer à créer le CSSOM, ce qui signifie que la première peinture se produira également plus tôt.</p><h3>Cas d'utilisation de l'encodage de transfert en morceaux</h3><ul><li><p>Streaming vidéo : les services de streaming vidéo comme YouTube ou Netflix utilisent l'encodage de transfert en morceaux pour envoyer des données vidéo en segments. Cette approche permet à la vidéo de commencer à jouer avant que le fichier entier ne soit téléchargé, réduisant ainsi les temps d'attente et la mise en mémoire tampon pour les utilisateurs.</p></li><li><p>Flux de données en temps réel : les applications qui fournissent des mises à jour de données en temps réel, telles que les résultats sportifs en direct, les données du marché financier ou les flux de médias sociaux, bénéficient de l'encodage de transfert en morceaux. Les données peuvent être envoyées au client dès qu'elles sont disponibles, ce qui garantit des mises à jour rapides sans attendre que l'ensemble des données soit compilé.</p></li><li><p>Téléchargements de fichiers volumineux : lorsqu'il s'agit de téléchargements de fichiers volumineux, en particulier ceux générés de manière dynamique (comme un rapport ou un fichier journal), l'encodage de transfert en morceaux permet au téléchargement de démarrer immédiatement. Cela réduit le temps d'attente des utilisateurs avant que le fichier ne commence à se télécharger.</p></li><li><p>Événements envoyés par le serveur (SSE) : dans les événements envoyés par le serveur, où le serveur envoie en continu des mises à jour de données au client, l'encodage de transfert en bloc garantit un flux d'informations fluide et efficace, améliorant ainsi la réactivité de l'application.</p></li></ul><h3>Exemple de scraping Web avec l'utilisation de Symfony</h3><p>Lorsque vous scrapez des sites Web qui utilisent l'encodage de transfert en bloc, la bibliothèque HTTP sous-jacente que vous utilisez doit gérer automatiquement le décodage du transfert en bloc pour vous. La plupart des bibliothèques clientes HTTP modernes prennent en charge c'est prêt à l'emploi. Voyez comment nous procédons dans Symfony.</p><p><img src="/blog/images/articles/chunk/symfony_request.png" alt="PHP threaded chunk" /></p><p>Explication :</p><ul><li>StreamedResponse : permet à Symfony d'envoyer le fichier en morceaux plutôt que de charger le fichier entier en mémoire.</li><li>fread() et flush() : cette combinaison lit le fichier en morceaux de 1 Mo et envoie chaque morceau au client immédiatement, évitant ainsi une surcharge de mémoire.</li><li>En-têtes : l'en-tête fragmenté Transfer-Encoding garantit que le client interprète correctement la réponse.</li></ul><p><img src="/blog/images/articles/chunk/symfony_chunk1.png" alt="PHP threaded chunk" /></p><p><img src="/blog/images/articles/chunk/symfony_chunk2.png" alt="PHP threaded chunk" /></p><ul><li>Exemple 1 : Traiter la réponse complète :</li></ul><p>Cette approche récupère la réponse entière en une seule fois et la traite comme une chaîne complète. La méthode getContent() est utilisée pour rassembler tous les fragments, et vous pouvez gérer les données après la réception de la réponse complète.</p><ul><li>Exemple 2 : Traiter les fragments individuellement :</li></ul><p>Cette méthode vous permet de traiter chaque fragment de la réponse au fur et à mesure de son arrivée. En utilisant la méthode stream() et en itérant sur chaque fragment avec each(), vous pouvez gérer les données de manière incrémentielle, ce qui est utile pour les réponses volumineuses ou le traitement en temps réel.</p><p>Les deux méthodes conviennent à différents cas d'utilisation selon que vous devez gérer l'intégralité de la réponse en une seule fois ou traiter les données de manière incrémentielle au fur et à mesure de leur arrivée. Le client HTTP Symfony fournit des outils robustes pour gérer efficacement ces scénarios.</p><p>Quand utiliser l'encodage de transfert en bloc dans Symfony :</p><ul><li>Génération de contenu dynamique : si votre application génère des rapports ou des journaux volumineux à la volée, l'encodage de transfert en bloc vous permet de démarrer le téléchargement immédiatement.</li><li>Environnements à mémoire limitée : dans les cas où l'utilisation de la mémoire est un problème, l'encodage de transfert en bloc réduit l'empreinte mémoire en évitant de charger des fichiers entiers en mémoire.</li><li>Amélioration de l'expérience utilisateur : en démarrant immédiatement le transfert de données, les utilisateursbénéficiez de temps de chargement plus rapides et de temps d'attente réduits pour les téléchargements volumineux.</li></ul><h3>Gestion des opérations asynchrones avec AsyncDecoratorTrait dans Symfony HttpClient</h3><p>Traditionnellement, les requêtes HTTP synchrones peuvent entraîner des goulots d'étranglement, où l'exécution du code est bloquée en attendant les réponses. Ce comportement bloquant peut ralentir considérablement une application, en particulier lorsqu'il s'agit de plusieurs appels d'API ou de grands ensembles de données. AsyncDecoratorTrait de Symfony offre une solution en permettant aux développeurs de gérer les réponses HTTP de manière asynchrone, sans compromettre le contrôle du flux de données.</p><ul><li><p>Qu'est-ce que AsyncDecoratorTrait ?
AsyncDecoratorTrait est une fonctionnalité du composant Symfony HttpClient qui permet la gestion asynchrone des réponses HTTP. Il permet aux développeurs d'étendre les fonctionnalités d'un client HTTP en le décorant de capacités asynchrones supplémentaires. Ce trait est particulièrement utile dans les scénarios où plusieurs requêtes HTTP doivent être gérées simultanément, ce qui permet des opérations non bloquantes et des performances d'application améliorées.</p></li><li><p>Comment ça marche ?
Le trait AsyncDecoratorTrait fonctionne en permettant la manipulation des flux de réponses à leur arrivée, sans attendre que la réponse entière soit reçue. Cela est particulièrement utile dans les situations où un traitement immédiat des données est requis ou lorsque plusieurs requêtes HTTP dépendantes sont effectuées.</p></li></ul><p>Lors de l'utilisation du trait AsyncDecoratorTrait, les données de réponse sont traitées par blocs, qui sont traités dès qu'ils sont disponibles. Cette approche garantit que l'application reste réactive et que les ressources sont utilisées efficacement. De plus, le trait fournit des mécanismes pour gérer les erreurs avec élégance, comme l'annulation d'une réponse ou la nouvelle tentative d'une requête en cas de problème.</p><ul><li>Applications pratiques</li></ul><p>Transclusion d'API : une application pratique du trait AsyncDecoratorTrait est la transclusion d'API, où une réponse d'API principale est augmentée de données provenant d'autres API. Avec le trait AsyncDecoratorTrait, vous pouvez lancer plusieurs requêtes d'API simultanément et fusionner leurs résultats à leur arrivée. Cette approche accélère non seulement le processus, mais garantit également que l'application ne se bloque pas en attendant toutes les réponses.</p><p>Gestion des erreurs avec élégance : Un autre avantage important du trait AsyncDecoratorTrait est sa capacité à gérer les erreurs dans un contexte asynchrone. Par exemple, si une erreur 404 est rencontrée lors d'une requête, le trait vous permet d'annuler la réponse, d'émettre une nouvelle requête ou de remplacer entièrement la réponse. Cette fonctionnalité est particulièrement utile lors du traitement de données paginées ou de la recherche dans plusieurs sources où des erreurs peuvent survenir de manière sporadique.</p><ul><li>Exemple : gestion des requêtes HTTP asynchrones</li></ul><p><img src="/blog/images/articles/chunk/async_decorator_trait_1.png" alt="PHP threaded chunk" /></p><p><img src="/blog/images/articles/chunk/async_decorator_trait_2.png" alt="PHP threaded chunk" /></p><p><img src="/blog/images/articles/chunk/async_decorator_trait_3.png" alt="PHP threaded chunk" /></p><ul><li>Avantages et limites</li></ul><p>Avantages :</p><p>Performances améliorées : en gérant les réponses de manière asynchrone, l'application peut traiter les données plus rapidement et plus efficacement, réduisant ainsi le risque de goulots d'étranglement.</p><p>Opérations non bloquantes : le trait AsyncDecoratorTrait permet des requêtes HTTP non bloquantes, garantissant que l'application peut continuer à exécuter d'autres tâches en attendant les réponses.</p><p>Gestion flexible des erreurs : le trait fournit des mécanismes robustes pour gérer les erreurs dans un contexte asynchrone, facilitant ainsi la gestion des flux de travail complexes.</p><p>Limitations :</p><p>Complexité : la gestion des flux de travail asynchrones peut introduire une complexité supplémentaire, en particulier lors du traitement de plusieurs requêtes simultanées.</p><p>Gestion des ressources : bien que cette caractéristique améliore les performances, il est important de gérer les ressources avec soin pour éviter de submerger le système avec trop de requêtes simultanées.</p><h3>Streaming de données avec la mise en mémoire tampon de sortie de PHP</h3><p>Les fonctions de mise en mémoire tampon de sortie de PHP peuvent être utilisées pour gérer efficacement la sortie de données par blocs, en particulier lorsque vous souhaitez envoyer des données au client progressivement. La mise en mémoire tampon de sortie peut aider à contrôler le moment où les données sont envoyées au client, ce qui permet d'obtenir des réponses par blocs.</p><p><img src="/blog/images/articles/chunk/output_buffering.png" alt="PHP threaded chunk" /></p><p>Explication :</p><ul><li>ob_start() : démarre la mise en mémoire tampon de sortie, vous permettant de contrôler quand la sortie est envoyée au client.</li><li>ob_flush() et flush() : ces fonctions garantissent que le contenu actuel du tampon est envoyé immédiatement au client, ce qui permet au serveur d'envoyer des données par blocs.</li><li>Délai simulé : la fonction usleep() introduit un délai entre les blocs, simulant un scénario réel dans lequel les données sont générées ou traitées au fil du temps.</li></ul><p>Cas d'utilisation :</p><p>Cette méthode est utile dans les scénarios où les données sont générées ou traitées à la volée, comme lors de la diffusion de journaux, de la génération de rapports ou de la livraison de grands ensembles de données assemblés de manière dynamique.</p><h3>Envoi incrémentiel de données JSON</h3><p>Parfois, vous devrez peut-être envoyer de grandes structures de données JSON au client de manière incrémentielle. Cela peut être fait en utilisant un codage de transfert par blocs pour envoyer chaque partie du JSON au fur et à mesure de sa génération.</p><p><img src="/blog/images/articles/chunk/json_data.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Diffusion JSON : le tableau JSON est ouvert en premier ([), et chaque bloc de données est envoyé en tant qu'objet JSON individuel. Le tableau est fermé (]) une fois tous les blocs envoyés.
JSON incrémental : cette méthode envoie chaque objet JSON au fur et à mesure de sa génération, ce qui peut être utile dans les API qui traitent de grands ensembles de données ou des tâches de génération de données de longue durée.</p><p>Cas d'utilisation :</p><p>Cette technique est utile pour les API qui doivent fournir de grands ensembles de données au format JSON mais qui souhaitent commencer à transmettre des données au client immédiatement plutôt que d'attendre que l'ensemble de données soit prêt.</p><h3>Gestion des téléchargements de fichiers volumineux avec des données en streaming</h3><p>Lors de la gestion des téléchargements de fichiers volumineux, vous pouvez utiliser le flux php://input de PHP pour lire les données entrantes par morceaux plutôt que de charger l'intégralité du fichier en mémoire.</p><p><img src="/blog/images/articles/chunk/large_file_uploads.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>php://input : ce flux vous permet d'accéder aux données POST brutes, ce qui est utile pour gérer directement les téléchargements de fichiers sans dépendre de $_FILES.
Gestion des téléchargements en morceaux : la lecture et l'écriture du fichier en morceaux évitent au serveur de manquer de mémoire lors de la gestion de téléchargements volumineux.</p><p>Cas d'utilisation :</p><p>Cette technique est utile dans les scénarios où vous vous attendez à des téléchargements de fichiers volumineux (par exemple, des téléchargements de vidéos, des soumissions de grands ensembles de données) et souhaitez vous assurer que votre application peut les gérer efficacement sans problèmes de mémoire.</p><h3>Événements envoyés par le serveur (SSE) avec PHP</h3><p>Les événements envoyés par le serveur (SSE) permettent à un serveur de transmettre des mises à jour au client en temps réel via une connexion HTTP. SSE utilise un codage de transfert fragmenté pour envoyer des données en continu.</p><p><img src="/blog/images/articles/chunk/server_sent_events.png" alt="PHP threaded chunk" /></p><h3>Pièges potentiels et bonnes pratiques</h3><p>Pièges :</p><ul><li>Compatibilité client : bien que la plupart des navigateurs et clients HTTP modernes prennent en charge l'encodage de transfert en bloc, certains clients plus anciens peuvent ne pas le gérer correctement. Assurez-vous que votre application se dégrade correctement si l'encodage en bloc n'est pas pris en charge.</li><li>Proxies intermédiaires : certains proxys ou pare-feu peuvent ne pas gérer correctement l'encodage de transfert en bloc, ce qui peut entraîner une corruption des données ou des transmissions incomplètes.</li><li>Transmission incomplète : si la connexion est interrompue avant la réception du dernier bloc, le client peut se retrouver avec des données incomplètes. Mettez en œuvre une gestion des erreurs et des tentatives appropriées lorsque cela est possible.</li></ul><p>Bonnes pratiques :</p><ul><li>Repli gracieux : implémentez des contrôles pour vous assurer que les clients peuvent gérer l'encodage de transfert en bloc. Si ce n'est pas le cas, envisagez d'envoyer la longueur totale du contenu ou de fournirune méthode de téléchargement alternative.</li><li>Vider fréquemment : utilisez <code>flush()</code> pour garantir que les données sont envoyées immédiatement au client, en particulier lors de la diffusion de fichiers volumineux. Cela évite de mettre en mémoire tampon de grandes quantités de données.</li><li>Surveiller les performances : surveillez régulièrement les performances de votre implémentation de transfert fragmenté pour identifier les goulots d'étranglement ou les problèmes, en particulier en cas de charge importante ou de fichiers volumineux.</li><li>Considérations relatives à la sécurité : assurez-vous que les réponses fragmentées sont correctement validées et nettoyées, car le codage fragmenté peut parfois être exploité dans les attaques de contrebande de requêtes HTTP.</li></ul><h2>Dans la déduplication des données, la synchronisation des données et la compression des données à distance</h2><p>Dans la déduplication des données, la synchronisation des données et la compression des données à distance, le découpage en morceaux est un processus de division d'un fichier en morceaux plus petits appelés morceaux à l'aide d'un algorithme de découpage en morceaux. Cela permet d'éliminer les copies en double de données répétitives sur le stockage ou de réduire la quantité de données envoyées sur le réseau en sélectionnant uniquement les morceaux modifiés. Les algorithmes de segmentation par contenu (CDC), tels que le hachage rotatif et ses variantes, sont les algorithmes de déduplication les plus populaires depuis 15 ans.</p><h3>Déduplication des données</h3><p>La déduplication des données est un processus utilisé pour éliminer les copies redondantes des données, réduisant ainsi les besoins de stockage. La segmentation joue un rôle important dans ce processus en décomposant les fichiers en segments plus petits, ce qui permet au système d'identifier et de stocker uniquement les segments uniques.</p><p>Types de segmentation dans la déduplication :</p><ul><li>Segmentation à taille fixe : le fichier est divisé en segments de taille fixe, par exemple 4 Ko ou 8 Ko.</li><li>Segmentation à taille variable (Segmentation par contenu défini) : le fichier est divisé en fonction du contenu, où les limites des segments sont déterminées par le contenu lui-même, souvent à l'aide d'algorithmes comme l'empreinte digitale de Rabin.</li></ul><p>Exemple avec segmentation à taille fixe :</p><p><img src="/blog/images/articles/chunk/fixed_size_chunking.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Chunking à taille fixe : cette méthode divise le fichier en segments de taille fixe, puis hache chaque segment. Si un segment est unique, il est enregistré ; sinon, il est supprimé, évitant ainsi le stockage redondant.</p><p>Avantages du découpage en segments dans la déduplication :</p><p>Efficacité du stockage : réduit la quantité d'espace disque requise en éliminant les données redondantes.</p><p>Sauvegardes plus rapides : étant donné que seuls les segments uniques sont stockés, les sauvegardes peuvent être plus rapides et nécessiter moins de stockage.</p><p>Déduplication avancée :</p><p>Chunking à taille variable : au lieu d'une taille fixe, le découpage à taille variable utilise des méthodes de découpage basées sur le contenu. Il est plus efficace pour identifier les données en double dans les fichiers où un contenu similaire peut être légèrement décalé (par exemple, dans les bases de données).</p><h3>Synchronisation des données</h3><p>La synchronisation des données consiste à maintenir plusieurs ensembles de données synchronisés sur différents systèmes ou emplacements. Le découpage en blocs est essentiel dans ce contexte pour garantir que seuls les blocs de données modifiés ou nouveaux sont transférés, minimisant ainsi la bande passante et le temps de traitement.</p><p>Exemple de synchronisation avec un comportement de type Rsync :</p><p><img src="/blog/images/articles/chunk/data_synchronization.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Synchronisation par blocs : cette méthode lit les fichiers source et cible en blocs, les compare et met à jour uniquement les blocs qui diffèrent. Cela imite le comportement d'outils comme rsync, qui sont très efficaces pour synchroniser de grands ensembles de données.</p><p>Avantages du découpage en blocs dans la synchronisation :</p><p>Efficacité de la bande passante : seuls les blocs modifiés sont transmis, ce qui réduit la quantité de données envoyées sur le réseau.
Temps de synchronisation réduit : en transférant uniquement ce qui est nécessaire, le processus de synchronisation est plus rapide.</p><h3>Compression des données à distance</h3><p>La compression des données à distance est le processus de compression des données avant de les envoyer sur un réseau, souvent utilisé dans des scénarios tels que la diffusion de contenu Web, le stockage dans le cloud et les sauvegardes à distance. Le découpage en blocs peut être appliqué ici pour compresser les données en segments, permettant un traitement plus efficace et parallèle.</p><p>Exemple d'utilisation de Gzip pour la compression en morceaux :</p><p><img src="/blog/images/articles/chunk/chunked_compression.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Compression en morceaux : le fichier est lu et compressé en morceaux, ce qui peut être particulièrement utile pour les fichiers très volumineux ou lorsque les contraintes de mémoire sont un problème.</p><p>Avantages de la compression en morceaux :</p><p>Efficacité de la mémoire : en compressant les données en morceaux, le fichier entier n'a pas besoin d'être chargé en mémoire, ce qui le rend adapté aux grands ensembles de données.
Traitement parallèle : la compression par blocs peut être parallélisée, ce qui améliore les performances sur les systèmes multicœurs.</p><h3>Exemple avancé : segmentation par contenu (CDC)</h3><p>Les algorithmes de segmentation par contenu (CDC), tels que l'empreinte Rabin, divisent les données en fonction du contenu plutôt que de tailles fixes, ce qui les rend plus efficaces pour la déduplication et la synchronisation dans les scénarios où les données sont fréquemment mises à jour avec de petites modifications.</p><p>Exemple avec segmentation par contenu :</p><p><img src="/blog/images/articles/chunk/content_defined_chunking.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Limites définies par le contenu : cet exemple illustre une implémentation de base de CDC, où les blocs sont déterminés par le contenu plutôt que par des tailles fixes. La détection des limites pourrait être plus sophistiquée en utilisant un véritable algorithme comme l'empreinte digitale Rabin.
Tailles de blocs adaptatives : CDC adapte les tailles de blocs en fonction du contenu, ce qui le rend plus efficace pour détecter le contenu dupliqué dans les fichiers avec des données similaires mais pas identiques.</p><p>Avantages :</p><p>Déduplication améliorée : CDC est plus efficace que le découpage en blocs de taille fixe pour détecter la redondance dans les fichiers dont le contenu a légèrement changé.
Synchronisation efficace : lorsque les fichiers ont été mis à jour avec de petites modifications, CDC garantit que seul le contenu modifié est transmis, optimisant ainsi davantage les processus de synchronisation.</p><h3>Découpage avec les services cloud</h3><p>De nombreuses solutions modernes de stockage et de sauvegarde dans le cloud utilisent le découpage en blocs en conjonction avec la déduplication et la compression pour optimiser l'utilisation du stockage et de la bande passante.</p><p>Exemple avec le téléchargement en plusieurs parties d'AWS S3 : lors du téléchargement de fichiers volumineux sur AWS S3, la fonction de téléchargement en plusieurs parties permet de télécharger les fichiers en blocs, ce qui facilite la gestion des fichiers volumineux, la reprise des téléchargements et la réduction de l'impact des problèmes de réseau.</p><p><img src="/blog/images/articles/chunk/cloud_service.png" alt="PHP threaded chunk" /></p><p>Explication :</p><p>Téléchargement en plusieurs parties : cet exemple montre comment télécharger un fichier volumineux sur S3 en morceaux, chacun d'une taille de 5 Mo. Cette approche est robuste, permettant de nouvelles tentatives sur des parties individuelles si le téléchargement échoue et rendant le processus de téléchargement plus efficace et plus fiable.
Avantages :</p><p>Évolutivité : gère les fichiers volumineux qui pourraient autrement provoquer des dépassements de délai ou dépasser les limites de mémoire.
Résilience : la possibilité de reprendre les téléchargements ayant échoué au niveau des parties minimise l'impact des perturbations du réseau.</p><h3>alexandre-daubois : Lazy streams</h3><p><img src="/blog/images/articles/chunk/lazy_streams.jpg" alt="PHP threaded chunk" /></p><p>Lors de sa récente présentation, Alexandre Daubois, Lead Symfony Developer chez Wanadev Digital, a évoqué les défis et les solutions auxquels son équipe a été confrontée lors du déplacement de son application de modélisation de maisons en 3D vers le cloud. L'accent a été mis principalement sur la gestion efficace de fichiers JSON volumineux, une exigence essentielle compte tenu de la lourdeur de l'applicationta utilisation.</p><ul><li><p>Principaux défis
L'application nécessitait le stockage de fichiers JSON massifs contenant des modèles 3D et des textures, qui fonctionnaient initialement bien avec le stockage local. Cependant, le passage au cloud a introduit des obstacles importants, notamment en matière de génération et de déploiement de fichiers. L'approche traditionnelle consistant à créer l'intégralité du fichier JSON en mémoire n'était plus viable, car elle entraînait des débordements de mémoire lorsque les fichiers devenaient trop volumineux.</p></li><li><p>Redis Streams à la rescousse
La solution s'est présentée sous la forme de Redis Streams. Redis, initialement utilisé uniquement pour le stockage de session, s'est avéré idéal pour ce nouveau cas d'utilisation en raison de sa structure de données en mémoire à grande vitesse. Redis Streams a permis à l'équipe de décomposer les fichiers JSON volumineux en morceaux plus petits qui pouvaient être traités simultanément par plusieurs pods dans le cloud. Chaque morceau était géré par un travailleur, sérialisé et stocké dans le flux Redis.</p></li><li><p>La mise en œuvre
Le processus impliquait que plusieurs travailleurs génèrent des segments JSON qui étaient ensuite consolidés dans le flux Redis. Cette approche a réparti la charge de travail sur plusieurs pods, garantissant qu'aucune instance ne manquerait de mémoire. Une fois tous les segments générés, l'étape finale consistait à concaténer les morceaux et à les télécharger sur le stockage cloud. Cependant, l'équipe a rencontré un autre défi lorsqu'elle a essayé de fusionner toutes les données en un seul fichier en raison des limites de mémoire.</p></li><li><p>Lazy Stream : une solution personnalisée
Pour résoudre ce problème, Daubois a développé une bibliothèque personnalisée appelée Lazy Stream, qui permettait l'écriture de fichiers fragmentés directement sur le stockage cloud. Cette approche évitait les débordements de mémoire en écrivant séquentiellement les données du flux Redis dans le fichier JSON final, en téléchargeant chaque morceau au fur et à mesure de son traitement. Cette méthode garantissait que même les fichiers extrêmement volumineux pouvaient être traités efficacement sans épuiser les ressources système.</p></li></ul><p>La bibliothèque PHP fournie implémente une série de classes sous l'espace de noms « LazyStream », conçue pour une gestion efficace et paresseuse des flux. Les classes incluent <code>LazyStreamChunkWriter</code>, <code>LazyStreamReader</code>, <code>LazyStreamWriter</code> et <code>MultiLazyStreamWriter</code>, chacune offrant des méthodes spécialisées pour travailler avec des flux de manière efficace en termes de mémoire. La bibliothèque permet de lire et d'écrire dans des flux de manière incrémentielle, en utilisant des générateurs pour gérer les données selon les besoins plutôt que de tout charger en mémoire en une seule fois. Cette approche est particulièrement utile pour traiter de grands ensembles de données ou travailler avec plusieurs flux simultanément, comme le montre la classe <code>MultiLazyStreamWriter</code>, qui gère l'écriture sur plusieurs flux simultanément avec un seul fournisseur de données. De plus, des fonctionnalités telles que la fermeture automatique des flux et la gestion des données binaires améliorent la flexibilité, ce qui rend cette bibliothèque adaptée aux opérations de streaming complexes tout en maintenant une faible utilisation des ressources.</p><ul><li><p>Gestion des flux paresseux : la bibliothèque se concentre sur la gestion des flux de manière paresseuse, ce qui signifie qu'elle traite les données de manière incrémentielle à l'aide de générateurs, ce qui permet de gérer efficacement la mémoire, en particulier pour les grands ensembles de données.</p></li><li><p>Types de flux multiples : elle fournit différentes classes pour la lecture et l'écriture de flux, notamment <code>LazyStreamReader</code>, <code>LazyStreamWriter</code>, <code>LazyStreamChunkWriter</code> et <code>MultiLazyStreamWriter</code>, chacune adaptée à des cas d'utilisation spécifiques.</p></li><li><p>Écriture en morceaux : la classe <code>LazyStreamChunkWriter</code> permet d'écrire les données en morceaux, en envoyant les données au fur et à mesure de leur génération plutôt que de les exiger toutes à l'avance.</p></li><li><p>Prise en charge de plusieurs flux : la classe <code>MultiLazyStreamWriter</code> peut écrire des données dans plusieurs flux simultanément à l'aide d'un seul fournisseur de données, ce qui est utile pour dupliquer des données sur plusieurs destinations.</p></li><li><p>Gestion automatique des flux : la bibliothèque comprend des fonctionnalités telles que l'ouverture, la fermeture et la gestion des erreurs automatiques des flux, simplifiant la gestion des ressources de flux.</p></li><li><p>Comportement personnalisable : les utilisateurs peuvent contrôler des aspects tels que la fermeture automatique des flux et la lecture en mode binaire, offrant une flexibilité dans la gestion des flux.</p></li></ul><p>Vous trouverez ci-dessous un exemple d'utilisation de base de la classe <code>LazyStreamChunkWriter</code> pour écrire des données dans un fichier :</p><p><img src="/blog/images/articles/chunk/lazystream_detail.png" alt="PHP threaded chunk" /></p><h3>Explication</h3><p>Dans cet exemple :</p><ul><li>Nous créons une instance de <code>LazyStreamChunkWriter</code> avec un URI de fichier.</li><li>Nous utilisons la méthode <code>send()</code> pour écrire des données dans le flux par morceaux.</li><li>Le flux est automatiquement ouvert en cas de besoin et éventuellement fermé en fonction de la configuration.</li></ul><p>Cet exemple démontre la capacité d'écriture incrémentielle des données de la bibliothèque, ce qui la rend idéale pour les situations où vous souhaitez traiter ou générer des données progressivement.</p><ul><li><p>Conclusion
La combinaison de Redis Streams et de la bibliothèque Lazy Stream a permis à Wanadev Digital de surmonter les défis importants de la migration vers le cloud. En exploitant Redis pour sa vitesse en mémoire et en utilisant Lazy Stream pour les téléchargements fragmentés, l'équipe a réussi à faire évoluer son application, permettant une gestion robuste et efficace des fichiers JSON volumineux dans un environnement cloud.</p></li><li><p>Points forts des questions-réponses :</p></li></ul><p>Gestion frontale des fichiers volumineux : les utilisateurs passent généralement plusieurs heures sur l'application, ce qui rend le temps de chargement initial acceptable. Les projets futurs incluent la transition vers la livraison de données basée sur l'API avec mise en cache et prise en charge du CDN pour des performances améliorées.
Cette solution est désormais une pierre angulaire de leur architecture basée sur le cloud, illustrant la puissance de la combinaison de Redis avec le développement personnalisé pour résoudre des problèmes complexes.</p><ul><li>Code exemple</li></ul><p><img src="/blog/images/articles/chunk/lazystream_exemple.png" alt="PHP threaded chunk" /></p><p>La classe <code>JsonRedisStreamEncoder</code> dans ce code PHP fournit un moyen efficace de convertir les données d'un flux Redis en un format de tableau JSON tout en minimisant l'utilisation de la mémoire. En implémentant un générateur dans la méthode <code>encode</code>, la classe traite les données du flux Redis de manière incrémentielle, produisant de petits morceaux JSON un par un. La méthode génère d'abord un crochet d'ouverture <code>[</code>, puis entre dans une boucle qui récupère, formate et génère chaque entrée de flux sous forme d'élément JSON, en ajoutant une virgule entre les éléments selon les besoins. Après avoir généré chaque morceau, l'entrée est supprimée du flux pour libérer de la mémoire. Une fois toutes les données traitées, la méthode supprime l'intégralité du flux de Redis et génère le crochet de fermeture <code>]</code> pour compléter le tableau JSON. Ce traitement incrémentiel permet une gestion efficace des grands ensembles de données, ce qui rend la classe particulièrement utile dans les environnements cloud où de grands fichiers JSON doivent être générés sans provoquer de dépassements de mémoire. L'exemple d'utilisation montre comment la méthode <code>encode</code> peut être itérée avec une boucle <code>foreach</code>, permettant aux blocs JSON d'être téléchargés ou traités séquentiellement.</p><h3>matyo91 : Offres mises en cache</h3><p>Le code fourni est une classe PHP chargée de gérer l'accès au catalogue et son affichage sur un site extranet. Il interagit avec divers services externes, dont Google BigQuery, pour récupérer et présenter les données du catalogue en fonction des entrées et des filtres des utilisateurs. La classe gère des opérations telles que la liste des éléments, la gestion de la pagination, l'application de critères de recherche et de filtrage et la récupération efficace de grands ensembles de données grâce à des mécanismes de segmentation et de mise en cache. En s'intégrant à Google BigQuery, tLa classe garantit que les informations du catalogue sont à jour et optimisées pour les performances, améliorant ainsi l'expérience utilisateur sur la plateforme.</p><p><img src="/blog/images/articles/chunk/cached_offers.png" alt="PHP threaded chunk" /></p><p>Explication de l'implémentation du découpage en blocs :</p><ul><li><p>Définir la taille du bloc
Le code définit une taille de bloc de 1 000 éléments (<code>$cacheSize = 1000;</code>). Cette taille détermine le nombre d'éléments traités à la fois.</p></li><li><p>Calculer les index
Les variables <code>$startIndex</code> et <code>$endIndex</code> définissent la plage d'éléments à récupérer pour la page en cours. Ces index aident à déterminer les blocs à récupérer.</p></li><li><p>Boucle sur les blocs
La boucle <code>for</code> parcourt les blocs requis, de <code>$startChunk</code> à <code>$endChunk</code>. À chaque itération, le système vérifie si le bloc est déjà mis en cache (stocké dans <code>$_SESSION</code>). Si ce n'est pas mis en cache, le fragment est récupéré à l'aide d'un appel API.</p></li><li><p>Résultats de la fusion
Les fragments récupérés sont fusionnés en un seul tableau (<code>$result</code>). Enfin, le tableau est découpé pour extraire uniquement les éléments pertinents pour la page en cours, garantissant une utilisation optimale de la mémoire.</p></li><li><p>Renvoyer le résultat
La fonction <code>getCachedOffers()</code> renvoie le tableau découpé, qui contient les données à afficher sur la page en cours.</p></li></ul><h2>Différence entre les données de bloc et de tampon</h2><p>Commençons par en discuter dans le contexte de JavaScript. JavaScript ne dispose pas d'un mécanisme intégré pour gérer et manipuler les données binaires. Par conséquent, un mécanisme était nécessaire. Nous avons un module global dans JavaScript appelé &quot;buffer&quot; qui gère toutes les données binaires. Le tampon est généralement une mémoire temporaire dans la RAM qui traite les données binaires à l'aide de blocs. Les blocs sont de petits morceaux de données binaires qui voyagent de la source à la destination à l'aide d'un flux.</p><p>Bloc : un bloc est un petit morceau de données binaires que nous voulons transférer de la source à la destination. Ainsi, nous avons un mécanisme appelé « chunks » qui contient ces petites données binaires et voyage de la source à la destination en utilisant des flux. Les chunks contiennent toutes les informations sur les données binaires, telles que les chunks qui doivent être traités et ceux qui ne le doivent pas.</p><p>Buffer : un buffer est une mémoire temporaire dans la RAM qui gère les données de chunk et les envoie pour traitement. Le buffer est un très petit bloc de mémoire adapté aux données binaires. Si le buffer est plein, les données sont envoyées pour traitement. Parfois, le buffer est utilisé comme middleware entre le traitement des données et la réception car un processeur est nécessaire pour le traitement des données.</p><p>Les chunks et les buffers diffèrent de plusieurs manières :</p><ul><li>Nature : les chunks sont des morceaux de données binaires, tandis que les buffers sont une classe globale dans Node.js utilisée pour gérer ces données binaires.</li><li>Contenu : les chunks ne contiennent que des données binaires, tandis que les buffers peuvent gérer des données au format binaire ainsi que d'autres formats.</li><li>Gestion : les chunks sont au format octet et doivent être gérés avec soin pour éviter la corruption des données. Les buffers gèrent les exceptions qui peuvent survenir lors de la gestion des chunks.</li><li>Dépendance : les blocs sont des conteneurs indépendants gérés par des tampons, tandis que les tampons s'appuient sur des blocs ou des flux pour le transfert de données.</li><li>Utilisation : les blocs sont utilisés pour la récupération de données externes, tandis que les tampons formatent et récupèrent des données sous diverses formes.</li><li>Contrôle : les blocs ont un flux incontrôlé, mais les tampons permettent de contrôler le flux de données à travers les flux.</li><li>Création : les blocs ne peuvent pas être créés directement, mais les tampons peuvent être créés pour contenir des blocs.</li><li>Exemple : dans <code>&lt;Buffer 48 65 6c 6c 6f&gt;</code>, la partie soulignée est un bloc, tandis que l'ensemble du contenu entre les crochets angulaires est un tampon.</li><li>Taille : un bloc stocke un octet de données, tandis que la taille d'un tampon dépend de la RAM et du matériel de la machine.</li></ul><h2>Différence entre bloc et thunk</h2><p>En programmation informatique, un thunk est une sous-routine utilisée pour injecter un calcul dans une autre sous-routine. Les thunks sont principalement utilisés pour retarder un calcul jusqu'à ce que son résultat soit nécessaire, ou pour insérer des opérations au début ou à la fin de l'autre sous-routine.Ils ont de nombreuses autres applications dans la génération de code de compilateur et la programmation modulaire.</p><ul><li>Applications</li></ul><p>Bien que l'industrie du logiciel ait largement standardisé l'évaluation par appel par valeur et par référence, l'étude active de l'appel par nom s'est poursuivie dans la communauté de la programmation fonctionnelle. Cette recherche a produit une série de langages de programmation d'évaluation paresseuse dans lesquels une variante de l'appel par nom est la stratégie d'évaluation standard. Les compilateurs de ces langages, tels que le compilateur Glasgow Haskell, se sont largement appuyés sur les thunks, avec la fonctionnalité supplémentaire que les thunks enregistrent leur résultat initial afin de pouvoir éviter de le recalculer ; [6] c'est ce qu'on appelle la mémorisation ou l'appel par besoin.</p><p>Les langages de programmation fonctionnelle ont également permis aux programmeurs de générer explicitement des thunks. Cela se fait dans le code source en enveloppant une expression d'argument dans une fonction anonyme qui n'a pas ses propres paramètres. Cela empêche l'expression d'être évaluée jusqu'à ce qu'une fonction réceptrice appelle la fonction anonyme, obtenant ainsi le même effet que l'appel par nom. L'adoption de fonctions anonymes dans d'autres langages de programmation a rendu cette capacité largement disponible.</p><p><img src="/blog/images/articles/chunk/thunk.png" alt="PHP threaded chunk" /></p><h2>Résumé</h2><p>En conclusion, les chunks jouent un rôle essentiel dans de nombreux domaines technologiques, allant du développement de logiciels à la gestion de la mémoire. Ils offrent un moyen de rendre le traitement des données plus efficace, structuré et fiable. Qu'il s'agisse de décomposer des fichiers de données, de comprendre des concepts complexes en psychologie ou de traiter efficacement des données en streaming, la méthode de fragmentation offre un moyen puissant de simplifier les tâches et de gérer efficacement de grandes quantités d'informations.</p><h2>Foire aux questions (FAQ)</h2><p>Q1 : Qu'est-ce qu'un fragment dans le contexte de la technologie ?
R1 : Un fragment, dans le contexte de la technologie, fait référence à une quantité spécifique de données qui sont manipulées, transmises ou traitées comme une seule entité. Il peut s'agir d'une partie d'un fichier, d'un paquet de données envoyé sur un réseau ou d'un élément d'information traité par un logiciel.</p><p>Q2 : Comment le fragmentation améliore-t-elle la gestion des données ?
R2 : Le fragmentation des données peut rendre les processus plus efficaces car il permet la transmission ou la gestion simultanée de plusieurs paquets de données. Il peut également réduire les erreurs, faciliter la récupération des données et améliorer la vitesse globale de traitement des données.</p><p>Q3 : Qu'est-ce que le fragmentation des données dans les réseaux ?
R3 : Dans les réseaux, le fragmentation des données fait souvent référence au processus de décomposition d'un fichier de données volumineux en « morceaux » plus petits qui peuvent être transmis séparément sur un réseau. Cela permet une transmission de données plus fiable car cela réduit l'impact d'un seul paquet de données perdu ou corrompu.</p><p>Q4 : Comment fonctionne le découpage en blocs dans la programmation ?
A4 : En programmation, le découpage en blocs peut être utilisé pour décomposer un processus ou une tâche volumineux en « blocs » plus petits et plus faciles à gérer. Cela peut rendre le codage de programmes complexes plus simple et plus efficace. Il peut également être utilisé pour gérer plus efficacement l'utilisation de la mémoire.</p><p>Q5 : Quel est le rôle des blocs dans le stockage informatique ?
A5 : Dans le contexte du stockage informatique, les blocs font souvent référence aux unités de données que les systèmes de stockage lisent et écrivent en tant que groupe. Le découpage en blocs peut optimiser l'utilisation de l'espace de stockage sur disque et améliorer les performances du système.</p><p>Q6 : Le découpage en blocs est-il applicable à tous les types de traitement de données ?
A6 : Pas nécessairement. L'application du découpage en blocs dépend de la nature des données, des exigences spécifiques d'un processus ou d'une tâche donnée et des caractéristiques du système utilisé.</p><p>Q7 : Quels sont les inconvénients potentiels du découpage en blocs ?
A7 : Bien que le découpage puisse améliorer l'efficacité, il peut également entraîner des complications s'il n'est pas effectué correctement. Lorsque des fichiers volumineux sont découpés de manière incorrecte, cela peut entraîner des problèmes tels que la redondance des données, la perte de données et des difficultés lors du réassemblage des données.</p><p>Ressources liées à l'article</p><ul><li>Articles
<ul><li>What is a chunk (coursera) https://www.coursera.org/lecture/learning-how-to-learn/2-2-what-is-a-chunk-LurUJ</li><li>Chunking for learning software development : https://www.learncoderetain.com/chunking-for-learning-software-development/</li><li>https://en.wikipedia.org/wiki/Chunking_(computing)</li><li>Difference between Chunks and Buffer https://www.geeksforgeeks.org/what-is-the-difference-between-chunk-and-the-buffer-data/</li><li>Chunk : https://www.devx.com/terms/chunk/</li><li>Chunking (computing) https://en.wikipedia.org/wiki/Chunking_(computing)</li><li>Chunked transfer encoding : https://en.wikipedia.org/wiki/Chunked_transfer_encoding</li><li>Releasing &quot;Chunk Scatter&quot;, an HTTP chunked encoding analysis tool : https://blog.yonatan.dev/chunk-scatter-http-chunked-response-analysis-tool</li><li>How can I handle HTTP chunked transfer encoding in web scraping? https://webscraping.ai/faq/http/how-can-i-handle-http-chunked-transfer-encoding-in-web-scraping</li></ul></li><li>PHP
<ul><li>https://github.com/symfony/symfony/tree/7.2/src/Symfony/Component/HttpClient/Chunk</li><li>Streamed response in Symphony https://yarnaudov.com/symfony-streamedresponse-large-files-example.html</li><li>A Comprehensive Guide to PHP's <code>array_chunk()</code> Function : https://reintech.io/blog/comprehensive-guide-php-array-chunk-function</li><li>chunk_split : https://www.php.net/manual/fr/function.chunk-split.php</li><li>Threaded::chunk : https://www.php.net/manual/fr/threaded.chunk.php</li><li>Laravel Chunk : https://laravel-france.com/posts/optimisez-votre-application-avec-le-chunk-de-laravel</li></ul></li><li>Slides
<ul><li>SymfonyLive Paris 2023: &quot;Jongler en asynchrone avec Symfony HttpClient&quot; : https://speakerdeck.com/alli83/jongler-en-asynchrone-avec-symfony-httpclient</li><li>Streams : nous sous-estimons tous Predis !
https://afup.org/talks/4289-streams-nous-sous-estimons-tous-predis</li><li>Flush your <head>! - an HTTP performance optimization tool - Reversim Summit '16
: https://speakerdeck.com/cowchimp/flush-your-an-http-performance-optimization-tool-reversim-summit-16?slide=15</li><li>Chunking slides : https://fr.slideshare.net/slideshow/chunking-slides-62307461/62307461</li><li>Chunking : https://fr.slideshare.net/slideshow/chunking-7706736/7706736</li><li>DATA Chunk : https://fr.slideserve.com/marianne/data-chunk</li></ul></li><li>Youtube
<ul><li>Lazy Collection - Pol DELLAIERA + Keynote de clôture - AFUP Day 2021 Lille/Rennes : https://www.youtube.com/watch?v=Kp47f8dtqoo</li><li>Streams : Nous sous-estimons tous Predis ! - Alexandre DAUBOIS - Forum PHP 2023 : https://www.youtube.com/watch?v=84SmSYccpZY</li></ul></li><li>Related
<ul><li>Data deduplication : https://en.wikipedia.org/wiki/Data_deduplication</li><li>Content-Defined Chunking (CDC) like Rolling hash algorithm https://en.wikipedia.org/wiki/Rolling_hash</li><li>Thunk : https://en.wikipedia.org/wiki/Thunk</li><li>High Performance Browser Networking : http://chimera.labs.oreilly.com/books/1230000000545</li></ul></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/chunk-computing-en-php</link><guid>https://blog.darkwood.com/article/chunk-computing-en-php</guid><enclosure url="http://darkwood.com/media/articles/66ceea45c0da2469809018.png" /></item><item><title>Automatiser la Création de Screenshots de Code avec Carbon.now</title><pubDate>Sat, 31 Aug 2024 20:43:33 +0000</pubDate><description><![CDATA[
La création de captures d&#039;écran de code est une tâche courante pour les développeurs, que ce soit pour documenter des projets, partager des extraits de code sur les réseaux sociaux ou illustrer des articles de blog. Carbon.now est un outil populaire qui pe...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66d381b1bac69788137551.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/K-GTIlPka_A?si=CBKgJ17pDrnDxkyx" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>La création de captures d'écran de code est une tâche courante pour les développeurs, que ce soit pour documenter des projets, partager des extraits de code sur les réseaux sociaux ou illustrer des articles de blog. Carbon.now est un outil populaire qui permet de générer des captures d'écran esthétiques de code. Cependant, lorsque vous avez besoin de créer ces images en grande quantité ou de manière automatisée, le faire manuellement devient fastidieux.</p><p>Dans cet article, nous allons explorer comment automatiser la génération de ces captures d'écran en utilisant Carbon.now et Symfony Panther. Panther est un outil de navigation web headless qui nous permettra de manipuler et d'interagir avec Carbon.now de manière programmatique.</p><h2>Pourquoi Automatiser avec Carbon.now ?</h2><p>Carbon.now est un service en ligne simple et efficace pour créer des images de code avec un style personnalisable. Automatiser ce processus présente plusieurs avantages : cela permet de gagner du temps en évitant de répéter la même tâche pour la création de nombreuses images, d'assurer une consistance visuelle en appliquant les mêmes paramètres (thème, police, taille, etc.) à toutes les images, et de faciliter l'intégration de la création d'images de code dans des workflows tels que des pipelines CI/CD, des scripts de publication de blogs, ou des bots de réseaux sociaux.</p><h2>Prérequis</h2><p>Avant de commencer, assurez-vous d'avoir les éléments suivants :</p><ul><li>PHP installé sur votre machine.</li><li>Symfony Panther installé. Si ce n'est pas encore fait, vous pouvez l'installer via Composer :</li></ul><pre><code class="language-bash">composer require symfony/panther
</code></pre><h2>Configurer un Projet PHP avec Panther</h2><p>Commencez par créer une nouvelle classe PHP qui encapsulera toute la logique pour interagir avec Carbon.now. Voici un exemple de classe que nous allons utiliser :</p><pre><code class="language-php">&lt;?php

declare(strict_types=1);

namespace App\Job;

use Symfony\Component\Panther\Client;
use Flow\JobInterface;
use RuntimeException;

class CarbonImageJob implements JobInterface
{
    private const CARBON_URL = 'https://carbon.now.sh/';
    private Client $client;
    private string $type;

    public function __construct(string $type = 'png', bool $disableHeadless = false)
    {
        if (!in_array($type, ['png', 'svg'], true)) {
            throw new \InvalidArgumentException('Type invalide. Seuls les types png et svg sont supportés.');
        }

        $this-&gt;type = $type;
        $this-&gt;client = Client::createChromeClient(null, null, ['headless' =&gt; !$disableHeadless]);
    }

    public function generateScreenshot(string $code, string $path): void
    {
        try {
            $url = $this-&gt;getCarbonUrl($code);
            $this-&gt;download($url, $path);
        } catch (\Exception $e) {
            throw new RuntimeException('Échec de la génération de la capture d\'écran : ' . $e-&gt;getMessage());
        } finally {
            $this-&gt;client-&gt;quit();
        }
    }

    private function getCarbonUrl(string $code): string
    {
        $encodedCode = rawurlencode($code);
        return self::CARBON_URL . '?code=' . $encodedCode . '&amp;t=night-owl';
    }

    private function download(string $url, string $path): void
    {
        $this-&gt;client-&gt;request('GET', $url);

        // Script pour cliquer sur le menu d'exportation
        $this-&gt;client-&gt;executeScript('document.querySelector(&quot;#export-menu&quot;).click();');
        sleep(1); // Petite pause pour que l'interface réponde

        // Script pour cliquer sur le bouton d'exportation correspondant (png/svg)
        $this-&gt;client-&gt;executeScript(sprintf('document.querySelector(&quot;#export-%s&quot;).click();', $this-&gt;type));

        // Attendre que le fichier soit téléchargé
        $this-&gt;waitForFile($path);
    }

    private function waitForFile(string $filePath, int $timeout = 30): void
    {
        $elapsed = 0;
        while (!file_exists($filePath) &amp;&amp; $elapsed &lt; $timeout) {
            sleep(1);
            $elapsed++;
        }

        if (!file_exists($filePath)) {
            throw new RuntimeException('Le fichier n\'a pas été téléchargé dans le temps imparti.');
        }
    }
}
</code></pre><h2>Générer une Capture d'Écran avec Flow</h2><p>Au lieu de générer une capture d'écran de manière directe, vous pouvez utiliser la puissance de la bibliothèque Flow pour orchestrer et paralléliser la création de plusieurs captures d'écran de code avec Carbon.now. Flow est une bibliothèque qui permet d'exécuter des tâches asynchrones et parallèles de manière efficace.</p><h3>Configuration de Flow pour Générer des Captures d'Écran</h3><p>Dans cette étape, nous allons créer une commande Symfony qui utilisera Flow pour générer plusieurs images de code en parallèle. Voici un exemple de commande que vous pouvez ajouter à votre projet Symfony :</p><pre><code class="language-php">&lt;?php

declare(strict_types=1);

namespace App\Command;

use App\Job\FlowExamples\CarbonImageJob;
use App\Model\CarbonImage;
use Flow\Driver\AmpDriver;
use Flow\Driver\FiberDriver;
use Flow\Driver\ReactDriver;
use Flow\Driver\SwooleDriver;
use Flow\Flow\Flow;
use Flow\Ip;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

use function sprintf;

#[AsCommand(
    name: 'app:carbon-image',
    description: 'Cette commande permet de générer des captures d\'écran de code en utilisant Carbon.now.sh avec Flow',
)]
class CarbonImageCommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $io = new SymfonyStyle($input, $output);

        // Sélection du driver Flow aléatoire
        $driver = match (random_int(1, 4)) {
            1 =&gt; new AmpDriver(),
            2 =&gt; new FiberDriver(),
            3 =&gt; new ReactDriver(),
            4 =&gt; new SwooleDriver(),
        };

        // Configuration du Flow pour exécuter les tâches
        $flow = Flow::do(static function () use ($io) {
            yield new CarbonImageJob(__DIR__ . '/../../data/carbon-image/carbon-config.json');
            yield static function (CarbonImage $carbonImage) use ($io) {
                $io-&gt;info(sprintf('Capture d\'écran générée pour : %s (%s)', $carbonImage-&gt;code, $carbonImage-&gt;url));
            };
        }, ['driver' =&gt; $driver]);

        // Création des instances CarbonImage avec le code à capturer
        $ip1 = new Ip(new CarbonImage(&quot;&lt;?php echo 'Hello, World!'; ?&gt;&quot;, __DIR__ . '/../../hello.png'));
        $ip2 = new Ip(new CarbonImage(&quot;&lt;?php
            \$name = 'User';
            echo 'Welcome, ' . htmlspecialchars(\$name) . '!';
            echo '&lt;br/&gt;Today\'s date is ' . date('Y-m-d');
        ?&gt;&quot;, __DIR__ . '/../../welcome_user.png'));
        $ip3 = new Ip(new CarbonImage(&quot;&lt;?php
            \$colors = ['Red', 'Green', 'Blue'];
            foreach(\$colors as \$color) {
                echo '&lt;div style=\&quot;color:' . strtolower(\$color) . '\&quot;&gt;' . \$color . '&lt;/div&gt;';
            }
        ?&gt;&quot;, __DIR__ . '/../../colors_list.png'));
        $ip4 = new Ip(new CarbonImage(&quot;&lt;?php
            \$error_message = 'Error 404: Page not found';
            echo '&lt;h1 style=\&quot;color: red;\&quot;&gt;' . \$error_message . '&lt;/h1&gt;';
            echo '&lt;p&gt;Please check the URL or return to the &lt;a href=\&quot;/\&quot;&gt;homepage&lt;/a&gt;.&lt;/p&gt;';
        ?&gt;&quot;, __DIR__ . '/../../error404_message.png'));
        $ip5 = new Ip(new CarbonImage(&quot;&lt;?php
            \$items = ['Home', 'About', 'Contact'];
            echo '&lt;ul&gt;';
            foreach(\$items as \$item) {
                echo '&lt;li&gt;' . \$item . '&lt;/li&gt;';
            }
            echo '&lt;/ul&gt;';
        ?&gt;&quot;, __DIR__ . '/../../navigation_menu.png'));

        // Exécution des tâches en parallèle
        $flow($ip1);
        $flow($ip2);
        $flow($ip3);
        $flow($ip4);
        $flow($ip5);

        // Attente de la fin de toutes les tâches
        $flow-&gt;await();

        $io-&gt;success('Les captures d\'écran ont été générées avec succès.');

        return Command::SUCCESS;
    }
}
</code></pre><h2>Explication</h2><ul><li>Command : La commande <code>app:carbon-image</code> permet de générer plusieurs captures d'écran de code en parallèle en utilisant des instances de CarbonImage.</li><li>Flow : Flow orchestre l'exécution parallèle des tâches, ce qui est particulièrement utile pour traiter plusieurs extraits de code à la fois.</li><li>Drivers : Flow propose plusieurs drivers pour gérer l'asynchronisme. Ici, un driver est choisi aléatoirement pour démontrer la flexibilité, mais vous pouvez spécifier un driver spécifique selon vos besoins.</li><li>CarbonImage : Chaque instance de <code>CarbonImage</code> représente un extrait de code à convertir en image. Le code source et le chemin de sauvegarde sont spécifiés pour chaque instance.</li></ul><h2>Personnaliser Votre Capture d'Écran</h2><p>La classe <code>CarbonImageJob</code> peut être facilement étendue pour accepter différentes configurations de thème, de police, de taille, etc. Voici comment vous pouvez le faire :</p><ol><li>Ajouter des paramètres au constructeur pour la configuration.</li><li>Modifier la méthode <code>getCarbonUrl</code> pour inclure ces paramètres dans l'URL de la requête.</li></ol><h2>Conclusion</h2><p>Grâce à Symfony Panther et Flow, vous pouvez facilement automatiser la création de captures d'écran de code avec Carbon.now. Cette automatisation peut être particulièrement utile pour les blogueurs, les formateurs, ou tout développeur souhaitant partager du code de manière visuelle.</p><p>En intégrant ce processus dans vos workflows, vous gagnerez en temps, en consistance, et en efficacité. N'hésitez pas à adapter cette approche à vos besoins spécifiques et à expérimenter avec les nombreuses options de personnalisation offertes par Carbon.now.</p><h2>Se former à Flow</h2><p>Si vous souhaitez approfondir vos connaissances sur le framework Flow et découvrir d'autres moyens d'améliorer votre productivité en tant que développeur, je propose une formation complète sur Flow disponible sur</p><p><a href="https://www.bonzai.pro/matyo91/shop">https://www.bonzai.pro/matyo91/shop</a></p><h2>Ressources Supplémentaires</h2><ul><li><a href="https://flow.darkwood.com">Flow</a></li><li><a href="https://github.com/matyo91/flow-live">Code source du projet</a></li><li><a href="https://symfony.com/doc/current/components/panther.html">Symfony Panther Documentation</a></li><li><a href="https://carbon.now.sh">Carbon.now.sh</a></li><li><a href="https://www.php.net/manual/en/">Documentation PHP</a></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/automatiser-la-creation-de-screenshots-de-code-avec-carbon-now</link><guid>https://blog.darkwood.com/article/automatiser-la-creation-de-screenshots-de-code-avec-carbon-now</guid><enclosure url="http://darkwood.com/media/articles/66d381b1bac69788137551.png" /></item><item><title>Scrape les sites de manière efficace</title><pubDate>Sun, 08 Sep 2024 10:56:43 +0000</pubDate><description><![CDATA[
Le scraping web est une technique essentielle pour extraire des données de sites internet, que ce soit pour des recherches, des analyses de marché ou des développements d’applications. En PHP, il est possible de tirer parti des modèles asynchrones, de la g...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66dd82eb68d24301675691.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/u2i9cUi0o3M?si=rZAx6Sn8IM0_z1Z2" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Le scraping web est une technique essentielle pour extraire des données de sites internet, que ce soit pour des recherches, des analyses de marché ou des développements d’applications. En PHP, il est possible de tirer parti des modèles asynchrones, de la gestion des IP et du pattern Y-combinator pour réaliser des tâches de scraping de manière efficace et évolutive. Cet article vous guide à travers trois étapes pour construire un scraper puissant : en commençant par un scraper basique d’URLs, en ajoutant une gestion avancée des IPs, et en finissant par l’utilisation du pattern Y-Combinator pour des tâches de traitement de données plus complexes.</p><h2>Scraper Basique avec ScrapUrlsJob</h2><p>Au cœur de notre scraper se trouve la classe <code>ScrapUrlsJob</code>, un outil simple mais efficace qui permet de récupérer des données à partir de plusieurs URLs en utilisant la fonctionnalité multi-handle de cURL. Cette technique permet d'envoyer plusieurs requêtes simultanément, ce qui accélère considérablement le processus.</p><p>Comment cela fonctionne :</p><ul><li>cURL Multi-Handle : En créant plusieurs sessions cURL et en les gérant ensemble, on peut exécuter plusieurs requêtes HTTP simultanément.</li><li>Suspension des Fibers : Cette méthode utilise les fibers de PHP pour une gestion asynchrone, suspendant l'exécution en attendant les réponses des URLs.</li></ul><p>Voici l’implémentation de <code>ScrapUrlsJob</code> :</p><pre><code class="language-php">class ScrapUrlsJob implements JobInterface
{
    public function __invoke($urlContents): array
    {
        // Initialisation de la multi-handle cURL
        $mh = curl_multi_init();
        $curl_handles = [];

        // Création et ajout des handles cURL à la multi-handle
        foreach ($urlContents as $urlContent) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $urlContent-&gt;url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_multi_add_handle($mh, $ch);
            $curl_handles[] = [$ch, $urlContent];
        }

        // Exécution des requêtes de manière asynchrone
        do {
            curl_multi_exec($mh, $running);
            Fiber::suspend();
        } while ($running &gt; 0);

        // Récupération des réponses
        $urlContents = [];
        foreach ($curl_handles as [$ch, $urlContent]) {
            $urlContent-&gt;content = curl_multi_getcontent($ch);
            $urlContents[] = $urlContent;
            curl_multi_remove_handle($mh, $ch);
            curl_close($ch);
        }

        // Fermeture de la multi-handle
        curl_multi_close($mh);

        return $urlContents;
    }
}
</code></pre><p>Dans ce job :</p><ul><li>Le scraper envoie plusieurs requêtes en parallèle et suspend l'exécution (<code>Fiber::suspend()</code>) en attendant les réponses.</li><li>Une fois les réponses reçues, le contenu est collecté et traité.</li></ul><p>Ce job est idéal pour scraper des données à partir d’une liste statique d'URLs, là où la limitation de débit ou le blocage des IPs ne pose pas de problème.</p><h2>Scraping Avancé avec ScrapUrlJob et FlattenIpStrategy</h2><p>Lorsqu’il s’agit de sites web sensibles ou limitant le débit des requêtes, la rotation des adresses IP devient essentielle. À cette étape, nous introduisons la classe <code>ScrapUrlJob</code> combinée à la stratégie de gestion d'IP <code>FlattenIpStrategy</code>, qui permet de répartir les requêtes sur plusieurs IPs pour éviter le blocage ou le ralentissement.</p><p>ScrapUrlJob est responsable du scraping d’une URL unique et de la gestion des sessions cURL. Lorsqu’elle est combinée avec FlattenIpStrategy, elle permet de distribuer les requêtes sur différentes adresses IP afin d’éviter les blocages par le serveur cible.</p><p>Voici l'implémentation de <code>ScrapUrlJob</code> :</p><pre><code class="language-php">class ScrapUrlJob implements JobInterface
{
    private CurlMultiHandle $mh;

    public function __construct()
    {
        // Initialize a cURL multi handle
        $this-&gt;mh = curl_multi_init();
    }

    public function __destruct()
    {
        curl_multi_close($this-&gt;mh);
    }

    public function __invoke($urlContent): mixed
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $urlContent-&gt;url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_multi_add_handle($this-&gt;mh, $ch);

        do {
            $status = curl_multi_exec($this-&gt;mh, $active);
            curl_multi_exec($this-&gt;mh, $active);

            Fiber::suspend();

            $info = curl_multi_info_read($this-&gt;mh);
        } while (
            $active &amp;&amp; $status === CURLM_OK // check curl_multi is active
            &amp;&amp; !($info !== false &amp;&amp; $info['handle'] === $ch &amp;&amp; $info['result'] === CURLE_OK) // check $ch is done
        );

        $content = curl_multi_getcontent($ch);
        curl_multi_remove_handle($this-&gt;mh, $ch);
        curl_close($ch);

        return new UrlContent($urlContent-&gt;url, $content);
    }
}
</code></pre><p>Et la stratégie <code>FlattenIpStrategy</code> :</p><pre><code class="language-php">class FlattenIpStrategy implements IpStrategyInterface
{
    private IpPool $ipPool;

    public function __construct()
    {
        $this-&gt;ipPool = new IpPool();
    }

    public function push(PushEvent $event): void
    {
        $ip = $event-&gt;getIp();
        if (!is_iterable($ip-&gt;data)) {
            throw new LogicException('Les données IP doivent être itérables');
        }
        foreach ($ip-&gt;data as $data) {
            $this-&gt;ipPool-&gt;addIp(new Ip($data));
        }
    }

    public function pull(PullEvent $event): void
    {
        $ip = $this-&gt;ipPool-&gt;shiftIp();
        if ($ip !== null) {
            $event-&gt;addIp($ip);
        }
    }

    public function pool(PoolEvent $event): void
    {
        $event-&gt;addIps($this-&gt;ipPool-&gt;getIps());
    }
}
</code></pre><p>Cette stratégie garantit que plusieurs adresses IP sont utilisées lors du scraping, réduisant ainsi les risques de blocage par le serveur cible. En combinant <code>ScrapUrlJob</code> avec <code>FlattenIpStrategy</code>, nous assurons que le scraper est résilient face aux limitations basées sur les IPs.</p><h2>Pattern Y-Combinator</h2><p>Le pattern Y-combinator est une technique de récursion avancée utilisée pour effectuer des opérations complexes. Dans notre cas, nous l’utilisons pour collecter des données utilisateurs à travers plusieurs pages et les agréger de manière asynchrone.</p><p>L’exemple suivant montre l’utilisation du pattern Y-combinator avec <code>YJob</code> pour gérer des tâches de scraping récursives, comme la récupération d'une liste d’utilisateurs, de leurs publications et de leurs tâches.</p><pre><code class="language-php">yield static fn () =&gt; [null, []];
yield [new YJob(function ($rec) {
    return function ($args) use ($rec) {
        [$data, $defer] = $args;

        return $defer(function ($complete, $async) use ($data, $defer, $rec) {
            [$i, $users] = $data;
            if ($i === null) {
                $response = $this-&gt;httpClient-&gt;request('GET', 'https://jsonplaceholder.typicode.com/users');
                Fiber::suspend();
                $users = $response-&gt;toArray();

                $async($rec([[0, $users], $defer]), static function ($result) use ($complete) {
                    $complete($result);
                });
            } elseif ($i &gt;= 0 &amp;&amp; $i &lt; count($users)) {
                $users[$i] = $this-&gt;getUserData($users[$i], $this-&gt;httpClient);

                $async($rec([[$i + 1, $users], $defer]), static function ($result) use ($complete) {
                    $complete($result);
                });
            } else {
                $complete([$users, $defer]);
            }
        });
    };
}), null, null, null, new DeferAsyncHandler()];

yield static function ($users) use ($io) {
    $io-&gt;writeln(sprintf('ScrapYDeferJob : Terminé le scraping de %d utilisateurs', count($users)));
};
</code></pre><p>Dans ce pattern :</p><ul><li>Traitement Récursif : La fonction continue à traiter les utilisateurs jusqu’à ce que toutes les données (comme les tâches et publications) aient été récupérées.</li><li>Gestion de la Suspension : La nature asynchrone du processus est gérée via le <code>DeferAsyncHandler</code>, permettant de suspendre le processus (<code>Fiber::suspend()</code>) et de le reprendre lorsque les données sont disponibles.</li></ul><p>Cette approche est extrêmement flexible et utile lorsqu’on travaille avec des APIs qui renvoient des données paginées ou imbriquées, permettant de chaîner les requêtes et de construire des structures de données complexes en temps réel.</p><h2>Se former à Flow</h2><p>Si vous souhaitez approfondir vos connaissances sur le framework Flow et découvrir d'autres moyens d'améliorer votre productivité en tant que développeur, je propose une formation complète sur Flow disponible sur</p><p><a href="https://www.bonzai.pro/matyo91/shop">https://www.bonzai.pro/matyo91/shop</a></p><h2>Conclusion</h2><p>Le scraping web peut varier d’une tâche simple, comme la récupération de pages statiques, à des opérations plus complexes impliquant des contenus dynamiques et de grands volumes de données. En progressant du scraper basique d’URL (<code>ScrapUrlsJob</code>) aux techniques avancées de gestion des IPs (<code>ScrapUrlJob</code> avec <code>FlattenIpStrategy</code>) et à l'utilisation de la récursivité asynchrone (Y-Combinator avec <code>YJob</code>), vous pouvez construire un scraper en PHP à la fois performant et évolutif.</p><p>Ces méthodes utilisent la puissance des opérations asynchrones, des fibers et de la gestion multi-handle de cURL pour optimiser le processus de scraping et réduire la consommation des ressources. Que vous grattiez de petits ou de grands ensembles de données, ces patterns vous aideront à collecter les informations de manière efficace tout en respectant les serveurs cibles.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/scrape-les-sites-de-maniere-efficace</link><guid>https://blog.darkwood.com/article/scrape-les-sites-de-maniere-efficace</guid><enclosure url="http://darkwood.com/media/articles/66dd82eb68d24301675691.png" /></item><item><title>Bienvenue dans l&#039;ère de la Creator Economy</title><pubDate>Mon, 09 Sep 2024 10:50:44 +0000</pubDate><description><![CDATA[
La Creator Economy est en plein essor, permettant à des millions de créateurs à travers le monde de générer des revenus à partir de leurs passions, connaissances et compétences. Contrairement aux modèles économiques traditionnels, tu n&#039;as plus besoin d&#039;êtr...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66ded30424821576410525.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/FQRDZx7WjKA?si=q5t0PHm3swuVnFH1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>La <em>Creator Economy</em> est en plein essor, permettant à des millions de créateurs à travers le monde de générer des revenus à partir de leurs passions, connaissances et compétences. Contrairement aux modèles économiques traditionnels, tu n'as plus besoin d'être un expert pour réussir. Avec une stratégie bien pensée et l'utilisation intelligente des plateformes numériques, tu peux toi aussi devenir un créateur. Ce guide va te montrer comment.</p><h2>Démarre dans la Creator Economy sans être un expert</h2><p>L'un des plus grands avantages de la <em>Creator Economy</em>, c'est qu'elle démocratise la création de contenu et la monétisation en ligne. Tu n'as pas besoin d'être un expert pour te lancer :</p><ul><li>Simplicité d'accès : Les plateformes comme YouTube, Instagram, TikTok ou Substack rendent la création de contenu accessible à tous.</li><li>Générer des revenus dès le départ : Il existe des stratégies simples pour commencer à monétiser dès les premières étapes, même si tu n'as pas encore une grande audience.</li><li>Ressources en ligne gratuites : De nombreux outils sont disponibles pour apprendre à optimiser tes contenus et les rendre visibles.</li></ul><p>Si tu es un expert dans un domaine, c'est tant mieux. Mais si tu es débutant, tu peux tout de même générer des revenus en ligne. La <em>Creator Economy</em> te permet de partager tes expériences et ton apprentissage en temps réel avec ton audience, en parlant simplement de ce qui te passionne.</p><ul><li>Partage authentique : Ton authenticité et ta passion sont tes plus grands atouts. Beaucoup de gens préfèrent suivre quelqu'un qui explore un sujet qu'ils veulent comprendre eux-mêmes, mais n'ont pas le temps ou l'envie d'expérimenter.</li><li>Création de valeur : En partageant tes découvertes, essais et échecs, tu crées de la valeur pour ton audience, qui peut se reconnaître dans ton parcours.</li></ul><p>Tu peux aussi te positionner comme gestionnaire de communauté, ou même offrir tes services pour gérer les publications ou les emails d'un créateur. Il y a de la place pour tout le monde dans cette économie.</p><h2>Trouve ta niche : L'importance d'une spécialisation pointue</h2><p>Le succès dans la <em>Creator Economy</em> repose sur ta capacité à te positionner comme une référence dans une niche ultra-spécifique :</p><ul><li>Pourquoi la niche est cruciale : Une niche te permet de te démarquer dans un océan de contenu. Elle rend ta voix plus authentique et plus ciblée.</li><li>Comment choisir ta niche : Il s'agit de trouver un équilibre entre tes passions, tes compétences et un besoin du marché non satisfait.</li><li>Exemples : De nombreux créateurs prospèrent en se concentrant sur des domaines spécifiques comme le minimalisme, le jardinage en appartement, ou les jeux vidéo rétro.</li></ul><p>La clé pour se démarquer dans la <em>Creator Economy</em> est de te spécialiser. Face à une concurrence intense, te concentrer sur une niche ultra-spécifique est la meilleure stratégie pour devenir une référence dans ton domaine.</p><ul><li>Spécialisation : Choisir un sujet très précis te permettra de t'imposer rapidement comme un expert dans ta niche.</li><li>Exemple de niche : Plutôt que de viser une thématique large comme l'investissement, tu pourrais te concentrer sur une sous-sous-niche, comme l'investissement dans le cuivre.</li></ul><p>En étant méthodique et en choisissant une spécialité très ciblée, tu peux devenir une autorité reconnue en seulement quelques mois. Attention, une niche trop générale pourrait te confronter à des créateurs établis, rendant la compétition plus difficile.</p><h2>Choisi tes réseaux sociaux</h2><p>Choisis la plateforme sur laquelle tu te sens le plus à l’aise. Chaque réseau social a ses propres codes et dynamiques. La maîtrise des outils spécifiques à chaque plateforme est essentielle pour maximiser ton impact.</p><ul><li>Optimiser tes résultats : Il est crucial de comprendre le fonctionnement de chaque réseau pour attirer efficacement une audience. Que tu sois sur Instagram, TikTok, ou YouTube, adapte ton approche en fonction de la plateforme choisie.</li></ul><p>Si tu cherches des astuces pour optimiser tes résultats sur les réseaux sociaux, tu trouveras des ressources sur Bonzai Premium pour perfectionner ta stratégie.</p><h2>Monétise ta passion : Transforme ta passion en profit</h2><p>Monétiser ta passion peut sembler risqué, mais avec une bonne stratégie, c'est une voie extrêmement gratifiante :</p><ul><li>Commencer par le partage : Il n'est pas nécessaire d'avoir un produit ou un service dès le début. Le simple fait de partager tes expériences et tes conseils peut suffire à attirer une audience fidèle.</li><li>Diversifier les sources de revenus : Utilise des stratégies comme le parrainage, les abonnements, la vente de produits numériques (e-books, formations) ou encore le financement participatif via des plateformes comme Patreon.</li><li>Passion et authenticité : Les créateurs qui réussissent sont ceux qui restent fidèles à eux-mêmes tout en construisant une communauté autour de leurs centres d'intérêt.</li></ul><p>La meilleure manière de vendre dans la <em>Creator Economy</em> est d'utiliser le marketing communautaire. Ce type de marketing te permet de proposer tes offres à une communauté engagée sans avoir l’air agressif.</p><h2>Développe une audience fidèle et engagée</h2><p>Une des clés du succès réside dans le développement d'une communauté engagée :</p><ul><li>Créer du contenu engageant : Apprendre à connaître ton audience et répondre à ses besoins est crucial pour construire une relation durable.</li><li>Les réseaux sociaux comme levier : Des plateformes comme Instagram, TikTok ou encore X (anciennement Twitter) sont des outils puissants pour faire grandir une communauté.</li><li>Interagir régulièrement : Utilise des sondages, des Q&amp;A et interagis avec tes abonnés pour les fidéliser.</li></ul><p>Le terme <em>influenceur</em> est devenu obsolète, souvent perçu de manière négative. Aujourd’hui, on met l'accent sur l'authenticité et la relation avec l'audience. Pour réussir dans la <em>Creator Economy</em>, il est crucial de bâtir une relation de confiance et durable avec ton audience.</p><h2>Capitalise sur la relation : La fin du marketing agressif</h2><p>En 2024, le marketing basé sur la relation et l'authenticité est la clé :</p><ul><li>Écoute ton audience : Prendre en compte les retours te permettra de créer un lien de confiance et de fidéliser ton audience.</li><li>Authenticité et transparence : Les consommateurs sont de plus en plus sensibles à l'authenticité. Évite les techniques de vente agressives, et privilégie des échanges honnêtes et transparents.</li><li>Un marketing d'influence renouvelé : Aujourd'hui, les créateurs s'associent de plus en plus avec des entreprises qui partagent leurs valeurs, plutôt que de suivre les grandes marques aveuglément.</li></ul><h2>Vend sans prise de tête : L'art du marketing communautaire</h2><p>Le marketing communautaire est centré sur l'engagement de la communauté :</p><ul><li>Membres engagés comme ambassadeurs : Tes abonnés fidèles peuvent devenir tes meilleurs ambassadeurs.</li><li>Offrir de la valeur avant tout : En apportant constamment de la valeur, les ventes de produits ou services deviennent une suite naturelle de la relation.</li><li>Exemples concrets : De nombreux créateurs lancent des produits spécifiques à leur communauté, comme des outils pédagogiques ou des produits dérivés.</li></ul><h2>Évite les pièges mortels : Les erreurs à ne pas commettre</h2><p>Il est facile de tomber dans certains pièges lorsque tu te lances dans la <em>Creator Economy</em> :</p><ul><li>Ne pas copier les autres : Reste authentique et ne te contente pas d’imiter ce qui fonctionne pour d'autres.</li><li>Gérer ta réputation en ligne : Des erreurs de communication peuvent parfois endommager de manière irréversible ta réputation.</li><li>L'importance de la constance : Ne te décourage pas si les premiers mois sont difficiles. La constance est essentielle pour réussir à long terme.</li></ul><h2>Saisis les opportunités de la Creator Economy en 2024</h2><p>L'essor de la <em>Creator Economy</em> en 2024 t'offre une opportunité unique pour transformer ta passion en métier. Les plateformes sont accessibles, les outils à disposition, et avec une approche stratégique, même un débutant peut réussir. En suivant les étapes de ce guide, tu es maintenant en mesure de surmonter les obstacles et d'exploiter les nombreuses opportunités offertes par la Creator Economy.</p><h2>Rejoins-moi dans la Creator Economy</h2><p>Je fais partie de la <em>Creator Economy</em> et j'aide des créateurs comme toi à automatiser leurs processus pour maximiser leur impact. Si tu souhaites apprendre à optimiser ton parcours et gagner du temps en automatisant tes tâches, clique sur le lien ci-dessous pour accéder à mon contenu :</p><div align="center"><a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></div><p>Et si tu veux aller encore plus loin, je t’invite à rejoindre le groupe de créateurs Bonzai ! <strong>Profite de notre offre promotionnelle exclusive : seulement 1€ pour la première semaine d’essai</strong>, puis 20€ par mois ensuite. Ne rate pas cette opportunité de t'engager pleinement dans la Creator Economy tout en bénéficiant du soutien d'une communauté active et inspirante.</p><p>Cette offre est limitée, alors n'attends plus !</p><div align="center"><a href="https://www.bonzai.pro/bonzaipremium?offers=trial&bp=t_lg9Kxp">https://www.bonzai.pro/bonzaipremium</a></div><p>C’est le moment idéal pour prendre en main ton aventure dans la Creator Economy et te connecter avec une communauté engagée !</p>
]]></content:encoded><link>https://blog.darkwood.com/article/bienvenue-dans-lere-de-la-creator-economy</link><guid>https://blog.darkwood.com/article/bienvenue-dans-lere-de-la-creator-economy</guid><enclosure url="http://darkwood.com/media/articles/66ded30424821576410525.jpg" /></item><item><title>J’ai comparé 38 outils d’automatisation : voici ce que vous devez savoir</title><pubDate>Sun, 15 Sep 2024 10:50:39 +0000</pubDate><description><![CDATA[
Dans le monde numérique en constante évolution d&#039;aujourd&#039;hui, l&#039;automatisation est devenue un outil essentiel pour les entreprises et les particuliers. Qu&#039;il s&#039;agisse de rationaliser les flux de travail, d&#039;intégrer diverses applications ou de simplifier le...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66e6c5bc3b9a8439331593.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/mSuq1fdzwv4?si=-6ACFjFlWj8E2ptD" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Dans le monde numérique en constante évolution d'aujourd'hui, l'automatisation est devenue un outil essentiel pour les entreprises et les particuliers. Qu'il s'agisse de rationaliser les flux de travail, d'intégrer diverses applications ou de simplifier les tâches répétitives, les outils d'automatisation ont révolutionné la façon dont nous gérons les données et les processus. Avec la grande variété de plateformes d'automatisation disponibles, choisir la bonne peut être difficile. Des plateformes sans code qui permettent aux utilisateurs non techniques aux outils puissants et axés sur les développeurs pour orchestrer des flux de travail complexes, les solutions d'automatisation répondent à un large éventail de besoins. Dans cet article, nous allons explorer une variété d'outils d'automatisation, en comparant leurs principales fonctionnalités, capacités et publics cibles.</p><h2>Présentation du paysage des outils d'automatisation</h2><p>Les outils d'automatisation se présentent sous de nombreuses formes, chacune conçue pour répondre à des objectifs différents. Certains, comme Zapier, IFTTT et Integromat (maintenant Make), offrent des solutions sans code pour connecter des applications et automatiser les flux de travail en toute simplicité. Ces plateformes sont largement utilisées par les utilisateurs non techniques et les petites entreprises pour automatiser les tâches quotidiennes. D’autre part, les outils destinés aux développeurs, comme Apache Airflow, Kestra et Temporal, sont conçus pour gérer des flux de travail à grande échelle, des pipelines de données et des systèmes distribués. Ces plateformes nécessitent généralement des compétences en codage, mais offrent une flexibilité et une puissance inégalées pour orchestrer des processus d’automatisation complexes.</p><p>Pour ceux qui se concentrent sur l’intégration de services et de données, des outils comme Datafire et Pipedream fournissent des solutions robustes pour la gestion des API et l’automatisation des flux de travail. Parallèlement, des plateformes spécialisées comme Apify et UIVision ciblent les utilisateurs qui cherchent à automatiser le scraping Web et les tâches de bureau, en offrant des fonctionnalités avancées comme la reconnaissance optique de caractères (OCR). Les plateformes sans code et à faible code comme Blitznocode et Bonitasoft gagnent également en popularité dans le monde de l’entreprise, permettant aux entreprises de créer des outils internes et d’automatiser des processus sans avoir besoin d’une expertise technique approfondie.</p><p>De plus, des plateformes comme Node-RED et NoFlo apportent une approche de programmation visuelle à l’IoT et aux systèmes distribués, tandis que Google Blockly et Scratch introduisent les concepts de codage aux jeunes apprenants via des interfaces basées sur des blocs. Que vous soyez un utilisateur professionnel à la recherche d'une utilisation simple ou un développeur à la recherche de fonctionnalités avancées, il existe un outil d'automatisation adapté à vos besoins.</p><h2>Détaillons-le</h2><ul><li><a href="https://github.com/Jmgr/actiona">Actiona</a></li></ul><p>Actiona est un outil d'automatisation multiplateforme qui permet aux utilisateurs de créer des scripts pour automatiser des tâches répétitives. Il fournit une interface utilisateur graphique (GUI), le rendant accessible aux utilisateurs sans aucune connaissance en programmation. Les scripts créés peuvent automatiser les flux de travail sur Windows et Linux, simplifiant des tâches telles que les clics de souris, la saisie au clavier, etc. Il est idéal pour les utilisateurs qui cherchent à automatiser efficacement les activités de bureau sans écrire de code.</p><ul><li><a href="https://github.com/tryanything-ai/anything">Anything</a></li></ul><p>Anything est une alternative locale open source à Zapier, écrite en Rust. Il permet aux utilisateurs d'automatiser les flux de travail entre différentes applications et services sur leurs machines locales. Contrairement aux outils d'automatisation basés sur le cloud comme Zapier, Anything fonctionne entièrement localement, offrant une meilleure sécurité et de meilleures performances en ne s'appuyant pas sur des serveurs externes. Rust, connu pour sa rapidité et sa sécurité, rend cet outil très efficace et fiable. Il est particulièrement adapté aux développeurs et aux organisations à la recherche de solutions d'automatisation axées sur la confidentialité et les performances.</p><ul><li><a href="https://airflow.apache.org">Apache Airflow</a></li></ul><p>Apache Airflow est une plate-forme open source conçue pour créer, planifier et surveiller par programmation des flux de travail. Il permet aux utilisateurs de définir des flux de travail complexes sous forme de graphiques acycliques dirigés (DAG), ce qui en fait un outil puissant pour orchestrer des pipelines de données et d'autres tâches automatisées. Airflow prend en charge les pipelines dynamiques qui peuvent être modifiés en fonction de l'environnement ou de facteurs externes. Avec son vaste écosystème de plugins et d'intégrations, Airflow est largement utilisé dans l'ingénierie des données, les processus ETL et les flux de travail d'apprentissage automatique. Son interface utilisateur Web permet une surveillance et une gestion visuelles des flux de travail, ce qui en fait un outil essentiel pour les scénarios d'automatisation complexes.</p><ul><li><a href="http://apify.com">Apify</a></li></ul><p>Apify est une plateforme de scraping et d'automatisation Web basée sur le cloud. Elle permet aux utilisateurs d'extraire des données de sites Web, de les traiter et de les intégrer dans divers flux de travail. Apify fournit des scrapers Web prêts à l'emploi et personnalisables, ce qui facilite l'automatisation des tâches de collecte de données à grande échelle. De plus, l'API d'Apify permet aux développeurs de gérer les tâches de scraping Web par programmation, et sa plateforme prend en charge l'extraction de données à partir de sites Web dynamiques à l'aide de navigateurs sans tête. Il est largement utilisé pour les études de marché, le référencement, le commerce électronique et la surveillance.</p><ul><li><a href="https://itnext.io/smart-developers-dont-code-2bf882568c37">Apache Camel</a></li></ul><p>Apache Camel est un framework d'intégration open source conçu pour aider les développeurs à intégrer différents systèmes à l'aide d'un modèle d'intégration d'entreprises (EIP). Il fournit un moyen standardisé et flexible de connecter divers systèmes via divers protocoles de transport, tels que HTTP, JMS ou FTP, sans avoir besoin d'écrire un code volumineux. Avec Camel, les développeurs peuvent définir des règles de routage et de médiation dans un langage spécifique au domaine (DSL), ce qui facilite la création, le déploiement et la maintenance des intégrations au sein d'une organisation. Sa nature légère et sa prise en charge de l'architecture de microservices en font un choix populaire pour la création d'intégrations évolutives.</p><ul><li><a href="https://play.google.com/store/apps/details?id=com.llamalab.automate">Automate</a></li></ul><p>Automate est une application Android qui permet aux utilisateurs de créer des scripts d'automatisation sur leurs appareils à l'aide d'une interface simple basée sur un organigramme. Avec Automate, les utilisateurs peuvent automatiser presque toutes les tâches sur leurs smartphones ou tablettes, comme l'envoi de SMS, le basculement des paramètres, l'exécution d'applications, etc. L'application propose diverses actions et déclencheurs tels que l'emplacement, l'heure ou les événements qui peuvent être liés entre eux pour créer des flux de travail complexes. Son interface intuitive par glisser-déposer facilite la conception de flux d'automatisation sans avoir à écrire de code, ce qui la rend accessible aux débutants comme aux utilisateurs avancés.</p><ul><li><a href="https://www.automa.site">Automa</a></li></ul><p>Automa est une extension de navigateur conçue pour automatiser les tâches répétitives dans l'environnement du navigateur. Elle permet aux utilisateurs d'automatiser des actions telles que le remplissage de formulaires, la prise de captures d'écran, le scraping de données de sites Web, etc. en connectant des blocs visuellement. Les utilisateurs peuvent créer des flux d'automatisation sans aucune connaissance en codage en reliant différentes actions entre elles. Cet outil est très utile pour le scraping Web, les tests et les tâches répétitives basées sur le navigateur, améliorant la productivité et l'efficacité en gérant facilement les processus de routine.</p><ul><li><a href="https://www.blitznocode.com">Blitznocode</a></li></ul><p>Blitznocode est une plate-forme sans code qui permet aux entreprises de créer des outils et des applications internes sans nécessiter de compétences en programmation. Elle permet aux utilisateurs de transformer rapidement et efficacement leur logique métier en applications fonctionnelles. Avec Blitz, les entreprises peuvent rationaliser les flux de travail internes, créer des outils personnalisés et automatiser les processus, améliorant ainsi l'efficacité opérationnelle sans s'appuyer sur le développement logiciel traditionnel. La plateforme est conçue pour être accessible aux utilisateurs non techniques, ce qui la rend idéale pour les petites et moyennes entreprises qui cherchent à numériser leurs opérations.</p><ul><li><a href="https://fr.bonitasoft.com">Bonitasoft</a></li></ul><p>Bonitasoft est une plateforme open source d'automatisation des processus métier qui aide les organisations à optimiser leurs opérations commerciales. La plateforme fournit des outils puissants pour créer, exécuter et surveiller les flux de travail et les processus métier. En mettant l'accent sur la gestion des processus métier (BPM), Bonitasoft permet aux utilisateurs de concevoir des flux de travail complexes visuellement, de s'intégrer à des systèmes externes et d'automatiser efficacement les tâches. Elle est idéale pour les organisations qui cherchent à améliorer l'efficacité opérationnelle et à rationaliser les processus entre les services, en proposant des éditions communautaires et d'entreprise.</p><ul><li><a href="https://camunda.com">Camunda</a></li></ul><p>Camunda est une plateforme open source d'automatisation des flux de travail et des processus. Elle permet aux organisations de définir, d'exécuter et de surveiller les processus métier à l'aide des normes Business Process Model and Notation (BPMN) et Decision Model and Notation (DMN). L'architecture légère de Camunda le rend adapté aux microservices, tandis que sa flexibilité lui permet d'être intégré à diverses technologies et systèmes. Il est largement utilisé pour automatiser les tâches, les règles métier et les flux de travail humains dans tous les secteurs.</p><ul><li><a href="https://github.com/bolinfest/chickenfoot">Chickenfoot</a></li></ul><p>Chickenfoot est une extension Firefox qui permet aux utilisateurs d'automatiser et de scripter les interactions avec les pages Web. Il a été conçu pour simplifier l'automatisation Web en fournissant une interface de script directement dans le navigateur. Chickenfoot utilise un langage de script de haut niveau pour manipuler les éléments Web, permettant aux utilisateurs d'automatiser des tâches telles que la soumission de formulaires, le clic sur des boutons ou l'extraction de données à partir de sites Web. Bien qu'il soit plus ancien, il offre aux utilisateurs un moyen simple d'interagir avec les pages Web par programmation, ce qui le rend utile pour automatiser les tâches répétitives dans le navigateur.</p><ul><li><a href="https://github.com/DataFire/DataFire">Datafire</a></li></ul><p>DataFire est une plate-forme open source qui simplifie l'intégration des API en permettant aux développeurs de créer, déployer et gérer des API et des flux de travail. Il est conçu pour gérer une grande variété de tâches, telles que la synchronisation des données, l'automatisation des processus et les intégrations en temps réel entre différents services. DataFire prend en charge plusieurs API, ce qui permet aux utilisateurs de créer des intégrations sans avoir à gérer manuellement les appels d'API. Cela facilite l'automatisation de flux de travail complexes impliquant de nombreuses API sur différents systèmes.</p><ul><li><a href="https://github.com/antonmi/flowex">Flowex</a></li></ul><p>Flowex est un framework basé sur Elixir conçu pour la création et la gestion de pipelines de traitement de données. Il permet aux développeurs de définir des flux de travail comme une série d'étapes connectées, où les données circulent à travers chaque étape. Flowex exploite le pLe modèle de concurrence d'Elixir permet des exécutions de pipeline hautement efficaces, évolutives et tolérantes aux pannes. Cela en fait un choix approprié pour le traitement des flux de données, la gestion des flux de travail complexes et la garantie de la fiabilité des systèmes de production.</p><ul><li><a href="http://www.flogo.io">Flogo</a></li></ul><p>Flogo est un framework open source conçu pour la création d'applications pilotées par événements, en particulier dans le contexte de l'IoT (Internet des objets) et de l'intégration. Il fournit une plate-forme légère et efficace pour connecter des appareils, des passerelles et des services cloud. L'architecture de Flogo permet aux utilisateurs de développer des flux de travail qui répondent aux événements en temps réel, ce qui le rend idéal pour les applications qui nécessitent un traitement à faible latence. Il est particulièrement connu pour son encombrement léger, qui lui permet de fonctionner efficacement même sur des appareils contraints tels que les passerelles de périphérie et les microcontrôleurs.</p><ul><li><a href="https://www.flyde.dev">Flyde</a></li></ul><p>Flyde est un environnement de programmation visuelle open source qui s'intègre directement dans Visual Studio Code (VS Code). Il permet aux développeurs de créer, de gérer et d'exécuter des flux de travail visuellement tout en s'intégrant au code TypeScript. Flyde est conçu pour les développeurs qui souhaitent tirer parti de la simplicité de la programmation visuelle sans sacrifier la puissance du codage traditionnel. Il prend en charge l'exécution d'applications à la fois dans le navigateur et dans Node.js, ce qui le rend flexible pour divers cas d'utilisation. Cet outil est idéal pour les développeurs qui cherchent à rationaliser le développement de leur flux de travail en combinant des approches visuelles et basées sur le code.</p><ul><li><a href="https://developers.google.com/blockly">Google Blockly</a></li></ul><p>Google Blockly est une bibliothèque de programmation visuelle basée sur le Web qui permet aux utilisateurs de créer des programmes en faisant glisser et en déposant des blocs. Chaque bloc représente un morceau de code et les utilisateurs peuvent les assembler pour créer une logique complexe sans avoir besoin d'écrire du code traditionnel. Blockly est largement utilisé dans les environnements éducatifs pour enseigner les concepts de programmation aux débutants. Il prend en charge une variété de langages, notamment JavaScript, Python et PHP, ce qui le rend adaptable à différents besoins de programmation. Les développeurs peuvent également intégrer Blockly dans des applications Web, permettant aux utilisateurs d'interagir avec une interface visuelle tout en créant du code réel.</p><ul><li><a href="https://github.com/huginn/huginn">Huginn</a></li></ul><p>Huginn est un système open source permettant de créer des agents qui exécutent des tâches automatisées en ligne. Similaire à IFTTT (If This Then That) ou Zapier, Huginn permet aux utilisateurs de créer des flux de travail qui réagissent à des événements spécifiques, tels que des modifications sur des sites Web ou des e-mails. Les agents peuvent être utilisés pour extraire des données Web, surveiller des flux RSS, envoyer des alertes ou même automatiser le traitement des données sur différents services. Contrairement aux services cloud, Huginn est conçu pour être auto-hébergé, offrant aux utilisateurs un contrôle total sur leurs données et leurs automatisations, ce qui en fait une excellente solution pour les utilisateurs et les développeurs soucieux de leur confidentialité qui préfèrent les configurations locales ou personnalisées.</p><ul><li><a href="https://ifttt.com">IFTTT</a></li></ul><p>IFTTT (If This Then That) est une plate-forme d'automatisation populaire qui permet aux utilisateurs de connecter différents services Web, applications et appareils pour créer des flux de travail appelés « applets ». Chaque applet se compose d'un déclencheur (le « si ») et d'une action (le « alors »). Par exemple, un utilisateur peut configurer une applet pour éteindre automatiquement les lumières lorsqu'il quitte la maison, envoyer une notification lorsqu'il est sur le point de pleuvoir ou synchroniser des fichiers entre des services de stockage cloud. IFTTT est conçu pour les utilisateurs techniques et non techniques, offrant des intégrations avec des milliers de services et de produits, ce qui facilite l'automatisation des tâches quotidiennes.</p><ul><li><a href="https://www.make.com">Make</a></li></ul><p>Integrate-io est une plate-forme d'intégration open source conçue pour automatiser les flux de travail entre différentes applications et services. Elle fournit un cadre pour la création d'intégrations à l'aide d'API, permettant aux développeurs de créer des connexions personnalisées entre des services cloud, des bases de données et d'autres systèmes. La plate-forme est utile pour les organisations qui cherchent à rationaliser les opérations, à synchroniser les données et à automatiser les flux de travail complexes. Grâce à sa flexibilité et à son approche centrée sur le développeur, Integrate-io convient à ceux qui souhaitent un contrôle total sur leurs processus d'intégration.</p><ul><li><a href="https://github.com/kestra-io/kestra">Kestra</a></li></ul><p>Kestra est une plate-forme d'orchestration et de gestion de flux de travail open source conçue pour les pipelines de données complexes à grande échelle. Il permet aux développeurs et aux ingénieurs de données de créer, de planifier et de surveiller des flux de travail impliquant l'ingestion, la transformation et d'autres processus automatisés de données. Kestra prend en charge une large gamme de plugins et d'intégrations, ce qui le rend flexible pour différents environnements et cas d'utilisation. Son interface Web offre un moyen simple de visualiser les flux de travail, de suivre la progression et de gérer les exécutions de tâches. Kestra est particulièrement adapté aux flux de travail Big Data, garantissant l'évolutivité et la fiabilité des systèmes distribués.</p><ul><li><a href="https://levity.ai">Levity</a></li></ul><p>Levity est une plateforme d'IA sans code qui permet aux entreprises d'automatiser les tâches impliquant des données non structurées, telles que des images, du texte et des documents. Avec Levity, les utilisateurs peuvent créer des modèles d'IA personnalisés qui classent unnd traite les données sans nécessiter de compétences en programmation. Il s'intègre facilement à d'autres outils et services, permettant aux entreprises d'automatiser les flux de travail impliquant le traitement des données, le support client, la modération de contenu, etc. Levity aide les organisations à tirer parti de l'IA pour réduire le travail manuel et améliorer l'efficacité opérationnelle.</p><ul><li><a href="https://github.com/n8n-io/n8n">n8n.io</a></li></ul><p>n8n est un outil d'automatisation de flux de travail gratuit et open source qui permet aux utilisateurs de connecter diverses applications et services via une interface intuitive basée sur des nœuds. Avec n8n, vous pouvez créer des flux de travail complexes pour automatiser les tâches, les transferts de données et les intégrations sans connaissances approfondies en codage. Il prend en charge une large gamme de nœuds pour différents services tels que les API, les bases de données et les plates-formes de messagerie.</p><p>n8n se distingue par ses capacités d'auto-hébergement, permettant aux utilisateurs de l'exécuter sur leurs propres serveurs pour un meilleur contrôle de la confidentialité et de la sécurité des données. Son architecture extensible permet aux développeurs de créer des nœuds personnalisés à intégrer à pratiquement n'importe quel service. Que vous automatisiez des tâches simples ou que vous créiez des pipelines de données complexes, n8n fournit une plate-forme flexible et puissante adaptée aux particuliers comme aux organisations.</p><ul><li><a href="https://noflojs.org">NoFlo</a></li></ul><p>NoFlo est un outil de programmation open source basé sur les flux (FBP) pour JavaScript qui permet aux développeurs de créer des applications en connectant des composants réutilisables dans une interface visuelle. Avec NoFlo, les développeurs peuvent créer des applications complexes en utilisant un paradigme de programmation « dataflow », où les données se déplacent entre les composants via des graphes dirigés. Chaque composant du système exécute une tâche spécifique, ce qui facilite la conception, la maintenance et l'extension des applications.</p><p>NoFlo est particulièrement adapté à la création de systèmes distribués, d'applications front-end et back-end et de solutions Internet des objets (IoT). Sa nature visuelle simplifie le processus de développement, ce qui en fait un choix populaire pour les développeurs débutants et expérimentés travaillant sur des systèmes complexes. NoFlo s'intègre bien aux frameworks JavaScript modernes et peut être utilisé pour créer des systèmes évolutifs et modulaires.</p><ul><li><a href="https://nodered.org">Nodered</a></li></ul><p>Node-RED est un outil de développement basé sur les flux conçu pour la programmation visuelle, qui permet aux utilisateurs de connecter des périphériques matériels, des API et des services en ligne dans le cadre de l'Internet des objets (IoT). Construit sur Node.js, il fournit une interface Web où les utilisateurs peuvent glisser-déposer des nœuds (représentant des services, des périphériques ou des fonctions) pour créer des flux, en connectant différentes entrées et sorties.</p><p>Node-RED prend en charge une vaste gamme d'intégrations, permettant aux utilisateurs d'automatiser facilement des tâches, de déclencher des événements et de traiter des données à partir de plusieurs sources. Sa nature légère le rend idéal pour les applications IoT, les projets de maison intelligente et le prototypage rapide. Que vous construisiez des automatisations pour des systèmes industriels ou des projets personnels, la flexibilité et la facilité d'utilisation de Node-RED en font un outil puissant pour les développeurs et les non-développeurs.</p><ul><li><a href="https://parabola.io">Parabola</a></li></ul><p>Parabola est une plateforme d'automatisation et de transformation de données sans code qui permet aux utilisateurs de créer des flux de travail en faisant glisser et en déposant des composants dans une interface visuelle. Elle est conçue pour aider les utilisateurs à automatiser les tâches répétitives, à traiter et à manipuler les données et à rationaliser les flux de travail sans avoir à écrire de code. Parabola est idéale pour les entreprises qui cherchent à automatiser leurs flux de données, qu'il s'agisse d'importer des données à partir de diverses sources, de les transformer ou de les exporter vers d'autres applications.</p><p>La plateforme s'intègre à des services populaires tels que Google Sheets, Airtable, Shopify et bien d'autres, permettant aux utilisateurs d'automatiser des tâches telles que la saisie de données, la création de rapports ou la gestion des commandes de commerce électronique. Parabola est bien adapté aux équipes qui ont besoin d'outils de traitement de données puissants mais qui ne veulent pas investir dans un développement personnalisé.</p><ul><li><a href="https://www.prefect.io">Prefect</a></li></ul><p>Prefect est un outil d'orchestration de flux de travail open source conçu pour automatiser et gérer les flux de travail et les pipelines de données. Il permet aux utilisateurs de créer, de surveiller et d'orchestrer des flux de travail complexes en toute simplicité, offrant une visibilité et un contrôle élevés sur le flux de données. L'architecture de Prefect est très flexible et peut être intégrée à divers processus d'ingénierie des données et ETL (Extract, Transform, Load), ce qui en fait un outil puissant pour les organisations axées sur les données.</p><p>Prefect propose également une plate-forme basée sur le cloud, Prefect Cloud, qui améliore la version open source avec des fonctionnalités telles que la surveillance, l'alerte et la gouvernance des flux de travail sans avoir à gérer l'infrastructure. Sa capacité à gérer des flux de travail dynamiques avec une gestion des erreurs, des tentatives et une planification robustes le rend idéal pour la gestion des pipelines de données simples et complexes.</p><ul><li><a href="https://pipedream.com">Pipedream</a></li></ul><p>Pipedream est une plate-forme d'intégration conçue pour que les développeurs puissent facilement créer, exécuter et automatiser des flux de travail qui s'intègrent à des centaines d'API. Pipedream permet aux utilisateurs de connecter des API, des sources de données et des applications, permettant des automatisations avec une configuration minimale. Il prend en charge à la fois les flux de travail basés sur le code et les flux de travail sans code, ce qui le rend flexible pourr divers cas d'utilisation.</p><p>L'architecture sans serveur de Pipedream permet aux utilisateurs de créer des intégrations et des automatisations sans avoir à gérer l'infrastructure, car la plateforme gère la mise à l'échelle et l'exécution. Elle fournit également une bibliothèque de connecteurs, d'intégrations et de modèles prédéfinis, ce qui permet de configurer rapidement et facilement des automatisations pour divers services, notamment Slack, Google Sheets, AWS et bien d'autres.</p><ul><li><a href="https://github.com/refinery-labs/refinery">Refinery.io</a></li></ul><p>Refinery.io était une plateforme basée sur le cloud axée sur la fourniture d'outils de gestion des pipelines de données, en particulier pour les développeurs et les ingénieurs de données. Elle offrait des fonctionnalités de création, de surveillance et de mise à l'échelle des flux de travail de traitement des données, aidant les utilisateurs à gérer des tâches d'automatisation des données à grande échelle. Refinery.io visait à simplifier le processus de configuration et de gestion d'opérations de données complexes grâce à une interface conviviale et à des outils d'automatisation.</p><ul><li><a href="https://scratch.mit.edu">Scratch</a></li></ul><p>Scratch est un langage de programmation visuel gratuit basé sur des blocs et une communauté en ligne conçue principalement pour les enfants et les débutants pour apprendre les concepts de programmation. Développé par le MIT Media Lab, Scratch permet aux utilisateurs de créer des histoires, des jeux et des animations interactifs en assemblant des blocs de code, comme des pièces de puzzle. Il présente des concepts de programmation clés tels que les boucles, les conditions et les variables de manière intuitive et engageante.</p><p>Scratch est largement utilisé dans les environnements éducatifs, des écoles aux clubs de codage, pour enseigner la résolution de problèmes, la pensée logique et la créativité. La plateforme comprend également une communauté mondiale où les utilisateurs peuvent partager leurs projets et collaborer avec d'autres. Scratch est idéal pour tous ceux qui souhaitent se lancer dans le codage, en particulier les jeunes apprenants.</p><ul><li><a href="https://apps.apple.com/us/app/scriptable/id1405459188">Scriptable.app</a></li></ul><p>Scriptable est une puissante application d'automatisation pour iOS qui permet aux utilisateurs de créer et d'exécuter du code JavaScript pour automatiser des tâches sur leurs iPhones ou iPads. Il s'intègre parfaitement aux fonctionnalités iOS, permettant aux utilisateurs d'automatiser les fonctions du système, d'interagir avec les applications et de personnaliser leurs flux de travail à l'aide de scripts. Scriptable peut être utilisé pour récupérer des données à partir d'API, contrôler des appareils domestiques intelligents, générer des notifications et bien plus encore.</p><p>Avec l'accès aux fonctionnalités natives d'iOS telles que le système de fichiers, les services de localisation et la possibilité de planifier des notifications, Scriptable offre aux utilisateurs un niveau de contrôle élevé sur l'automatisation de leur appareil. Il est particulièrement utile pour les développeurs ou les utilisateurs avancés qui souhaitent étendre les fonctionnalités de leurs appareils iOS avec du code personnalisé.</p><ul><li><a href="https://apps.apple.com/us/app/shortcuts/id915249334">Shortcut pour iOS</a></li><li><a href="https://github.com/pfgithub/scpl">Shortcut similaire à Mac OS</a></li><li><a href="https://github.com/steventroughtonsmith/shortcuts-iosmac">Shortcut similaire</a></li></ul><p>Shortcuts est l'application d'automatisation intégrée d'Apple pour les appareils iOS, permettant aux utilisateurs de créer des flux de travail personnalisés qui automatisent les tâches sur les applications et les services de leur iPhone ou iPad. Avec Shortcuts, les utilisateurs peuvent combiner plusieurs actions pour effectuer des tâches telles que l'envoi de messages, la lecture de musique, le contrôle des appareils domestiques intelligents, etc. L'application prend en charge la commande vocale via Siri, permettant une automatisation mains libres. Elle est hautement personnalisable et comprend l'accès à des fonctionnalités système approfondies, permettant aux utilisateurs de créer des automatisations puissantes sans aucune expérience de programmation.</p><ul><li><a href="https://skyvia.com">Skyvia</a></li></ul><p>Skyvia est une plateforme d'intégration, de sauvegarde et de gestion de données basée sur le cloud qui permet aux utilisateurs de connecter divers services cloud, bases de données et applications. Elle prend en charge la synchronisation, la migration et l'intégration des données sans nécessiter de codage. Skyvia est conçue pour aider les entreprises à rationaliser leurs processus de données en fournissant une interface visuelle pour créer des pipelines de données, permettant aux utilisateurs d'automatiser les flux de travail, de déplacer des données entre les plateformes et de les gérer plus efficacement.</p><p>Skyvia propose également des outils de sauvegarde des données dans le cloud et de gestion des API REST, ce qui en fait une solution polyvalente pour les organisations qui cherchent à centraliser et à simplifier leurs flux de travail de gestion des données. Elle s'intègre à des plateformes populaires telles que Salesforce, Google Sheets et les bases de données SQL, entre autres.</p><ul><li><a href="https://github.com/temporalio/samples-php">Temporal</a></li></ul><p>Temporal est une plateforme d'orchestration de flux de travail open source conçue pour simplifier la création, la gestion et la surveillance de flux de travail complexes dans des systèmes distribués. Il fournit un cadre durable et fiable pour la gestion des opérations avec état, ce qui le rend idéal pour gérer les tâches de longue durée, les tentatives et les échecs dans les environnements distribués.</p><p>Temporal permet aux développeurs de définir des flux de travail dans le code à l'aide de langages de programmation populaires tels que Go, Java et PHP. Il est conçu pour garantir que les flux de travail sont exécutés de manière fiable, même en cas de pannes de réseau, de plantages de processus ou d'autres problèmes. Les exemples PHP sur GitHub fournissent des exemples de mise en œuvre de flux de travail temporels dans des applications PHP, illustrant sa capacité à gérer les processus distribués et à garantir une exécution fiable des tâches.</p><ul><li><a href="https://titanoboa.io">Titanoboa</a></li></ul><p>Titanoboa est un moteur de workflow low-code distribué conçu pour automatiser les processus de big data et servir de plate-forme d'intégration (iPaaS). Il permet aux utilisateurs de créer, planifier et gérer des workflows dans un environnement distribué, ce qui le rend idéal pour gérer des pipelines de données complexes et des tâches d'automatisation de données à grande échelle. Titanoboa prend en charge divers environnements de déploiement, notamment les machines virtuelles (VM), Docker, Kubernetes et les serveurs bare metal, offrant une flexibilité dans la manière et l'endroit où il s'exécute.</p><p>Son approche low-code permet aux utilisateurs de définir des workflows sans nécessiter de connaissances approfondies en programmation, tout en conservant la robustesse nécessaire aux tâches de traitement et d'automatisation des données au niveau de l'entreprise.</p><ul><li><a href="https://tray.io">Tray.io</a></li></ul><p>Tray.io est une plate-forme d'automatisation low-code conçue pour connecter des applications basées sur le cloud et automatiser des workflows complexes. Il fournit aux utilisateurs une interface visuelle pour créer des intégrations puissantes entre divers services et applications. Tray.io permet aux utilisateurs techniques et non techniques de concevoir des flux de travail qui automatisent les flux de données, déclenchent des actions et synchronisent les informations entre les applications, sans avoir besoin de connaissances approfondies en codage.</p><p>Avec son évolutivité de niveau entreprise, Tray.io est particulièrement adapté aux entreprises qui ont besoin d'automatiser des processus complexes impliquant plusieurs applications, API et bases de données. Il prend en charge des fonctionnalités avancées telles que les conditions, la logique de ramification et la gestion des erreurs, ce qui en fait une solution flexible pour automatiser les processus métier dans divers secteurs.</p><ul><li><a href="https://ui.vision/x/desktop-automation">UIVision</a></li></ul><p>UIVision est un outil d'automatisation qui permet aux utilisateurs d'automatiser les tâches du navigateur et du bureau. Il combine l'automatisation Web, l'automatisation du bureau et la reconnaissance optique de caractères (OCR) pour automatiser les tâches répétitives, telles que le remplissage de formulaires, le clic sur des boutons ou l'interaction avec des applications de bureau. UIVision propose un éditeur de flux de travail visuel, où les utilisateurs peuvent créer des automatisations sans connaissances en programmation, mais il fournit également des options de script pour les utilisateurs plus avancés.</p><p>La flexibilité d'UIVision en fait un outil utile pour le scraping Web, l'automatisation des tests de navigateur et la gestion des applications de bureau. Ses capacités OCR permettent aux utilisateurs d'extraire du texte à partir d'images ou de PDF, ce qui le rend particulièrement utile pour les tâches impliquant de travailler avec des données non structurées.</p><ul><li><a href="https://www.workato.com">Workato</a></li></ul><p>Workato est une plate-forme d'automatisation d'entreprise qui permet aux entreprises d'automatiser les flux de travail sur diverses applications et services. Elle offre un environnement sans code/à faible code dans lequel les utilisateurs peuvent créer des intégrations, appelées « recettes », pour automatiser des tâches telles que la synchronisation des données, la gestion des processus et l'intégration d'applications. Workato s'intègre à des milliers d'applications commerciales populaires, notamment CRM, ERP, outils d'automatisation du marketing, etc., permettant aux entreprises de rationaliser leurs opérations.</p><p>Workato se concentre sur l'automatisation de niveau entreprise, prenant en charge des flux de travail complexes avec des fonctionnalités telles que la logique conditionnelle, la gestion des erreurs et les déclencheurs en temps réel. Il est idéal pour les organisations qui cherchent à améliorer leur productivité en réduisant le travail manuel et en automatisant les processus commerciaux à grande échelle.</p><ul><li><a href="https://zapier.com">Zapier</a></li></ul><p>Zapier est une plateforme d'automatisation populaire qui permet aux utilisateurs de connecter différentes applications Web et d'automatiser les flux de travail, appelés « Zaps ». Avec Zapier, les utilisateurs peuvent configurer des déclencheurs et des actions sur plus de 7 000 applications sans avoir à écrire de code. Par exemple, les utilisateurs peuvent automatiquement enregistrer les pièces jointes d'un e-mail dans le stockage cloud, envoyer des notifications lorsqu'une nouvelle soumission de formulaire se produit ou synchroniser les données entre des applications telles que Google Sheets, Slack et Trello.</p><p>Zapier est conçu pour les utilisateurs de tous niveaux de compétences techniques, offrant une interface intuitive qui simplifie le processus de création d'automatisations. Sa flexibilité et sa large gamme d'intégrations en font un outil idéal pour les entreprises et les particuliers qui cherchent à réduire les tâches manuelles et à améliorer l'efficacité en automatisant les processus répétitifs.</p><h2>Comparaison</h2><div class="table-responsive"><table class="table table-striped"><thead><tr><th>Tool</th><th>Platform</th><th>Code Requirement</th><th>Key Focus</th><th>Open-source</th><th>Target Users</th><th>Complexity</th><th>Self-hosting</th><th>Overview</th></tr></thead><tbody><tr><td>Actiona</td><td>Desktop</td><td>No-code</td><td>Automation</td><td>No</td><td>Both</td><td>Simple</td><td>No</td><td>Cross-platform automation tool for desktop task automation.</td></tr><tr><td>Anything</td><td>Desktop</td><td>Low-code</td><td>Local Automation</td><td>Yes</td><td>Developers</td><td>Moderate</td><td>Yes</td><td>Local alternative to Zapier written in Rust with a focus on privacy and performance.</td></tr><tr><td>Apache Airflow</td><td>Cloud</td><td>Full-code</td><td>Workflows</td><td>Yes</td><td>Developers</td><td>Complex</td><td>No</td><td>Open-source platform for authoring, scheduling, and monitoring workflows (DAGs).</td></tr><tr><td>Apify</td><td>Cloud</td><td>No-code</td><td>Web Scraping</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Cloud-based web scraping and automation platform.</td></tr><tr><td>Apache Camel</td><td>Desktop/Cloud</td><td>Full-code</td><td>Integration</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Open-source integration framework using enterprise integration patterns (EIPs).</td></tr><tr><td>Automate</td><td>Mobile</td><td>No-code</td><td>Mobile Automation</td><td>No</td><td>Both</td><td>Simple</td><td>No</td><td>Android app for creating automation workflows via flowcharts.</td></tr><tr><td>Automa</td><td>Browser</td><td>No-code</td><td>Browser Automation</td><td>No</td><td>Both</td><td>Simple</td><td>No</td><td>Browser extension to automate web tasks by connecting blocks.</td></tr><tr><td>Blitznocode</td><td>Cloud</td><td>No-code</td><td>Internal Tools</td><td>No</td><td>Business</td><td>Moderate</td><td>No</td><td>No-code platform for building internal tools and automating workflows.</td></tr><tr><td>Bonitasoft</td><td>Cloud</td><td>Low-code</td><td>BPM</td><td>Yes</td><td>Business</td><td>Moderate</td><td>No</td><td>Open-source business process automation platform for BPM.</td></tr><tr><td>Camunda</td><td>Cloud</td><td>Low-code</td><td>BPM</td><td>Yes</td><td>Both</td><td>Complex</td><td>Yes</td><td>Open-source platform for workflow and process automation using BPMN/DMN.</td></tr><tr><td>Chickenfoot</td><td>Browser</td><td>Full-code</td><td>Web Automation</td><td>Yes</td><td>Developers</td><td>Simple</td><td>No</td><td>Firefox extension for automating web tasks using high-level scripts.</td></tr><tr><td>Datafire</td><td>Cloud</td><td>Full-code</td><td>API Integration</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Open-source platform for API integrations and workflow automation.</td></tr><tr><td>Flowex</td><td>Cloud</td><td>Full-code</td><td>Data Pipelines</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Elixir-based framework for managing data pipelines and workflows.</td></tr><tr><td>Flogo</td><td>Cloud/IoT</td><td>No-code</td><td>IoT</td><td>Yes</td><td>Both</td><td>Moderate</td><td>No</td><td>Open-source framework for building event-driven IoT applications.</td></tr><tr><td>Flyde</td><td>Desktop</td><td>No-code</td><td>Visual Programming</td><td>Yes</td><td>Developers</td><td>Moderate</td><td>No</td><td>Visual programming environment for VS Code integrating with TypeScript.</td></tr><tr><td>Google Blockly</td><td>Browser</td><td>No-code</td><td>Education</td><td>Yes</td><td>Education</td><td>Simple</td><td>No</td><td>Web-based visual programming library for building code using blocks.</td></tr><tr><td>Gluedata</td><td>Cloud</td><td>Low-code</td><td>Data Integration</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Data integration platform to connect, manage, and process data across sources.</td></tr><tr><td>Huginn</td><td>Cloud</td><td>Full-code</td><td>Automation Agents</td><td>Yes</td><td>Developers</td><td>Moderate</td><td>Yes</td><td>Open-source system for creating agents that automate online tasks.</td></tr><tr><td>IFTTT</td><td>Cloud</td><td>No-code</td><td>Automation</td><td>No</td><td>Both</td><td>Simple</td><td>No</td><td>Popular automation platform for connecting services via applets.</td></tr><tr><td>Kestra</td><td>Cloud</td><td>Full-code</td><td>Data Pipelines</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Open-source orchestration platform for complex data pipelines.</td></tr><tr><td>Levity</td><td>Cloud</td><td>No-code</td><td>AI Automation</td><td>No</td><td>Business</td><td>Moderate</td><td>No</td><td>No-code AI platform for automating tasks involving unstructured data.</td></tr><tr><td>n8n.io</td><td>Self-hosted</td><td>Full-code</td><td>Workflow Automation</td><td>Yes</td><td>Both</td><td>Moderate</td><td>Yes</td><td>Open-source workflow automation tool supporting self-hosting.</td></tr><tr><td>NoFlo</td><td>Browser</td><td>Full-code</td><td>Flow-based Programming</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Flow-based programming tool for building distributed systems in JavaScript.</td></tr><tr><td>Node-RED</td><td>Cloud</td><td>Full-code</td><td>IoT Automation</td><td>Yes</td><td>Both</td><td>Moderate</td><td>Yes</td><td>Flow-based tool for visual programming and IoT automation.</td></tr><tr><td>Parabola</td><td>Cloud</td><td>No-code</td><td>Data Workflows</td><td>No</td><td>Business</td><td>Moderate</td><td>No</td><td>No-code platform for automating data workflows by dragging and dropping.</td></tr><tr><td>Prefect</td><td>Cloud</td><td>Full-code</td><td>Data Orchestration</td><td>Yes</td><td>Developers</td><td>Moderate</td><td>No</td><td>Open-source workflow orchestration tool for managing data pipelines.</td></tr><tr><td>Pipedream</td><td>Cloud</td><td>Low-code</td><td>API Integrations</td><td>No</td><td>Developers</td><td>Moderate</td><td>No</td><td>Integration platform for automating workflows with hundreds of APIs.</td></tr><tr><td>Refinery.io</td><td>Cloud</td><td>Low-code</td><td>Data Pipelines</td><td>No</td><td>Developers</td><td>Moderate</td><td>No</td><td>Cloud-based data pipeline management platform.</td></tr><tr><td>Scratch</td><td>Browser</td><td>No-code</td><td>Education</td><td>Yes</td><td>Education</td><td>Simple</td><td>No</td><td>Block-based visual programming language designed for children and beginners.</td></tr><tr><td>Scriptable</td><td>Mobile</td><td>Low-code</td><td>Mobile Automation</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Automation app for iOS that uses JavaScript to automate tasks.</td></tr><tr><td>Shortcuts for iOS</td><td>Mobile</td><td>No-code</td><td>Mobile Automation</td><td>No</td><td>Both</td><td>Simple</td><td>No</td><td>Apple&#39;s built-in automation app for iOS to automate workflows.</td></tr><tr><td>Skyvia</td><td>Cloud</td><td>No-code</td><td>Data Integration</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Cloud-based data integration, backup, and management platform.</td></tr><tr><td>Temporal</td><td>Cloud</td><td>Full-code</td><td>Distributed Workflows</td><td>Yes</td><td>Developers</td><td>Complex</td><td>Yes</td><td>Open-source workflow orchestration platform for distributed systems.</td></tr><tr><td>Titanoboa</td><td>Cloud</td><td>Low-code</td><td>Big Data Automation</td><td>Yes</td><td>Both</td><td>Complex</td><td>Yes</td><td>Distributed low-code workflow engine for big data automation.</td></tr><tr><td>Tray.io</td><td>Cloud</td><td>Low-code</td><td>Workflow Automation</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Low-code automation platform for complex workflows and app integration.</td></tr><tr><td>UIVision</td><td>Browser/Desktop</td><td>No-code</td><td>Automation</td><td>No</td><td>Both</td><td>Simple</td><td>Yes</td><td>Automation tool for browser and desktop tasks with OCR support.</td></tr><tr><td>Workato</td><td>Cloud</td><td>No-code</td><td>Enterprise Automation</td><td>No</td><td>Business</td><td>Moderate</td><td>No</td><td>Enterprise automation platform for automating workflows across apps and services.</td></tr><tr><td>Zapier</td><td>Cloud</td><td>No-code</td><td>Workflow Automation</td><td>No</td><td>Both</td><td>Moderate</td><td>No</td><td>Popular automation platform for connecting apps and creating workflows.</td></tr></tbody></table></div><p>Le tableau compare 39 outils d'automatisation selon divers critères tels que la plateforme, les exigences de code, l'objectif principal, la disponibilité open source, les utilisateurs cibles, la complexité et la capacité d'auto-hébergement. Des outils comme Actiona, Automate et Automa se concentrent sur l'automatisation sans code ou à faible code sur les plates-formes de bureau, mobiles et de navigateur, permettant aux utilisateurs d'automatiser facilement les tâches répétitives. Anything, écrit en Rust, offre une automatisation locale avec une alternative axée sur la confidentialité à Zapier, tandis qu'Apache Airflow, Kestra et Temporal s'adressent aux développeurs qui ont besoin d'outils d'orchestration de flux de travail à code complet pour gérer des pipelines de données complexes et des flux de travail distribués.</p><p>De nombreux outils comme Blitznocode, Bonitasoft et Camunda se concentrent sur la gestion des processus métier (BPM), fournissant des environnements à faible code pour l'automatisation des processus internes, tandis que des plates-formes comme Google Blockly et Scratch sont éducatives, conçues pour enseigner les concepts de programmation avec des interfaces visuelles. Node-RED et NoFlo mettent l'accent sur la programmation basée sur les flux pour l'IoT et les systèmes distribués, avec des capacités d'auto-hébergement.</p><p>Les plateformes basées sur le cloud comme Zapier, Tray.io et Workato offrent des interfaces sans code pour connecter des applications et automatiser les flux de travail, tandis que n8n.io offre des fonctionnalités similaires mais prend en charge l'auto-hébergement pour les utilisateurs plus soucieux de la confidentialité. Les plateformes d'intégration d'API comme Pipedream et Datafire sont destinées aux développeurs qui ont besoin d'automatiser les intégrations entre différents services Web. D'autre part, des outils comme Scriptable et Shortcuts pour iOS offrent aux utilisateurs mobiles des capacités d'automatisation via JavaScript et le système d'automatisation intégré d'iOS.</p><p>Plusieurs plateformes sont spécifiquement destinées à la gestion de données à grande échelle et à l'automatisation, notamment Titanoboa pour l'automatisation du big data, Gluedata pour l'intégration de données et Prefect pour l'orchestration de données. Enfin, des outils comme Apify et UIVision offrent des capacités d'automatisation spécialisées comme le scraping Web et l'automatisation de bureau avec des fonctionnalités de reconnaissance optique de caractères (OCR).</p><p>Dans l'ensemble, la comparaison présente une large gamme d'outils conçus pour différents utilisateurs et besoins d'automatisation, des solutions sans code destinées aux utilisateurs professionnels aux plateformes plus complexes centrées sur les développeurs et axées sur les pipelines de données, les API et les flux de travail distribués.</p><h2>Cas d'utilisation et applications concrètes</h2><p>Les outils d'automatisation sont efficaces lorsqu'ils sont appliqués à des scénarios concrets et spécifiques. Voici quelques exemples :</p><ul><li>Zapier : largement utilisé par les petites entreprises pour automatiser les tâches marketing. Par exemple, la publication automatique de nouveaux articles de blog sur les réseaux sociaux ou la synchronisation des soumissions de formulaires d'un site Web vers un CRM comme Salesforce.</li><li>Apache Airflow : couramment utilisé dans l'ingénierie des données pour gérer des processus ETL (Extraction, Transformation, Chargement) complexes. Airflow planifie et surveille les pipelines de données, gérant des milliers de tâches quotidiennement pour des entreprises comme Airbnb.</li><li>Automatiser : utile pour les automatisations mobiles personnelles telles que le déclenchement de rappels basés sur la localisation ou la gestion automatique des paramètres Wi-Fi et Bluetooth sur les appareils Android.</li></ul><h2>Avantages et inconvénients de chaque catégorie d'outils</h2><p>Chaque catégorie d'outils d'automatisation offre différents avantages et limites :</p><ul><li><p>Sans code : facile à utiliser, idéal pour les utilisateurs non techniques, mais limité en flexibilité. Exemple : Zapier est rapide à configurer mais peut avoir des difficultés avec des flux de travail très complexes.</p></li><li><p>Avantages : configuration rapide, courbe d'apprentissage minimale.</p></li><li><p>Inconvénients : personnalisation limitée, coûts plus élevés à mesure que vous évoluez.</p></li><li><p>Faible code : offre plus de flexibilité sans nécessiter de connaissances approfondies en codage. Exemple : Blitznocode permet de créer des applications internes avec un minimum de code.</p></li><li><p>Avantages : flexible, plus rapide que le code complet.</p></li><li><p>Inconvénients : nécessite toujours certaines connaissances techniques.</p></li><li><p>Code complet : extrêmement puissant, mais nécessite l'expertise du développeur. Exemple : Apache Airflow offre un contrôle inégalé sur les pipelines de données, mais nécessite une connaissance de Python et des DAG.</p></li><li><p>Avantages : grande flexibilité, parfait pour les cas d'utilisation complexes.</p></li><li><p>Inconvénients : courbe d'apprentissage plus raide, temps de configuration plus long.</p></li></ul><h2>Modèles de tarification et de licence</h2><p>Comprendre la tarification des outils d'automatisation vous aide à planifier les coûts :</p><ul><li>Zapier : propose un niveau gratuit, mais l'évolution vers des tâches plus complexes nécessite un plan payant, à partir de 19,99 $/mois.</li><li>n8n.io : gratuit et sous licence de code équitable s'il est auto-hébergé, mais propose des plans hébergés dans le cloud à partir de 20 $/mois.</li><li>Workato : principalement destiné aux entreprises, avec des prix adaptés aux besoins personnalisés, ce qui le rend plus cher que les autres outils.</li><li>Bonitasoft : propose à la fois une édition communautaire gratuite et une édition entreprise payante avec des fonctionnalités supplémentaires.</li></ul><h2>Considérations relatives à la sécurité et à la confidentialité</h2><p>La sécurité est cruciale, en particulier pour les plateformes basées sur le cloud. Voici comment différents outils abordent cette question :</p><ul><li>Les options d'auto-hébergement comme Huginn ou n8n.io permettent un contrôle total des données, offrant une confidentialité et une sécurité accrues pour les flux de travail sensibles.</li><li>Les plateformes cloud comme Zapier et IFTTT stockent les données sur des serveurs externes, ce qui peut être une préoccupation pour les entreprises qui traitent des informations sensibles.</li><li>Levity, une plateforme d'automatisation pilotée par l'IA, met l'accent sur la conformité stricte des données, en particulier lors du traitement de données non structurées telles que des images ou des documents. Ils s'intègrent aux fournisseurs de cloud conformes au RGPD pour la sécurité des données.</li></ul><h2>Facilité d'intégration avec les plateformes populaires</h2><p>L'un des principaux arguments de vente des outils d'automatisation est leur bonne intégration avec les services populaires :</p><ul><li>Zapier prend en charge plus de 7 000 intégrations, ce qui en fait un excellent choix pour les entreprises ayant besoin de flexibilité sur des applications telles que Google Sheets, Slack ou Shopify.</li><li>Integromat (Make) est populaire pour ses capacités d'intégration avancées, permettant des flux de travail en plusieurs étapes et la gestion des erreurs avec des applications telles que Trello, Dropbox et GitHub.</li><li>Pipedream est très populaire parmi les développeurs pour ses intégrations avec des services tels qu'AWS Lambda, Twilio et les API HTTP, permettant aux utilisateurs plus techniques de créer des flux de travail sans serveur.</li></ul><h2>Tendances du marché et avenir de l'automatisation</h2><p>L'automatisation s'oriente de plus en plus vers des processus pilotés par l'IA et des plateformes low-code/no-code. Des outils comme Levity exploitent l'apprentissage automatique pour gérer des données non structurées, ce qui permet d'automatiser des tâches plus complexes comme la classification de documents ou la reconnaissance d'images.</p><ul><li>Automatisation pilotée par l'IA : les entreprises utilisent l'IA pour automatiser les tâches de prise de décision. Par exemple, Levity permet aux entreprises de créer des modèles d'IA personnalisés pour automatiser le tri des e-mails ou la classification des tickets d'assistance client.</li><li>Croissance low-code : des plateformes comme Blitznocode et Bonitasoft deviennent de plus en plus populaires à mesure que les entreprises cherchent à automatiser les flux de travail sans dépendre fortement des développeurs.</li></ul><h2>Guide de sélection des outils</h2><p>Lorsque vous choisissez le bon outil, tenez compte des facteurs suivants :</p><ul><li>Taille de l'entreprise : une petite entreprise peut bénéficier de Zapier ou d'Integromat, tandis que les grandes entreprises avec des flux de travail complexes auraient besoin d'un outil comme Apache Airflow ou Camunda.</li><li>Budget : les options gratuites et open source comme n8n.io et Huginn sont idéales pour les entreprises ayant des budgets plus serrés, tandis que les outils d'entreprise comme Workato sont les meilleurs pour ceux qui sont prêts à investir dans des fonctionnalités haut de gamme.</li><li>Expertise technique : les plateformes sans code comme IFTTT sont idéales pour les utilisateurs non techniques, tandis que les plateformes à code complet comme Flowex et Kestra sont mieux adaptées aux développeurs.</li></ul><h2>Expérience utilisateur et courbe d'apprentissage</h2><p>La courbe d'apprentissage varie selon les outils :</p><ul><li>Scratch est adapté aux débutants, parfait pour enseigner aux enfants les principes de codage par glisser-déposer.</li><li>Zapier et Integromat offrent des interfaces utilisateur intuitives, ce qui les rend faciles à apprendre pour les utilisateurs non techniques.</li><li>Apache Airflow ou Temporal nécessitent une compréhension plus approfondie du codage et de l'architecture, ce qui les rend adaptés aux développeurs gérant des tâches complexes.</li></ul><h2>Performances et évolutivité</h2><p>L'évolutivité est essentielle pour les entreprises qui traitent de gros volumes de données :</p><ul><li>Apache Airflow excelle dans l'orchestration de flux de travail à grande échelle sur des systèmes distribués, ce qui en fait la solution de référence pour des entreprises comme Airbnb et Lyft.</li><li>Flogo se distingue par son architecture légère, conçue pour fonctionner sur des appareils à faible consommation dans des environnements IoT.</li><li>Titanoboa est un moteur distribué à faible code optimisé pour les traitements de big data.ng, idéal pour les tâches d'automatisation des données d'entreprise à grande échelle.</li></ul><h2>Communauté et support</h2><p>La force de la communauté d'un outil peut avoir un impact sur la rapidité avec laquelle les utilisateurs peuvent résoudre les problèmes ou trouver des ressources :</p><ul><li>Camunda et Apache Airflow disposent de communautés open source vastes et actives, avec une documentation et des forums complets.</li><li>Zapier propose un support client dédié avec des plans premium, mais dispose également d'une grande communauté en ligne d'utilisateurs partageant des modèles et des intégrations.</li><li>n8n.io a une communauté croissante en raison de sa nature open source, les utilisateurs contribuant régulièrement à de nouveaux nœuds et fonctionnalités.</li></ul><h2>Conclusion</h2><p>Le paysage des outils d'automatisation est diversifié, offrant des solutions pour un large éventail d'utilisateurs, des utilisateurs occasionnels aux développeurs travaillant sur des systèmes de données complexes. Que vous automatisiez des flux de travail pour la productivité personnelle, des processus métier ou des pipelines de données à grande échelle, le bon outil peut améliorer considérablement l'efficacité et réduire les efforts manuels. Les plateformes sans code comme Zapier et Workato rendent l'automatisation accessible à tous, tandis que des outils comme Kestra, Temporal et Apache Airflow offrent la flexibilité et l'évolutivité nécessaires à l'automatisation au niveau de l'entreprise. Alors que la demande d’automatisation continue de croître, comprendre les forces et les faiblesses de ces outils vous aidera à choisir la meilleure solution pour vos besoins.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/jai-compare-38-outils-dautomatisation-voici-ce-que-vous-devez-savoir</link><guid>https://blog.darkwood.com/article/jai-compare-38-outils-dautomatisation-voici-ce-que-vous-devez-savoir</guid><enclosure url="http://darkwood.com/media/articles/66e6c5bc3b9a8439331593.png" /></item><item><title>Introduction à Flow</title><pubDate>Fri, 20 Sep 2024 19:24:09 +0000</pubDate><description><![CDATA[
La présentation liée à l&#039;article :

Connaissez-vous ?

Nodered
Apache Airflow
Google Blockly
Huginn
IFTTT
Zapier
Make
Workato
n8n.io
Kestra
Raccourci
Uniflow
Symfony Messenger

Tout cela relève de la programmation visuelle ou de l&#039;orchestration de données...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/66edcbd980e14990353674.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/jFd3_naDid0?si=oIncphY9XOrRNVKv" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>La présentation liée à l'article :</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/0d851835c331411e96611b2149521aa6" title="Flow introduction in PHP" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;" data-ratio="1.78343949044586"></iframe></div><h2>Connaissez-vous ?</h2><ul><li><a href="https://nodered.org">Nodered</a></li><li><a href="https://airflow.apache.org">Apache Airflow</a></li><li><a href="https://developers.google.com/blockly">Google Blockly</a></li><li><a href="https://github.com/huginn/huginn">Huginn</a></li><li><a href="https://ifttt.com">IFTTT</a></li><li><a href="https://zapier.com">Zapier</a></li><li><a href="https://www.make.com">Make</a></li><li><a href="https://www.workato.com">Workato</a></li><li><a href="https://github.com/n8n-io/n8n">n8n.io</a></li><li><a href="https://github.com/kestra-io/kestra">Kestra</a></li><li><a href="https://apps.apple.com/us/app/shortcuts/id915249334">Raccourci</a></li><li><a href="https://uniflow.io">Uniflow</a></li><li><a href="https://symfony.com/doc/current/messenger.html">Symfony Messenger</a></li></ul><p>Tout cela relève de la programmation visuelle ou de l'orchestration de données</p><h2>Qu'est-ce que Flow ?</h2><p>Il s'agit d'un framework d'orchestration visuelle de données en PHP</p><p>Flow est un framework d'orchestration visuelle de données de pointe conçu spécifiquement pour PHP. Il offre aux développeurs un moyen de créer des flux de travail complexes à l'aide d'une interface visuelle, permettant l'orchestration des données et des processus de manière plus intuitive et évolutive. Flow vous permet de gérer les transformations de données, d'intégrer divers services et de définir des processus asynchrones en toute simplicité, ce qui en fait un outil essentiel pour la création d'applications PHP modernes.</p><h2>Quel est l'objectif de Flow ?</h2><p>Flow cherche à simplifier la manière dont les développeurs créent et gèrent leurs applications PHP en se concentrant sur trois principes fondamentaux</p><ul><li><p>Adopter l'asynchrone comme implémentation native : Flow adopte la programmation asynchrone dès le départ, vous permettant de créer des applications hautement performantes capables de gérer efficacement les tâches simultanées.</p></li><li><p>Construisez votre code avec la programmation fonctionnelle : Flow encourage une approche de programmation fonctionnelle, qui favorise l'immuabilité et la création de fonctions pures, rendant votre code plus prévisible, modulaire et plus facile à tester.</p></li><li><p>Assemblez votre code visuellement : avec Flow, vous pouvez composer et organiser visuellement les différents composants de votre application. Cela permet de voir facilement comment les différents processus interagissent, ce qui vous aide à concevoir et à gérer des flux de travail complexes de manière plus intuitive.</p></li></ul><h2>Programmation basée sur les flux</h2><p>La programmation basée sur les flux (FBP) est un paradigme de programmation introduit par J. Paul Rodker Morrison dans les années 1960. Il a ensuite été implémenté dans divers langages (JavaScript, PHP, C) par Henri Bergius. L'idée principale de FBP est de représenter un modèle d'application sous la forme d'un graphe de processus indépendants où les données sont échangées via des connexions. L'objectif est d'exprimer un problème en termes de transformations de flux de données.</p><p>Par exemple, imaginez une usine d'embouteillage. Une bouteille vide passe d'abord par une étape de remplissage. Une fois cette opération terminée, la bouteille passe à une étape de scellage pour fermer son contenu en toute sécurité. Enfin, la bouteille est étiquetée lors de la dernière étape, ce qui la rend prête à être distribuée.</p><p>Dans FBP, il existe deux perspectives pour visualiser un tel système. La première est l'approche de bas niveau, appelée logique métier, où nous nous concentrons sur chaque composant (ou processus) individuellement. Chaque composant possède une ou plusieurs entrées et sorties. Le rôle de chaque composant est de traiter les données entrantes (entrée) et de renvoyer les résultats via la sortie. Chaque composant peut être implémenté dans n'importe quel langage de programmation.</p><p>La deuxième perspective est l'approche de haut niveau, appelée logique de communication. Dans cette approche, le flux de données est représenté en connectant les composants via les connexions du graphique. Le même composant peut être réutilisé dans différentes parties du graphique. Les données qui circulent dans un tel graphique sont appelées paquets d'informations (IP). De plus, un tel graphique peut être considéré comme une grande boîte noire avec ses propres entrées et sorties, ce qui permet de créer des systèmes cohérents et évolutifs en construisant de nouveaux graphiques à partir de graphiques existants.</p><h3>Avantages de FBP :</h3><ul><li>Parallélisme naturel : si un composant est surchargé de données, vous pouvez simplement le dupliquer (le mettre à l'échelle) pour augmenter la capacité de traitement. C'est ce qu'on appelle la contre-pression, où trop de paquets d'informations submergent un composant.</li><li>Tests unitaires : chaque composant peut facilement être testé unitairement pour son processus spécifique.</li><li>Pas de mémoire partagée ni de verrous : les composants étant indépendants, il n'y a aucun problème de mémoire partagée ou de verrous.</li><li>Représentation visuelle : la création d'un graphique de données est simple à représenter visuellement, ce qui conduit à une programmation visuelle ou même à des solutions sans code.</li></ul><h2>Programmation basée sur le flux en rail de données</h2><p>Basée sur le travail d'Anton Mishchuk, la programmation orientée chemin de fer (ROP) est un modèle de conception axé sur la gestion des erreurs de manière fonctionnelle. Expliquons le concept avec un exemple. Imaginez un processus composé de plusieurs étapes : récupérer une demande d'utilisateur, valider les données, mettre à jour la base de données utilisateur, envoyer un e-mail de vérification et renvoyer le résultat à l'utilisateur.</p><p>Dans la programmation orientée objet classique, vous pouvez écrire une seule fonction pour gérer cette tâche. Mais que se passe-t-il si les données ne sont pas valides ? Vous ajoutez une condition pour gérer ce cas. Que se passe-t-il s'il y a un problème de connexion à la base de données ? Vous encapsulez le code dans un bloc « try-catch ». Que se passe-t-il si l'utilisateur n'existe pas dans la base de données ? Vous ajoutez plus de logique pour le gérer. L'e-mail de vérification a-t-il été envoyé avec succès ?ly ? Vous introduisez la journalisation pour cela. Au fil du temps, un processus simple peut devenir complexe et difficile à maintenir à mesure que de nouvelles exigences apparaissent.</p><p>La programmation orientée chemin de fer offre un moyen fonctionnel de gérer les erreurs. L'idée est de construire votre programme sur une série de « rails ». Chaque rail comporte deux parties : la partie fonctionnelle, qui traite les données, et la partie de gestion des erreurs. Vous pouvez composer votre programme en enchaînant ces rails. Le processus s'exécute comme prévu et si une erreur se produit, elle est immédiatement envoyée à la fin de la chaîne. Cette approche vous permet de composer un programme à partir de rails indépendants qui peuvent être testés individuellement.</p><p>La programmation basée sur le flux ferroviaire combine les deux concepts (FBP et ROP) en un seul système cohérent. Définissons cela étape par étape.</p><p>Considérez un ensemble simple d'opérations comme <code>AddOne</code>, <code>MultByTwo</code> et <code>MinusThree</code>. Ces opérations sont connectées par des rails. À une extrémité, vous avez un producteur, un processus responsable de la génération des données. Vous concaténez ces opérations sur les rails, ajoutez un système d'erreurs pour la gestion des erreurs et, à l'autre extrémité, un consommateur qui traite la sortie finale. Un superviseur gère l'ensemble du système, instancie et orchestrait tous les composants.</p><p>Comment cela fonctionne-t-il ? Comme dans FBP, un client envoie un paquet d'informations au producteur. Ce paquet circule dans les rails, est traité et transformé par chaque opération, et finalement renvoyé au client par le consommateur.</p><p>Ce qui est intéressant, c'est que plusieurs clients peuvent envoyer des requêtes simultanément. Chaque client envoie un ou plusieurs paquets d'informations dans le réseau, et le système traite et renvoie les résultats.</p><p>Dans un cas d'utilisation plus avancé, imaginez que l'opération « MultByTwo » nécessite beaucoup de ressources. Si plusieurs clients envoient trop de paquets d'informations, nous rencontrons une <strong>contre-pression</strong>. Cela se produit lorsque l'opération « MultByTwo » est submergée par trop de données à traiter, ce qui provoque le blocage du flux d'informations. Pour gérer cela, nous pouvons faire évoluer l'opération en augmentant le nombre d'instances « MultByTwo », ce qui évite les goulots d'étranglement et assure un traitement plus fluide. Le système de gestion des erreurs peut également être rendu évolutif de manière similaire.</p><h3>Avantages de la programmation basée sur le flux ferroviaire :</h3><ul><li>La structure des données dans le paquet d'informations est explicite et bien définie.</li><li>Il est facile de suivre où se trouve le paquet d'informations dans le pipeline de traitement.</li><li>Le système est intrinsèquement parallélisé et simple à configurer.</li><li>Le programme est facile à entretenir et à réutiliser, car chaque rail du système est traité comme un composant indépendant et réutilisable.</li></ul><h2>Utiliser Y-Combinator</h2><p>Y-Combinator offre un moyen d'introduire la récursivité dans un langage qui ne la prend pas en charge nativement. Alors pourquoi envisager cela alors que nous avons déjà la récursivité en PHP ? La clé réside dans la nature fonctionnelle et itérative de la récursivité, comme le démontre un exemple classique : la fonction factorielle.</p><p>Dans un pipeline simple codé en PHP, la récursivité est absente. Dans un flux simple, l'exécution se déplace de haut en bas sans possibilité de reculer par récursivité. C'est l'élément manquant qui nous permet d'écrire des programmes plus complexes.</p><h3>Qu'est-ce que le calcul lambda ?</h3><p>Avant de discuter du combinateur Y, nous devons introduire le calcul lambda, qui constitue la base de la récursivité dans la programmation fonctionnelle. Développé par Alonzo Church à l'Université de Princeton, le calcul lambda fournit un cadre théorique pour comprendre les fonctions et leurs calculs.</p><p>Il est intéressant de noter que Church était le mentor d'Alan Turing, qui a inventé la machine de Turing, un autre modèle fondamental de calcul. La machine de Turing et le calcul lambda sont tous deux des modèles équivalents, comme le décrit la thèse de Church-Turing.</p><p>Dans le calcul lambda, une fonction est traitée comme une boîte noire : elle prend des entrées et produit des sorties. Par exemple, si nous entrons « X », la boîte noire produit « X + 1 ». Ce comportement est représenté par la notation lambda : « λ x . x + 1<code>, ce qui signifie que pour une entrée </code>X<code>, la fonction renvoie </code>X + 1`.</p><p>Le calcul lambda introduit également le concept de fonctions pures, c'est-à-dire des fonctions qui renvoient toujours la même sortie pour les mêmes entrées sans aucun état interne.</p><h3>Application du calcul lambda à la récursivité</h3><p>En programmation fonctionnelle, la récursivité peut être introduite même dans les langages qui ne la prennent pas en charge nativement. Le Y-Combinator y parvient en appliquant une fonction à lui-même. Ce concept d'auto-application permet un comportement récursif même lorsque les mécanismes de récursivité traditionnels sont absents.</p><p>Par exemple, une fonction factorielle récursive en calcul lambda ressemblerait à ceci :</p><ul><li><code>fac(3) = 3 * fac(2) = 3 * 2 * fac(1) = 3 * 2 * 1 = 6</code></li></ul><p>Mais comment définissons-nous la récursivité en calcul lambda ? Le Y-Combinator nous permet d'exprimer la récursivité dans n'importe quel langage fonctionnel, même lorsque le langage ne fournit pas de moyen direct d'effectuer des appels récursifs.</p><h3>Y-Combinator en PHP</h3><p>En PHP, nous pouvons implémenter le Y-Combinator en utilisant le code suivant :</p><pre><code class="language-php">$Y = fn(Closure $f) =&gt; $U(fn(Closure $x) =&gt; $f(fn(Closure $y) =&gt; $U($x)($y)));
</code></pre><p>Ce n'est qu'une des nombreuses implémentations possibles en PHP. Une autre implémentation élégante peut être trouvée dans le référentiel loophp, qui couvre également d'autres concepts de calcul lambda. Pour plus de détails, je vous recommande de consulter le référentiel : <a href="https://github.com/loophp/combinator">loophp/combinator</a>.</p><p>De plus, le référentiel d'Igor W. fournit une implémentation de calcul lambda en PHP, vous permettant d'écrire directement des fonctions comme <code>$true</code>, <code>$false</code>, <code>$not</code> et même <code>$fact</code> (factorial).</p><h2>Async par défaut</h2><p>Flow est conçu pour gérer efficacement les opérations asynchrones, garantissant que les tâches peuvent être exécutées simultanément sans bloquer d'autres processus. La programmation asynchrone est une fonctionnalité clé des applications modernes, permettant au système d'effectuer plusieurs opérations simultanément, telles que la gestion des tâches liées aux E/S, des appels réseau ou de toute tâche non bloquante.</p><p>Flow propose une manière structurée de gérer ces opérations asynchrones via un ensemble de pilotes. Chaque pilote fournit des fonctionnalités spécifiques, permettant aux développeurs d'implémenter la concurrence à l'aide de diverses approches telles que les coroutines, les fibres ou les boucles d'événements.</p><h3>Pilotes actuellement implémentés</h3><p>Flow prend actuellement en charge les pilotes suivants :</p><ul><li><p>Amp Driver : un framework de concurrence pour PHP qui permet l'utilisation d'opérations asynchrones.</p></li><li><p>Fiber Driver : PHP 8.1 a introduit les fibres, qui offrent un support natif des coroutines.</p></li><li><p>ReactPHP Driver : une bibliothèque qui apporte des E/S non bloquantes pilotées par événements à PHP.</p></li><li><p>Spatie Driver : une bibliothèque de tâches asynchrones simple pour PHP, facilitant le travail avec la concurrence.</p></li><li><p>Swoole Driver : un framework de programmation asynchrone et de coroutine hautes performances pour PHP, idéal pour créer des applications Web à grande échelle et en temps réel.</p></li></ul><h3>Méthodes asynchrones de base dans Flow</h3><p>Le modèle asynchrone de Flow s'articule autour de plusieurs méthodes clés qui sont implémentées dans <code>DriverInterface</code>. Ces méthodes donnent aux développeurs un contrôle précis sur la façon dont les tâches asynchrones sont gérées dans leurs applications.</p><h4><code>async(Closure|JobInterface $callback): Closure</code></h4><p>La méthode <code>async()</code> est conçue pour démarrer un processus asynchrone. Elle prend une <code>Closure</code> ou une <code>JobInterface</code> comme argument et renvoie une <code>Closure</code> qui initie la tâche asynchrone lorsqu'elle est invoquée.</p><ul><li>Closure : il s'agit d'une fonction anonyme typique en PHP qui sera exécutée de manière asynchrone.</li><li>JobInterface : cela permet une définition de tâche plus structurée, où le travail encapsule la logique de traitement et de gestion de l'opération asynchrone.</li></ul><p>Le but de <code>async()</code> est de mettre en file d'attente les tâches à exécuter sans bloquer le thread principal. Cela est particulièrement utile dans les situations où plusieurs tâches liées aux E/S ou coûteuses en calcul doivent s'exécuter simultanément.</p><h5>Exemple d'utilisation :</h5><pre><code class="language-php">$driver-&gt;async(function () {
    // Some asynchronous task, such as making an HTTP request
});
</code></pre><p>Dans cet exemple, la fonction anonyme sera exécutée de manière asynchrone, ce qui permettra à d'autres tâches de continuer à s'exécuter en attendant la fin de cette opération.</p><h4><code>defer(Closure $callback): mixed</code></h4><p>La méthode <code>defer()</code> permet un contrôle plus précis des tâches asynchrones en fournissant deux rappels à la tâche : un rappel d'achèvement et un rappel asynchrone. Cela permet de différer les tâches asynchrones, garantissant qu'elles ne bloquent pas d'autres processus en attendant l'étape suivante du flux.</p><ul><li>Le rappel d'achèvement est utilisé pour stocker le résultat de la tâche une fois qu'elle est terminée.</li><li>Le rappel asynchrone est utilisé pour déclencher l'étape suivante de la chaîne asynchrone.</li></ul><p>Cette méthode est particulièrement utile lorsque vous devez enchaîner des tâches asynchrones ou contrôler l'ordre dans lequel les tâches sont exécutées.</p><h5>Exemple d'utilisation :</h5><pre><code class="language-php">$driver-&gt;defer(function ($complete, $nextAsync) {
    // Some asynchronous task
    $complete($result); // Store the result
    $nextAsync($result); // Move to the next async task
});
</code></pre><p>Ici, la méthode <code>defer()</code> garantit que la tâche est correctement exécutée et, une fois terminée, elle passe à la tâche suivante tout en stockant le résultat pour une utilisation ultérieure.</p><h4><code>await(array &amp;$stream): void</code></h4><p>La méthode <code>await()</code> est utilisée pour attendre que toutes les opérations asynchrones d'un flux soient terminées avant de revenir à l'exécution synchrone. Cette méthode est essentielle pour garantir que toutes les tâches sont terminées avant de procéder à d'autres opérations synchrones.</p><p>Elle prend un tableau d'opérations, contenant généralement les fonctions de flux et les répartiteurs, et garantit que chaque tâche asynchrone de ce flux est terminée.</p><p>Cette méthode est utile dans les scénarios où vous souhaitez vous assurer que tous les processus asynchrones se terminent avant de passer à la partie suivante de la logique de votre application. Par exemple, si vous gérez plusieurs requêtes HTTP simultanément, vous pouvez utiliser <code>await()</code> pour vous assurer que toutes les requêtes sont terminées avant de traiter les résultats.</p><h5>Exemple d'utilisation :</h5><pre><code class="language-php">$stream = [
    'fnFlows' =&gt; [/* asynchronous flows */],
    'dispatchers' =&gt; [/* event dispatchers */]
];

$driver-&gt;await($stream);
</code></pre><p>Dans ce cas, la méthode <code>await()</code> garantit que toutes les opérations asynchrones au sein du flux ont été terminées avant de passer à l'étape synchrone suivante.</p><h3>Résumé du modèle asynchrone de Flow</h3><p>Les méthodes asynchrones de Flow offrent aux développeurs des options flexibles pour gérer la concurrence au sein des applications PHP. Avec des méthodes comme <code>async()</code>, <code>defer()</code> et <code>await()</code>, Flow permet un contrôle précis sur la manière et le moment d'exécution des tâches asynchrones, garantissant que les applications peuvent gérer efficacement les opérations à grande échelle et en temps réel. De plus, la disponibilité de plusieurs pilotes permet une personnalisation en fonction des besoins de l'application, offrant une large gamme d'outils pour mettre en œuvre efficacement la programmation asynchrone.</p><h2>Choisissez votre stratégie IP</h2><p>Flow s'intègre au composant Symfony EventDispatcher, tirant parti de sa puissante architecture basée sur les événements pour gérer les paquets d'informations (IP) tout au long du flux. En utilisant les modèles de conception Mediator et Observer, Flow permet une orchestration dynamique pilotée par les événements, garantissant que chaque IP peut être traitée de manière flexible sans interférer avec d'autres composants du système. Cette architecture basée sur les événements reflète la façon dont Symfony gère les événements, offrant la même extensibilité et le même contrôle sur l'exécution du flux.</p><p>Voici comment les différentes stratégies IP sont implémentées dans Flow à l'aide de l'EventDispatcher :</p><ul><li>PUSH : Flow déclenche un événement « PUSH » au tout début, vous permettant de pousser une IP dans le flux avant le démarrage de tout processus asynchrone. Ceci est utile pour initialiser et mettre en file d'attente les IP pour un traitement ultérieur.</li></ul><p>Exemple d'événement : « Flow\Event\PushEvent »</p><ul><li>ASYNC : L'événement « ASYNC » est envoyé lorsque Flow commence le traitement asynchrone d'une IP. Cela vous permet de gérer l'IP de manière asynchrone, offrant une flexibilité dans la façon dont les différentes étapes du flux sont exécutées simultanément.</li></ul><p>Exemple d'événement : <code>Flow\Event\AsyncEvent</code></p><ul><li>PULL : l'événement <code>PULL</code> est envoyé lorsque Flow doit extraire l'IP suivante pour un traitement asynchrone. Cela vous permet de définir la logique de sélection de l'IP qui sera traitée ensuite parmi les IP poussées.</li></ul><p>Exemple d'événement : <code>Flow\Event\PullEvent</code></p><ul><li>POP : lorsqu'une IP a terminé le traitement asynchrone, Flow déclenche un événement <code>POP</code>. Cet événement permet de s'assurer que l'IP a franchi toutes les étapes nécessaires et qu'elle est prête à passer au processus suivant dans le flux.</li></ul><p>Exemple d'événement : <code>Flow\Event\PopEvent</code></p><ul><li>POOL : l'événement <code>POOL</code> est utilisé lorsque Flow doit rassembler un pool d'IP pour le traitement. Cet événement permet de sélectionner dynamiquement des IP dans un pool pour un traitement simultané, permettant une orchestration efficace.</li></ul><p>Exemple d'événement : <code>Flow\Event\PoolEvent</code></p><p>En s'intégrant à l'EventDispatcher de Symfony, Flow offre une manière flexible et extensible de gérer les IP, garantissant que chaque étape du flux peut être personnalisée et étendue sans modifier la logique de base. Cela est similaire à la façon dont le système d'événements de Symfony permet de modifier des objets comme <code>Response</code> dans le composant HttpKernel, où divers écouteurs peuvent modifier la réponse avant qu'elle ne soit renvoyée.</p><p>Cette approche offre des avantages significatifs, notamment :</p><ul><li>Extensibilité : de nouvelles fonctionnalités peuvent être introduites sans modifier la logique de flux de base, simplement en ajoutant de nouveaux écouteurs d'événements.</li><li>Parallélisme : Flow prend naturellement en charge le traitement asynchrone et le système d'événements assure une gestion efficace de plusieurs IP simultanément.</li><li>Séparation des préoccupations : chaque événement (PUSH, ASYNC, PULL, POP, POOL) gère des étapes spécifiques du traitement des IP, ce qui rend le système plus modulaire et plus facile à entretenir.</li></ul><h2>Exemple</h2><p>L'exemple suivant montre à quel point Flow est puissant lorsqu'il s'agit de gérer la récursivité asynchrone. Dans ce code, Flow orchestre le calcul des nombres de Fibonacci à l'aide d'un processus asynchrone et non bloquant. Cela montre comment Flow gère efficacement la récursivité et l'exécution asynchrone, permettant à plusieurs tâches d'être exécutées simultanément sans verrouiller le système.</p><h3>Composants clés de l'exemple</h3><ol><li>Sélection du pilote :
Le code sélectionne dynamiquement un pilote asynchrone (soit « AmpDriver », « ReactDriver », « FiberDriver » ou « SwooleDriver ») à l'aide de l'instruction « match », ajoutant de la flexibilité à la gestion des processus asynchrones. Chaque pilote apporte ses propres avantages uniques en fonction de l'environnement d'application.</li></ol><pre><code class="language-php">$driver = match (random_int(1, 4)) {
   1 =&gt; new AmpDriver(),
   2 =&gt; new ReactDriver(),
   3 =&gt; new FiberDriver(),
   4 =&gt; new SwooleDriver(),
};
</code></pre><ol start="2"><li>Calcul de Fibonacci :
Le calcul de Fibonacci (<code>fibonacciYJobDefer</code>) est exécuté de manière récursive dans un cadre asynchrone. Cela signifie que, plutôt que de bloquer le programme en attendant le retour des appels récursifs, Flow permet au programme de continuer à exécuter d'autres tâches, rendant le calcul de Fibonacci efficace et non bloquant.</li></ol><ul><li>Avant le calcul de Fibonacci :
Une tâche (<code>fibonacciYJobDeferBefore</code>) est définie pour initialiser et enregistrer le début du calcul de Fibonacci.</li></ul><pre><code class="language-php">$fibonacciYJobDeferBefore = static function (YFlowData $data) {
    printf(&quot;....* #%d - Job 5 : Calcul de fibonacciYJobDefer(%d)\n&quot;, $data-&gt;id, $data-&gt;number);
    return new YFlowData($data-&gt;id, $data-&gt;number, $data-&gt;number);
};
</code></pre><ul><li>Calcul asynchrone de Fibonacci :
Le calcul récursif de Fibonacci se produit à l'intérieur de <code>fibonacciYJobDefer</code>. Ce travail utilise une gestion différée asynchrone, permettant au programme de traiter chaque étape en parallèle sans attendre que la séquence de Fibonacci entière soit calculée.</li></ul><pre><code class="language-php">$fibonacciYJobDefer = new YJob(static function ($fibonacci) use ($driver) {
	return static function ($args) use ($fibonacci, $driver) {
		[$data, $defer] = $args;

		return $defer(static function ($complete, $async) use ($data, $defer, $fibonacci, $driver) {
			if ($data-&gt;result &lt;= 1) {
				$delay = random_int(1, 3);
				printf(&quot;....* #%d - Job 5 : Step fibonacciYJobDefer(%d) with delay %d\n&quot;, $data-&gt;id, $data-&gt;number, $delay);
				$driver-&gt;delay($delay);
				$complete([new YFlowData($data-&gt;id, $data-&gt;number, 1), $defer]);
			} else {
				$async($fibonacci([new YFlowData($data-&gt;id, $data-&gt;number, $data-&gt;result - 1), $defer]), static function ($result1) use ($data, $complete, $driver, $async, $fibonacci) {
					[$resultData1, $defer1] = $result1;
					$async($fibonacci([new YFlowData($data-&gt;id, $data-&gt;number, $data-&gt;result - 2), $defer1]), static function ($result2) use ($data, $complete, $driver, $resultData1) {
						[$resultData2, $defer2] = $result2;
						$delay = random_int(1, 3);
						printf(&quot;....* #%d - Job 5 : Step async fibonacciYJobDefer(%d) with delay %d\n&quot;, $data-&gt;id, $data-&gt;number, $delay);
						$driver-&gt;delay($delay);
						$fibResult = $resultData1-&gt;result + $resultData2-&gt;result;
						$complete([new YFlowData($data-&gt;id, $data-&gt;number, $fibResult), $defer2]);
					});
				});
			}
		});
	};
});
</code></pre><p>Cette étape démontre la puissance de Flow dans la gestion de la récursivité avec le traitement asynchrone. Les rappels <code>async</code> permettent à plusieurs appels récursifs (pour <code>F(n-1)</code> et <code>F(n-2)</code>) de se produire en parallèle, et les résultats sont combinés une fois les deux terminés. Cette approche non bloquante empêche le blocage du système et permet à d'autres processus de s'exécuter simultanément.</p><ul><li>Après le calcul de Fibonacci :
Une fois le calcul de Fibonacci terminé, le résultat est enregistré à l'aide de la tâche <code>fibonacciYJobDeferAfter</code>.</li></ul><pre><code class="language-php"> $fibonacciYJobDeferAfter = static function ($args) {
	 [$data, $defer] = $args;
	 return $defer(static function ($complete) use ($data, $defer) {
		 printf(&quot;....* #%d - Job 5 : Result for fibonacciYJobDefer(%d) = %d\n&quot;, $data-&gt;id, $data-&gt;number, $data-&gt;result);
		 $complete([new YFlowData($data-&gt;id, $data-&gt;number), $defer]);
	 });
 };
</code></pre><ol start="3"><li>Orchestration de flux :
Le framework Flow orchestre l'intégralité du processus. Les étapes de calcul de Fibonacci sont définies comme une série de tâches qui sont générées et exécutées de manière asynchrone. Chaque tâche, y compris la préparation, la récursivité et la journalisation du résultat final, est traitée en séquence, mais sans bloquer le thread principal.</li></ol><pre><code class="language-php">$flow = Flow::do(static function () use (
   $fibonacciYJobDeferBefore,
   $fibonacciYJobDefer,
   $fibonacciYJobDeferAfter
) {
   yield [$fibonacciYJobDeferBefore];
   yield [$fibonacciYJobDefer, null, null, null, new DeferAsyncHandler()];
   yield [$fibonacciYJobDeferAfter, null, null, null, new DeferAsyncHandler()];
}, ['driver' =&gt; $driver]);
</code></pre><ol start="4"><li>Traitement IP :
Enfin, le code crée et traite des paquets d'informations (<code>Ip</code>) pour chaque calcul, en les transmettant via le pipeline Flow. Le flux est ensuite attendu pour garantir que toutes les opérations asynchrones se terminent avant la fin du programme.</li></ol><pre><code class="language-php">for ($i = 1; $i &lt;= 5; $i++) {
   $ip = new Ip(new YFlowData($i, $i));
   $flow($ip);
}
$flow-&gt;await();
</code></pre><h3>Qu'obtenons-nous ?</h3><ul><li><p>Récursivité asynchrone : la récursivité peut souvent être lourde en termes de performances et bloquer d'autres processus dans les systèmes traditionnels. Flow permet à la récursivité de se produire de manière asynchrone, ce qui signifie que d'autres tâches peuvent s'exécuter simultanément pendant que les appels récursifs s'exécutent, améliorant ainsi l'efficacité et la réactivité.</p></li><li><p>Flexibilité du pilote : la sélection dynamique du pilote permet à Flow de s'adapter à différents environnements, ce qui le rend très polyvalent. En fonction des besoins du système ou de l'application, Flow peut utiliser différents pilotes pour obtenir un comportement asynchrone.</p></li><li><p>Exécution non bloquante : en utilisant des rappels asynchrones et une gestion différée, cet exemple démontre la capacité de Flow à gérer plusieurs tâches simultanément, améliorant ainsi l'évolutivité et le rendant idéal pour les applications en temps réel.</p></li><li><p>Modulaire et extensible : chaque tâche (avant, pendant et après le calcul de Fibonacci) est modulaire, ce qui facilite l'extension ou la modification du flux de travail sans affecter le reste du système.</p></li></ul><h3>Installer Flow</h3><p>Vous pouvez vous rendre sur l'url suivante pour plus de détails</p><p><a href="https://flow.darkwood.com">https://flow.darkwood.com</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/introduction-a-flow</link><guid>https://blog.darkwood.com/article/introduction-a-flow</guid><enclosure url="http://darkwood.com/media/articles/66edcbd980e14990353674.png" /></item><item><title>Wave function collapse</title><pubDate>Tue, 29 Oct 2024 01:17:03 +0000</pubDate><description><![CDATA[
Introduction : Qu&#039;est-ce que le Wave Function Collapse ?
Le Wave Function Collapse (WFC) est un puissant algorithme de génération procédurale qui suscite un vif intérêt dans le développement de jeux et la création de contenu. Bien qu’il s’inspire de concep...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/672004e40d91e141964156.jpeg" /></p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/83b6b91a612641739a78ccd41a9f1cbe" title="Wave function collapse" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;" data-ratio="1.78343949044586"></iframe></div><h2>Introduction : Qu'est-ce que le Wave Function Collapse ?</h2><p>Le Wave Function Collapse (WFC) est un puissant algorithme de génération procédurale qui suscite un vif intérêt dans le développement de jeux et la création de contenu. Bien qu’il s’inspire de concepts en mécanique quantique, le WFC est accessible et offre des applications uniques pour générer des motifs, des cartes et des mises en page suivant des règles spécifiques.</p><p>En physique, une fonction d’onde représente tous les états possibles dans lesquels une particule pourrait exister simultanément, et « s’effondre » en un seul état lors de l’observation. De manière similaire, l’algorithme WFC commence avec de nombreux états potentiels pour chaque tuile ou cellule et réduit progressivement chaque option en appliquant des contraintes, jusqu'à ce qu’une seule solution valide émerge.</p><p>Ce guide vous expliquera comment fonctionne le WFC, ses applications et comment l'utiliser avec PHP – un langage pas forcément associé à la génération procédurale, mais tout à fait capable de la gérer.</p><h2>Comment fonctionne l'algorithme de Wave Function Collapse ?</h2><p>L’algorithme WFC est un solveur basé sur des contraintes qui s’assure que les cellules voisines suivent des règles spécifiques. Ces règles peuvent représenter des exigences d’adjacence de tuiles dans un jeu, voire des contraintes de mise en page pour éviter le chevauchement d'éléments visuels.</p><h3>Concepts de Base</h3><ul><li>Entropie : Dans le WFC, l’entropie désigne le nombre d'états valides restants pour une cellule. Une cellule avec une faible entropie a peu d’états possibles, tandis qu'une cellule avec une forte entropie en a plusieurs.</li><li>Propagation : Au fur et à mesure que les cellules s’effondrent, elles influencent leurs voisines en limitant les états que celles-ci peuvent avoir, réduisant ainsi leur entropie.</li><li>Effondrement : L’algorithme choisit toujours une cellule avec la plus faible entropie, l’effondre en un seul état, puis propage ce changement aux cellules voisines. Ce processus continue jusqu'à ce que toutes les cellules soient effondrées ou qu’une contradiction soit détectée.</li></ul><h3>Le WFC en Action</h3><p>Voici une vue d’ensemble étape par étape du fonctionnement de l'algorithme WFC :</p><ol><li>Initialisation : Chaque cellule commence avec tous les états possibles (par exemple, dans une carte en tuiles, une cellule pourrait représenter des options comme mur, sol, eau, etc.).</li><li>Sélection de la plus faible entropie : Choisir la cellule avec le moins d’états possibles (la plus faible entropie).</li><li>Effondrement de la cellule : Sélectionner au hasard l’un des états valides restants.</li><li>Propagation des contraintes : Mettre à jour les cellules voisines pour éliminer les états qui ne sont plus valides en fonction de la cellule effondrée.</li><li>Répéter ou gérer les contradictions : Si toutes les cellules s’effondrent avec succès, vous avez une solution. Sinon, il faudra gérer les contradictions.</li></ol><h3>Visualiser le WFC</h3><p>Imaginez que vous résolvez un puzzle où chaque tuile doit s’ajuster parfaitement à ses voisines. Au départ, chaque cellule a plusieurs options de tuiles, mais à mesure que vous placez des tuiles, vous réduisez les choix des cellules environnantes jusqu'à ce que seules des configurations valides restent.</p><h2>Implémenter le WFC en PHP : Guide Étape par Étape</h2><p>Bien que PHP ne soit peut-être pas votre premier choix pour la génération procédurale, il fonctionne bien pour les projets web et la génération dynamique de mises en page. Voici comment implémenter le WFC en PHP.</p><h3>Définir les Tuiles et Contraintes</h3><p>Tout d'abord, nous définissons une classe <code>Tile</code> en PHP, où chaque tuile a des contraintes qui spécifient avec quelles autres tuiles elle peut être adjacente. Par exemple, une tuile « eau » peut être autorisée uniquement à côté de « eau » ou de « sable ».</p><pre><code class="language-php">class Tile {
    public $name;
    public $constraints;

    public function __construct($name, $constraints) {
        $this-&gt;name = $name;
        $this-&gt;constraints = $constraints;
    }
}
</code></pre><h3>Initialiser la Grille</h3><p>Ensuite, nous créons une grille où chaque cellule commence avec tous les états de tuile possibles :</p><pre><code class="language-php">$grid = array_fill(0, $width, array_fill(0, $height, ['eau', 'sable', 'forêt', 'montagne']));
</code></pre><h3>Propager les Contraintes</h3><p>Pour refléter l’état de chaque cellule, nous définissons une fonction qui met à jour les cellules voisines en fonction des contraintes d’une cellule effondrée.</p><pre><code class="language-php">function propagateConstraints(&amp;$grid, $x, $y, $tile) {
    $directions = [
        'gauche' =&gt; [-1, 0],
        'droite' =&gt; [1, 0],
        'haut' =&gt; [0, -1],
        'bas' =&gt; [0, 1]
    ];
    foreach ($directions as $direction =&gt; $offset) {
        $dx = $x + $offset[0];
        $dy = $y + $offset[1];
        if (isset($grid[$dx][$dy])) {
            $grid[$dx][$dy] = array_intersect($grid[$dx][$dy], $tile-&gt;constraints[$direction]);
        }
    }
}
</code></pre><h3>Effondrer la Cellule avec la Plus Faible Entropie</h3><p>Nous sélectionnons la cellule avec la plus faible entropie, l’effondrons, puis propageons les contraintes aux cellules voisines.</p><pre><code class="language-php">function getLowestEntropyCell($grid) {
    $minEntropy = PHP_INT_MAX;
    $bestCell = null;

    foreach ($grid as $x =&gt; $row) {
        foreach ($row as $y =&gt; $cell) {
            if (count($cell) &lt; $minEntropy &amp;&amp; count($cell) &gt; 1) {
                $minEntropy = count($cell);
                $bestCell = [$x, $y];
            }
        }
    }

    return $bestCell;
}

function collapseCell(&amp;$grid, $x, $y) {
    $possibilities = $grid[$x][$y];
    if (empty($possibilities)) {
        throw new Exception(&quot;Contradiction détectée en [$x, $y]&quot;);
    }
    $choice = $possibilities[array_rand($possibilities)];
    $grid[$x][$y] = [$choice];
    propagateConstraints($grid, $x, $y, new Tile($choice, []));
}
</code></pre><h3>Exécuter l'Algorithme</h3><p>Pour terminer, nous exécutons l’algorithme jusqu’à ce que toutes les cellules soient effondrées.</p><pre><code class="language-php">while ($cell = getLowestEntropyCell($grid)) {
    list($x, $y) = $cell;
    collapseCell($grid, $x, $y);
}

// Afficher la grille
foreach ($grid as $row) {
    foreach ($row as $cell) {
        echo $cell[0] . ' ';
    }
    echo PHP_EOL;
}
</code></pre><p>Si une contradiction se produit, là où une cellule n’a pas d'options valides, vous pouvez essayer de revenir en arrière ou de redémarrer de manière aléatoire.</p><h2>Gérer les Contradictions</h2><p>Les contradictions surviennent lorsque les contraintes d’une cellule lui laissent aucun état valide. Pour y remédier, vous pouvez :</p><ul><li>Revenir à un état précédent et essayer une autre option.</li><li>Redémarrer le processus avec des conditions initiales différentes.</li><li>Ajuster les calculs d’entropie pour éviter les contradictions plus tôt.</li></ul><h2>Exploration d’Autres Algorithmes de Génération de Cartes</h2><p>Au-delà du WFC, il existe de nombreux autres algorithmes de génération procédurale, chacun étant adapté à des tâches spécifiques comme la génération de terrain, les formes organiques ou les structures complexes. Voici un aperçu de quelques alternatives :</p><ul><li>Perlin &amp; Simplex Noise : Idéal pour générer des terrains lisses et naturels comme des montagnes et des vallées.</li><li>Automates Cellulaires : Parfait pour créer des structures de grottes organiques.</li><li>Diagrammes de Voronoi : Utile pour diviser un espace en régions basées sur la proximité de points, parfait pour la génération de biomes.</li><li>L-Systems : Souvent utilisés pour créer des structures de branchement naturelles comme des arbres.</li><li>Génération de Donjons : Des algorithmes comme la partition binaire (BSP) et la marche aléatoire créent des pièces et des couloirs pour des structures de type donjon.</li></ul><p>Chacun de ces algorithmes a des forces uniques, donc le choix dépend des besoins et des contraintes du projet.</p><h2>Applications du Wave Function Collapse</h2><p>Le WFC a une gamme d’applications :</p><ul><li>Développement de jeux : Générer des cartes de tuiles cohérentes, des niveaux ou des cartes.</li><li>Génération d'images : Créer des motifs et textures qui suivent des règles d'adjacence spécifiées.</li><li>Plans de villes : Générer des mises en page où certaines structures doivent coexister.</li><li>Création de puzzles : Concevoir des puzzles comme le Sudoku ou des mots croisés qui reposent sur des règles d'adjacence.</li></ul><h2>Le Défi Technique avec Symfony UX</h2><p>Intégrer l’algorithme WFC dans une application Symfony implique des défis uniques. Comme Symfony UX est conçu pour des expériences utilisateur réactives, il est essentiel de gérer les mises à jour continues d’une grille générée dynamiquement à mesure que WFC progresse. Ici, les composants LiveComponent et la gestion asynchrone de Symfony UX contribuent à créer une expérience fluide pour visualiser le WFC tout en garantissant des performances stables.</p><p>Un élément crucial de cette implémentation est Flow, un framework d’orchestration visuelle des données. Flow améliore considérablement la réutilisabilité et la modularité, des clés pour gérer des processus de génération procédurale complexes. Par exemple, chaque tâche du WFC, de l'effondrement des cellules à l'application des contraintes, est encapsulée comme une unité modulaire dans Flow. Cette approche simplifie le code et permet de réutiliser les fonctionnalités du WFC dans différents contextes, que ce soit pour des ensembles de données variés ou des tailles de grille différentes, avec peu de modifications.</p><h3>Demo et sources</h3><p>Voici une vidéo concrète générée par l'algorithme</p><div class="ratio ratio-16x9"><video width="640" height="360" autoplay loop controls muted><source src="/blog/images/articles/wave-function-collapse/wave_function_collapse.mp4" type="video/mp4"></video></div><p>Le code de cette implémentation Symfony est disponible ici : <a href="https://github.com/matyo91/flow-live">https://github.com/matyo91/flow-live</a></p><h2>Conclusion</h2><p>Le Wave Function Collapse est un outil fascinant pour la génération procédurale, combinant contraintes et aléatoire pour créer des sorties cohérentes et visuellement plaisantes. Bien que PHP ne soit pas forcément le premier langage auquel on pense pour le WFC, il est plus que capable de gérer l’algorithme, ouvrant des possibilités intéressantes pour la génération de contenu procédural sur le web.</p><p>Le WFC a de vastes applications, allant des jeux à la conception graphique en passant par la mise en page. Maîtriser cet algorithme ouvre la voie à la création de mondes et de motifs générés par algorithme, à la fois complexes et esthétiquement attrayants.</p><h2>Ressources</h2><p>Explorez ces ressources pour approfondir votre compréhension du WFC et des techniques de génération procédurale.</p><ul><li>Wave function collapse on Wikipedia General : https://en.wikipedia.org/wiki/Wave_function_collapse</li><li>Wave function collapse on Wikipedia Algorithm : https://en.wikipedia.org/wiki/Model_synthesis</li><li>WaveFunctionCollapse Github : https://github.com/mxgmn/WaveFunctionCollapse</li><li>Coding Challenge 171 Wave Function Collapse : https://www.youtube.com/watch?v=rI_y2GAlQFM</li><li>Wave Function Collapse Explained : https://www.boristhebrave.com/2020/04/13/wave-function-collapse-explained</li><li>The Wavefunction Collapse Algorithm explained very clearly : https://robertheaton.com/2018/12/17/wavefunction-collapse-algorithm</li><li>The fascinating Wave Function Collapse algorithm : https://dev.to/kavinbharathi/the-fascinating-wave-function-collapse-algorithm-4nc3</li><li>A new way to generate worlds (stitched WFC) : https://www.youtube.com/watch?v=dFYMOzoSDNE</li><li>EPC2018 - Oskar Stalberg - Wave Function Collapse in Bad North : https://www.youtube.com/watch?v=0bcZb-SsnrA</li><li>Introduction to procedural generation with Wave Function Collapse : https://www.youtube.com/watch?v=ZdbpTkuStKI</li><li>Wave Function Collapse Is A Thing - Godot 4.1 C# (Full Lesson) : https://www.youtube.com/watch?v=OiJmO2BRcVE</li><li>Expanding Wave Function Collapse with Growing Grids for Procedural Content Generation : https://www.youtube.com/watch?v=2TDgZfc-bu0</li><li>The Wave Function Collapse algorithm : https://www.youtube.com/watch?v=qRtrj6Pua2A</li><li>A.I. Level Generation, High Res (Wave Function Collapse #6) : https://www.youtube.com/watch?v=bVI-i39lYP8</li><li>PHP-WFC : https://github.com/FeatheredSnek/phpwfc</li><li>Procedural Generation with Wave Function Collapse and Model Synthesis | Unity Devlog : https://www.youtube.com/watch?v=zIRTOgfsjl0</li><li>Model Synthesis : https://paulmerrell.org/model-synthesis</li><li>Wave Collapse Function algorithm in Processing : https://discourse.processing.org/t/wave-collapse-function-algorithm-in-processing/12983</li><li>Présentation du Wave Function Collapse (Procédural) https://www.youtube.com/watch?v=_pRIHB8Qbek</li><li>Automatic Generation of Game Content using a Graph-based Wave Function Collapse Algorithm : https://fr.slideshare.net/slideshow/automatic-generation-of-game-content-using-a-graphbased-wave-function-collapse-algorithm-191777606/191777606</li></ul><p>Creative works</p><ul><li>Creating Little Castles with Wave Function Collapse : https://www.youtube.com/watch?v=MyMbbmWVCDw</li><li>Eternal Mist. Example of Wave Function Collapse (for #screenshotsaturday ). Indie Game Devlog #2.1 : https://www.youtube.com/watch?v=Ff0tXzaMpvU</li><li>Wave Function Collapse For Dummies Like Me (With Unity Example) : https://www.youtube.com/watch?v=57MaTTVH_XI</li><li>Procedural generation from a single example with WaveFunctionCollapse : https://www.youtube.com/watch?v=DOQTr2Xmlz0</li><li>EASY Wave Function Collapse Tutorial for Unity Games! (Unity Tutorial - Reupload) : https://www.youtube.com/watch?v=3g440SA2hKU</li><li>Why I use Wave Function Collapse to create levels for my game : https://www.youtube.com/watch?v=TO0Tx3w5abQ</li><li>How Townscaper Works: A Story Four Games in the Making | AI and Games #65 : https://www.youtube.com/watch?v=_1fvJ5sHh6A</li><li>Oisín Wave Function Collapse for poetry: https://github.com/mewo2/oisin</li><li>Townscaper : https://www.townscapergame.com/</li><li>unity-wave-function-collapse : https://selfsame.itch.io/unitywfc</li><li>Zelda WFC : https://observablehq.com/@makio135/zelda-wfc</li><li>Wave Function Collapse Demonstration : https://oskarstalberg.com/game/wave/wave.html</li><li>Infinite procedurally generated city : https://marian42.de/article/wfc/</li><li>Generating stairy scenes : https://x.com/exutumno/status/895683455299723265?lang=eu</li><li>Herbert Wolverson - Procedural Map Generation Techniques : https://www.youtube.com/watch?v=TlLIOgWYVpI</li><li>What Is Perlin Noise? Procedural Generating in Video Games : https://www.youtube.com/watch?v=9x6NvGkxXhU</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/wave-function-collapse</link><guid>https://blog.darkwood.com/article/wave-function-collapse</guid><enclosure url="http://darkwood.com/media/articles/672004e40d91e141964156.jpeg" /></item><item><title>Automatise la création de vignettes Youtube</title><pubDate>Sun, 08 Dec 2024 20:39:47 +0000</pubDate><description><![CDATA[
Vous souhaitez adapter des modèles d’intelligence artificielle (IA) à vos besoins spécifiques sans exploser votre budget ou sacrifier des heures de travail ? LoRA (Low-Rank Adaptation) est la solution idéale. Couplée avec des outils comme Flux et Replicate...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67560413b1791745997663.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/FUpvo93MK1w?si=rzTApef5BYAowrWC" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Vous souhaitez adapter des modèles d’intelligence artificielle (IA) à vos besoins spécifiques sans exploser votre budget ou sacrifier des heures de travail ? LoRA (Low-Rank Adaptation) est la solution idéale. Couplée avec des outils comme Flux et Replicate, cette méthode rend la personnalisation de l’IA plus simple, rapide et accessible que jamais.</p><p>Dans cet article, nous allons explorer ensemble ce qu’est LoRA, pourquoi vous devriez l’utiliser et comment vous pouvez l’intégrer dans des workflows automatisés pour maximiser vos projets. Que vous soyez créateur de contenu, développeur ou simplement curieux, restez avec nous : vous découvrirez comment ces outils transforment vos idées en réalité.</p><h2>LoRA : La clé d'une personnalisation simplifiée</h2><h3>Qu’est-ce que LoRA ?</h3><p>LoRA, ou Low-Rank Adaptation, est une méthode qui permet d’ajuster des modèles d’IA préentraînés en modifiant uniquement une petite partie de leurs paramètres. Contrairement à un entraînement complet qui demande des ressources importantes, LoRA offre une alternative légère, rapide et économique.</p><h3>Pourquoi est-ce révolutionnaire ?</h3><p>LoRA simplifie un processus qui, auparavant, pouvait sembler hors de portée pour de nombreux créateurs ou petites entreprises. Voici ses principaux avantages :</p><ul><li>Consommation mémoire réduite : Seules quelques couches du modèle sont ajustées.</li><li>Performance accrue : Les ajustements sont rapides, même avec un matériel modeste.</li><li>Compatibilité étendue : Fonctionne avec des modèles populaires comme GPT, Stable Diffusion et BERT.</li></ul><p>Imaginez pouvoir entraîner un modèle d’IA pour refléter votre style artistique ou répondre parfaitement aux besoins de vos utilisateurs en une fraction du temps !</p><h2>Pourquoi devriez-vous utiliser LoRA ?</h2><p>LoRA est fait pour vous si vous voulez :</p><ul><li>Créer des images uniques et stylisées : Imaginez des visuels sur mesure pour vos réseaux sociaux, publicités ou contenus créatifs.</li><li>Personnaliser des chatbots : Rendez vos assistants plus humains, pertinents et alignés sur votre marque.</li><li>Automatiser vos workflows créatifs : Simplifiez la création de vignettes YouTube, illustrations ou tout autre contenu graphique.</li></ul><h3>Un exemple concret : Personnalisation d’un modèle artistique</h3><p>Prenons un exemple : vous êtes créateur de contenu et souhaitez des images dans un style graphique bien précis. Avec LoRA, vous pouvez adapter un modèle préentraîné, comme Stable Diffusion, pour générer des images parfaitement alignées avec votre vision artistique – sans avoir besoin de réentraîner un modèle entier.</p><h2>Associez LoRA avec Flux et Replicate pour une puissance maximale</h2><p>Maintenant que vous comprenez la valeur de LoRA, voyons comment Flux et Replicate entrent en jeu pour automatiser vos workflows et simplifier vos processus.</p><h3>Replicate : La plateforme clé en main pour LoRA</h3><p>Replicate est une plateforme qui vous permet d’entraîner, exécuter et partager vos modèles d’IA. Avec une interface intuitive et des fonctionnalités puissantes, c’est l’outil parfait pour gérer LoRA. Voici comment cela fonctionne :</p><ul><li>Entraînez votre modèle avec LoRA : Téléchargez vos données spécifiques (images ou textes) et configurez l’entraînement directement sur Replicate.</li><li>Générez des résultats impressionnants : Testez votre modèle en utilisant des prompts personnalisés.</li><li>Partagez vos créations : Publiez vos modèles pour vos équipes ou vos projets.</li></ul><p>Exemple : Vous voulez générer des images dans un style de bande dessinée rétro. Chargez quelques images de référence dans Replicate, entraînez votre modèle avec LoRA, et commencez à produire des visuels époustouflants !</p><h3>Flux : Automatisez vos workflows créatifs</h3><p>Flux est un outil d’orchestration open-source qui connecte et automatise vos outils et processus. En combinant Flux avec LoRA et Replicate, vous pouvez créer des pipelines complets pour vos projets.</p><ul><li>Automatisez la génération de contenus : Configurez des étapes pour importer vos prompts, générer des résultats avec LoRA, et exporter automatiquement vos fichiers.</li><li>Personnalisez votre workflow : Ajoutez des processus comme l’application de filtres, l’ajout de texte ou le redimensionnement.</li></ul><p>Exemple concret : Création automatisée de vignettes YouTube</p><ul><li>Entraînez LoRA avec des images de style unique sur Replicate.</li><li>Générez des vignettes personnalisées en fonction des sujets de vos vidéos.</li><li>Automatisez le traitement final (ajout de texte, ajustement de la résolution, etc.) avec Flux.</li></ul><p>Le résultat ? Des vignettes prêtes à publier en un clin d’œil.</p><h2>Cas pratique : Une journée dans la vie d’un créateur avec LoRA</h2><p>Imaginez que vous êtes créateur de contenu et que vous devez produire une série de vignettes pour vos vidéos de la semaine. Avec LoRA, Flux et Replicate :</p><ul><li>Préparation : Vous chargez vos images de référence et configurez LoRA pour adapter un modèle existant.</li><li>Production : Vous générez des visuels à partir de descriptions textuelles (par exemple, &quot;un décor futuriste avec des teintes violettes&quot;).</li><li>Automatisation : Vous configurez Flux pour ajouter automatiquement du texte et exporter les fichiers dans le bon format.</li></ul><p>En quelques heures, vous avez produit des visuels de haute qualité, entièrement personnalisés et prêts à être utilisés.</p><h2>Pourquoi attendre ?</h2><p>Avec LoRA, la personnalisation de l’IA devient accessible à tous. Couplé à Flux et Replicate, vous pouvez non seulement créer des modèles adaptés à vos besoins, mais aussi automatiser leur utilisation dans des projets variés.</p><p>Ne restez pas en marge de cette révolution. Essayez LoRA dès aujourd’hui et transformez vos workflows grâce à l’intelligence artificielle.</p><p>Pour aller plus loin, découvrez <a href="https://blackforestlabs.ai">Flux</a>, une solution open-source avec des options commerciales pour les projets professionnels.</p><p>Et vous, quels projets pourriez-vous transformer avec LoRA ? Partagez vos idées en commentaires ou contactez-nous pour en savoir plus !</p>
]]></content:encoded><link>https://blog.darkwood.com/article/automatise-la-creation-de-vignettes-youtube</link><guid>https://blog.darkwood.com/article/automatise-la-creation-de-vignettes-youtube</guid><enclosure url="http://darkwood.com/media/articles/67560413b1791745997663.png" /></item><item><title>Création d’un Projet Symfony avec IA : Utilisation de DTO, Flow et RapidAPI</title><pubDate>Sun, 19 Jan 2025 14:12:30 +0000</pubDate><description><![CDATA[
  
    
    Your browser does not support the video tag.
  

Le développement d’applications modernes s’appuie de plus en plus sur l’intelligence artificielle pour optimiser les processus de création. Cet article explique comment créer une application Symf...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/678d084e77c58675560716.png" /></p><div class="ratio ratio-16x9"><video controls style="width: 100%; height: auto; border: 0; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px;"><source src="/blog/images/articles/creation-dun-projet-symfony-avec-ia-utilisation-de-dto-flow-et-rapidapi/urlscraping.mp4" type="video/mp4">
    Your browser does not support the video tag.
  </video></div><p>Le développement d’applications modernes s’appuie de plus en plus sur l’intelligence artificielle pour optimiser les processus de création. Cet article explique comment créer une application Symfony pour scraper des pages web, obtenir un résumé et des tags pertinents, en s’appuyant sur des technologies telles que <strong>Flow</strong>, <strong>OpenAI</strong>, et <strong>RapidAPI</strong>. Ce projet a été conçu à l’aide de prompts personnalisés sur Cursor, tels que : <em>&quot;Mets en place une API avec Flow et OpenAI&quot;</em>.</p><p>L'idée principale derrière ce projet est de démontrer comment mettre en place rapidement un SaaS (Software as a Service) performant. Dans cet exemple, nous avons créé un service qui permet de scraper n'importe quelle URL et d'en extraire automatiquement les informations pertinentes grâce à l'intelligence artificielle.</p><p>Cette approche présente plusieurs avantages :</p><ul><li><strong>Rapidité de mise en place</strong> : En utilisant des outils modernes comme Symfony, ApiPlatform, Flow et l'API OpenAI, nous pouvons développer rapidement un service fonctionnel</li><li><strong>Scalabilité</strong> : L'architecture choisie permet de gérer facilement une montée en charge</li><li><strong>Valeur ajoutée</strong> : L'utilisation de l'IA pour l'analyse du contenu apporte une réelle plus-value au service</li></ul><p>Le service peut être utilisé dans de nombreux contextes : veille concurrentielle, agrégation de contenu, analyse de tendances, etc.</p><h2>Initialisation du Projet Symfony</h2><p>Commencez par créer un projet Symfony :</p><pre><code class="language-bash">composer create-project symfony/skeleton my_project
cd my_project
composer require webapp
</code></pre><p>Ajoutez les dépendances de base :</p><pre><code class="language-bash">composer require doctrine annotations
composer require api
composer require maker http-client symfony/serializer
composer require openai-php/client
</code></pre><p>Vérifiez que le serveur fonctionne :</p><pre><code class="language-bash">symfony serve
</code></pre><p>Votre projet de base est prêt !</p><h2>Implémentation du Contrôleur pour le Scraping et l’Analyse</h2><p>Voici un contrôleur basé sur le code source de l’application :</p><pre><code class="language-php">&lt;?php

namespace App\Controller;

use App\Dto\UrlDto;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use OpenAI;
use Flow\Flow\Flow;
use Flow\FlowFactory;
use Flow\Ip;

class UrlController extends AbstractController
{
    public function __construct(
        private HttpClientInterface $httpClient,
        private string $openaiApiKey
    ) {}

    public function __invoke(Request $request, SerializerInterface $serializer): JsonResponse
    {
        try {
            // Decode JSON request body
            $data = json_decode($request-&gt;getContent(), true);

            // Deserialize into UrlDto
            $urlDto = $serializer-&gt;denormalize($data, UrlDto::class);

            // Integrate Flow
            $flow = (new FlowFactory())-&gt;create(function() use (&amp;$data) {
                yield function ($url) use (&amp;$data) {
                    // Fetch URL content
                    $response = $this-&gt;httpClient-&gt;request('GET', $url);
                    $content = $response-&gt;getContent();

                    // Initialize OpenAI client
                    $client = OpenAI::client($this-&gt;openaiApiKey);

                    // Get summary and tags from ChatGPT
                    $result = $client-&gt;chat()-&gt;create([
                        'model' =&gt; 'gpt-4o-mini',
                        'messages' =&gt; [
                            ['role' =&gt; 'system', 'content' =&gt; 'First provide a concise summary of the webpage content. Then on a new line after &quot;TAGS:&quot;, list up to 10 relevant single-word or short-phrase tags, separated by commas.'],
                            ['role' =&gt; 'user', 'content' =&gt; $content],
                        ],
                        'max_tokens' =&gt; 400
                    ]);

                    // Split the response into summary and tags
                    $data = $result-&gt;choices[0]-&gt;message-&gt;content;
                };
            });

            $ip = new Ip($urlDto-&gt;url);
            $flow($ip);
            $flow-&gt;await();

            $parts = explode('TAGS:', $data);
            $summary = trim($parts[0]);
            $tags = isset($parts[1]) ? array_map('trim', explode(',', trim($parts[1]))) : [];

            return new JsonResponse([
                'url' =&gt; $urlDto-&gt;url,
                'summary' =&gt; $summary,
                'tags' =&gt; $tags,
            ]);

        } catch (\Exception $e) {
            return new JsonResponse([
                'error' =&gt; $e-&gt;getMessage()
            ], 500);
        }
    }
}
</code></pre><h2>Intégration de Flow pour Orchestrer les Données</h2><p><strong>Flow</strong> est utilisé pour orchestrer les étapes du pipeline de scraping et d’analyse. Dans le code ci-dessus :</p><ul><li><strong>Récupération du contenu</strong> : Le contenu de l’URL est récupéré via <code>HttpClientInterface</code>.</li><li><strong>Analyse via OpenAI</strong> : Le contenu est envoyé à OpenAI pour générer un résumé et des tags.</li><li><strong>Traitement des résultats</strong> : Les réponses sont traitées et renvoyées sous forme de JSON.</li></ul><h2>Mise en Place du SaaS avec RapidAPI</h2><p>Pour transformer ce projet en SaaS accessible via RapidAPI :</p><ul><li><p><strong>Créez un Compte RapidAPI</strong> :
Inscrivez-vous sur <a href="https://rapidapi.com/">RapidAPI</a>.</p></li><li><p><strong>Publiez vos Endpoints</strong> :</p><ul><li>Créez des endpoints RESTful comme présenté ci-dessus.</li><li>Configurez les routes et les paramètres requis sur RapidAPI.</li></ul></li><li><p><strong>Testez et Partagez</strong> :
Testez votre API directement sur la plateforme et partagez-la avec vos utilisateurs.</p></li></ul><h2>Conlusion</h2><p>Ce projet montre comment utiliser Symfony, ApiPlatform, Flow et OpenAI pour créer une API performante capable de scraper des pages web et d’analyser leur contenu. En publiant cette API sur RapidAPI, vous pouvez transformer cette solution en un SaaS accessible à tous.</p><p>Essayez d’intégrer ces concepts dans vos propres projets et adaptez-les en fonction des besoins de vos utilisateurs. Pour des détails supplémentaires, référez-vous à la source sur <a href="https://github.com/matyo91/UrlScrapingApi">UrlScrapingApi</a>.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/creation-dun-projet-symfony-avec-ia-utilisation-de-dto-flow-et-rapidapi</link><guid>https://blog.darkwood.com/article/creation-dun-projet-symfony-avec-ia-utilisation-de-dto-flow-et-rapidapi</guid><enclosure url="http://darkwood.com/media/articles/678d084e77c58675560716.png" /></item><item><title>Attention is all you need</title><pubDate>Mon, 24 Feb 2025 06:38:05 +0000</pubDate><description><![CDATA[
Now I get you attention, let&#039;s dive into the subject.
Building AI Orgs and AI Agents in 2025
Last week took place the AI Engineer Summit is the #1 technical conference in the world for AI engineers and leadership (CTOs &amp;amp; VPs of AI) to meet, learn, and...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67bc13cd1512c260748735.jpeg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/ZVqod6SBa4M?si=UcITpkMnOUVwZhp7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Now I get you attention, let's dive into the subject.</p><h2>Building AI Orgs and AI Agents in 2025</h2><p>Last week took place the AI Engineer Summit is the #1 technical conference in the world for AI engineers and leadership (CTOs &amp; VPs of AI) to meet, learn, and advance the field. For the third year running, it brings together the best minds in AI to discuss the future of AI engineering.</p><p>Speakers and sponsors of past events have included founders and senior leaders from DeepMind, OpenAI, Anthropic, Meta, Cohere, Mistral, Midjourney, Cartesia, NVIDIA, Groq, Crusoe, Together.ai, Fireworks, LangChain, LlamaIndex, Databricks, Neo4j, MongoDB, GitHub, Microsoft, Google, AWS, and more.</p><h2>The Theme: Agents at Work</h2><p>This year’s focus is AI Agents in Production, with a particular emphasis on real-world applications in finance, technology, and beyond—featuring insights from Jane Street, BlackRock, Bloomberg, and other industry leaders. Unlike other AI conferences, the main stage at AI Engineer Summit avoids vendor pitches, keeping discussions technical, relevant, and forward-thinking.</p><p>The event is an exclusive gathering of the top AI Agent builders to discuss the challenges and breakthroughs shaping AI in 2025. With invite-only applications, the Summit fosters a highly curated, in-depth experience for attendees.</p><p>🔗 Find more details about the event here: <a href="https://www.ai.engineer/summit/2025">AI Engineer Summit 2025</a></p><h2>Frontier Feud: The AI Trivia Showdown</h2><p>One of the segments at the Summit was Frontier Feud, an interactive trivia-style game where teams from leading AI frontier labs competed to determine the most influential research paper in AI history.</p><p>Hosted by Barr Yaron, Partner at Amplify Partners, the event featured a series of rapid-fire questions and answers on major breakthroughs in AI, with contestants racing to identify the most impactful papers, concepts, and models. Among the highlights was the discussion of &quot;Attention is All You Need,&quot; the seminal research behind the Transformer architecture—now powering the most advanced AI models today.</p><p>The competition was not only an exciting intellectual challenge but also a reflection of how much AI research has evolved and influenced the state of modern technology.</p><p>If you’re curious about the event and how the discussion unfolded, you can watch it in action at the following link: <a href="https://www.youtube.com/live/L89GzWEILkM?si=fxn9H9xNPvCckEtm&amp;t=17047">AI Engineer Summit 2025 - Frontier Feud</a>.</p><h2>Applying Attention: Automating Responses with Uniflow</h2><p>Since attention is the key to AI-driven advancements, why not leverage it in automation? A compelling application is an auto-answering bot capable of responding to content across the internet—especially on major social media platforms.</p><p>For this purpose, I created a Uniflow workflow called <a href="https://uniflow.io/flows">Prime AI Answer on Uniflow</a>, designed to generate intelligent responses to social media content dynamically.</p><div align="center">
  Check Prime AI Answer on Uniflow <a href="https://uniflow.io/flows">https://uniflow.io/flows</a></div><h2>How the Workflow Works</h2><p>The Prime AI Answer workflow follows these key steps:</p><p>1️⃣ Set Environment Variables – Define necessary configurations like API keys, session cookies, and model parameters.</p><p>2️⃣ Describe the Prime AI Agent Prompt – Establish a structured prompt that guides the AI’s response generation.</p><p>3️⃣ Scrape Social Media Content – In this demonstration, I focused on LinkedIn.</p><ul><li>To achieve this, I released the Prime AI Answer GitHub project: <a href="https://github.com/matyo91/prime-ai-answer">GitHub - Prime AI Answer</a></li><li>This tool allows scraping LinkedIn content by passing a current session cookie.</li><li>The workflow fetches content via an API call and processes it within Uniflow.</li></ul><p>4️⃣ Create the Prime AI Agent – This step initializes the AI agent and injects the curated prompt, which consists of:</p><ul><li>The descriptive prompt</li><li>The scraped LinkedIn content</li><li>The author’s tone, which was predefined as an environment variable</li></ul><p>5️⃣ Generate &amp; Display AI Responses – The final step showcases the AI-generated responses within Uniflow.</p><h2>Why Automate Social Media Engagement?</h2><p>With AI models becoming increasingly adept at understanding and generating human-like text, automating social media engagement is a powerful application.</p><p>🔥 Prime AI Answer makes it possible to:</p><ul><li>Dynamically generate responses tailored to each post.</li><li>Mimic human-like engagement with the correct tone.</li><li>Scale social media interactions efficiently across platforms.</li></ul><p>As AI continues evolving, leveraging attention-based mechanisms in automation will only grow in importance. Prime AI Answer is just the beginning—imagine the broader possibilities of AI-driven engagement at scale.</p><p>💡 Would you automate your social media interactions? Let me know your thoughts!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/attention-is-all-you-need</link><guid>https://blog.darkwood.com/article/attention-is-all-you-need</guid><enclosure url="http://darkwood.com/media/articles/67bc13cd1512c260748735.jpeg" /></item><item><title>Youtube timestamp looker</title><pubDate>Mon, 10 Mar 2025 07:44:37 +0000</pubDate><description><![CDATA[
Have you ever watched a video and later struggled to remember when a key point was mentioned? Or perhaps you wanted to revisit an interesting moment but couldn’t recall the exact timestamp? Whether you&#039;re conducting research, creating content, or simply tr...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67ce98658c11a896745291.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/YG2wRYH1GQA?si=S4rqr-N4XIGyDkMp" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Have you ever watched a video and later struggled to remember when a key point was mentioned? Or perhaps you wanted to revisit an interesting moment but couldn’t recall the exact timestamp? Whether you're conducting research, creating content, or simply trying to bookmark notable moments, finding specific timestamps in long YouTube videos can be a challenge.</p><p>In this article, we explore how to create an efficient workflow using <a href="https://uniflow.io">Uniflow</a> to interactively retrieve timestamped information from YouTube videos. This dedicated workflow
<a href="https://uniflow.io/flows">Youtube timestamp looker</a> leverages environment variables, custom prompts, and integrates API tools to provide a seamless experience for users seeking detailed insights from YouTube transcripts.</p><h2>Workflow Overview</h2><p>Here are the following key components used to build the workflow</p><ul><li><p>Environment Variables:<br />
Securely store sensitive data such as API keys and configuration settings.</p></li><li><p>Custom Prompt:<br />
Allow the user to write a question or a specific request regarding the video content.</p></li><li><p>Interactive Step Prompt:<br />
Prompt the user to provide the YouTube Video ID for the video they wish to analyze.</p></li><li><p>Code Block Execution:<br />
This is the core of the workflow, where multiple processes occur:</p><h3>ChatGPT Tool Integration</h3><ul><li>Utilize ChatGPT along with a custom tool to analyze the video transcript.</li></ul><h3>API Transcript Timecode Retriever</h3><ul><li>Use the custom API tool based on the contribution made to the <a href="https://github.com/yoanbernabeu/YoutubeTranscriptApi/pull/1">YouTube Transcript API repository</a>.</li><li>This tool fetches the transcript along with its corresponding timecodes, and filters out irrelevant short entries to enhance accuracy.</li></ul><h3>Transcript Cleanup and Chunking</h3><ul><li>The transcript is processed to exclude brief or irrelevant text entries, ensuring concise and valuable input for the API.</li><li>Each entry is converted to a <code>HH:MM:SS</code> format and grouped into 30-second sections for clarity.</li><li>To manage API token limits, the system ensures the text doesn't exceed predefined length restrictions (e.g., 8000 characters).</li></ul><h3>Transcript Summarization (if necessary)</h3><ul><li>If the transcript is too long, the system uses ChatGPT to summarize it while preserving essential timestamps and insights.</li></ul><h3>API Call Execution</h3><ul><li>The summarized or cleaned transcript is then used in an API call with ChatGPT. The call utilizes an interactive prompt where users can specify the exact details they seek from the video.</li></ul><h3>Result Display</h3><ul><li>The result is displayed with clear timestamp markers, ensuring users can easily navigate to the moments they’re interested in.</li></ul></li></ul><h2>Potential Use Cases</h2><ul><li>Content Review: Quickly locate key moments in a video by asking direct questions about its content.</li><li>Content Summarization: Summarize sections of a video, providing timecodes for easy navigation.</li><li>Highlight Extraction: Identify and timestamp notable quotes or events from a video.</li><li>Educational Content: Help educators and learners find relevant video segments aligned with specific topics.</li></ul><h2>Conclusion</h2><p>By leveraging Uniflow's interactive capabilities and integrating with specialized API tools, this workflow provides an efficient solution for extracting and analyzing timestamped data from YouTube videos. This approach not only simplifies content analysis but also enhances user interaction by automating complex data retrieval processes.</p><p>Feel free to adapt and extend this workflow to suit different scenarios, ensuring more efficient and tailored content analysis experiences.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/youtube-timestamp-looker</link><guid>https://blog.darkwood.com/article/youtube-timestamp-looker</guid><enclosure url="http://darkwood.com/media/articles/67ce98658c11a896745291.png" /></item><item><title>Create a Lambda Interpreter in PHP</title><pubDate>Fri, 21 Mar 2025 06:50:32 +0000</pubDate><description><![CDATA[
Presentation associated to this article

Functional programming has gained traction due to its declarative nature, immutability, and composability. A powerful aspect of functional programming is its ability to transform data through the application of func...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67dd0c38a96d4012925969.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/TsVHdYLQorM" title="Create a Lambda Interpreter in PHP" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Presentation associated to this article</p><div class="ratio ratio-16x9"><iframe class="speakerdeck-iframe" frameborder="0" src="https://speakerdeck.com/player/35c59cc4a5ab42faa4263de7dcd2dffa" title="Chunk Computing in PHP" allowfullscreen="true" style="border: 0px; background: padding-box padding-box rgba(0, 0, 0, 0.1); margin: 0px; padding: 0px; border-radius: 6px; box-shadow: rgba(0, 0, 0, 0.2) 0px 5px 40px; width: 100%; height: auto; aspect-ratio: 560 / 314;" data-ratio="1.78343949044586"></iframe></div><p>Functional programming has gained traction due to its declarative nature, immutability, and composability. A powerful aspect of functional programming is its ability to transform data through the application of functions. The foundational concept behind it, Lambda Calculus, introduced by Alonzo Church (1903 - 1995), serves as the theoretical basis for computation, equivalent to the Turing Machine. Church, a mathematician at Princeton, was fascinated by understanding the notion of functions in computational logic. Interestingly, he supervised Alan Turing, known for inventing the Turing machine—a cornerstone of modern computing. The Church-Turing thesis states that lambda calculus and Turing machines are equivalent models of computation. Lambda calculus serves as the conceptual model, while the Turing machine embodies its machine-level implementation.</p><p>In this article, we will explore:</p><ul><li>The theoretical background of Lambda Calculus.</li><li>How functional programming principles can be applied in PHP.</li><li>How we can build a simple lambda interpreter in PHP using existing tools.</li><li>How to integrate it with Symfony Expression Language.</li></ul><h2>Why Lambda Interpreter?</h2><p>The goal is to define a language that allows processing data-flows with functional programming principles. Functional programming is gaining traction due to its declarative nature, immutability, and composability. Instead of imperative programming, where each step modifies a shared state, functional programming treats computation as the evaluation of mathematical functions, avoiding mutable data and side effects. One of its most fascinating applications is in the creation of compilers—transforming code from one representation to another using pure functions. In this article, we will explore building a minimal functional programming compiler in PHP, inspired by https://github.com/loophp/combinator, https://github.com/igorw/lambda-php, and https://github.com/jamiebuilds/the-super-tiny-compiler.</p><h2>What is Lambda Calculus?</h2><p>Before diving into the compiler, let's revisit some functional programming concepts. Lambda Calculus is a formal system in mathematical logic for expressing computation based on function abstraction and application. It was invented by Alonzo Church as a foundation for functional programming.</p><p>Key properties of Lambda Calculus:</p><ul><li>Functions are first-class citizens: They can be passed as arguments and returned as values.</li><li>Everything is a function: Computation consists of function application viewed as functions that apply transformations.</li><li>Pure functions: Functions without side effects.</li><li>Immutability: Data does not change once defined.</li><li>No state, no assignments: There are no variables as in imperative programming.</li></ul><p>In lambda calculus, a function is treated like a black box: it takes inputs and produces outputs. For instance, given the input <code>X</code>, the black box might produce <code>X + 1</code>. This behavior is represented using lambda notation: <code>λx.x + 1</code>, which means &quot;for an input <code>X</code>, return <code>X + 1</code>.</p><p>Basic examples:</p><pre><code>λx.x + 1
(λx.x + 1)(5) = 5 + 1 = 6
</code></pre><p>With multiple parameters:</p><pre><code>λx.λy.x + y
(λx.λy.x + y)(5, 6) = 5 + 6 = 11
</code></pre><h3>Key points:</h3><ul><li>There are variables.</li><li>We have a way to build functions.</li><li>We can apply functions to each other by passing elements of the language itself.</li></ul><p>Lambda calculus also introduces the concept of pure functions, which always return the same output for the same inputs without any internal state.</p><h3>True and False in Lambda Calculus</h3><p>Lambda calculus defines basic logical structures as functions:</p><pre><code>True = λx.λy.x
False = λx.λy.y
</code></pre><p>Translated to PHP:</p><pre><code class="language-php">$true = fn($x) =&gt; fn($y) =&gt; $x;
$false = fn($x) =&gt; fn($y) =&gt; $y;
</code></pre><h3>Implementing Not in Lambda Calculus</h3><p>The <code>not</code> operation can be expressed as:</p><pre><code>Not = λb.b False True
</code></pre><p>In PHP:</p><pre><code class="language-php">$not = fn($b) =&gt; $b($false)($true);
</code></pre><p>If we apply it:</p><pre><code class="language-php">echo $not($true)($x, $y); // Should produce $y (false)
</code></pre><p>Lambda calculus thus defines variables, a way to build functions, and the capacity to apply functions to other functions. Everything derived from the lambda calculus language is self-contained within this system.</p><h2>Functional Programming</h2><p>To learn more about functional programming principles, it is recommended to explore Haskell, a language built on these principles.</p><h2>Functional Programming in PHP</h2><p>Grégoire Hébert wrote a blog about functional programming in PHP, introducing key concepts like currying:
🔗 <a href="https://knot.gheb.dev/blog/php-programmation-fonctionnelle">PHP et programmation fonctionnelle</a></p><h2>Understanding Combinatory Logic in PHP</h2><p>Combinatory logic eliminates the need for explicit variables by using combinators, such as:</p><ul><li>Identity (I): <code>λx.x</code>  → <code>fn($x) =&gt; $x</code></li><li>Kestrel (K): <code>λx.λy.x</code>  → <code>fn($x) =&gt; fn($y) =&gt; $x</code></li><li>Starling (S): <code>λx.λy.λz.x z (y z)</code> → <code>fn($x) =&gt; fn($y) =&gt; fn($z) =&gt; ($x($z))($y($z))</code></li></ul><p>A combinator is a higher-order function that applies transformations without needing explicit variables. Pol Dellaiera created a project that lists and implements remarkable combinators in PHP:
🔗 <a href="https://github.com/loophp/combinator">loophp/combinator</a></p><p>Example of combinators in PHP:</p><pre><code class="language-php">use loophp\Combinator\Combinators;
$I = Combinators::I();
$K = Combinators::K();
$S = Combinators::S();
</code></pre><p>This allows for point-free programming—writing functions without explicitly mentioning arguments.</p><h2>Lambda-PHP</h2><p>Igor Wiedler developed a Lambda interpreter in PHP, using the Dissect library:
🔗 <a href="https://github.com/igorw/lambda-php">lambda-php</a></p><p>Bonus features include:</p><ul><li>Krivine Machine: An alternate interpreter using de Bruijn indices.</li><li>Binary Lambda Calculus: A way to encode lambda calculus in a compact binary form.</li></ul><h2>Symfony Expression Language</h2><p>Symfony Expression Language is an engine that allows you to evaluate expressions dynamically in PHP. Damien Alexandre wrote about specializing it with custom functions:
🔗 <a href="https://jolicode.com/blog/adding-php-function-to-symfony-expressionlanguage-the-simple-way">Adding PHP Function to Symfony ExpressionLanguage</a></p><p>Example of a custom function:</p><pre><code class="language-php">use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;

$language = new ExpressionLanguage();
$language-&gt;addFunction(new ExpressionFunction(
    'reverse',
    function ($str) {
        return sprintf('strrev(%s)', $str);
    },
    function ($arguments, $str) {
        return strrev($str);
    }
));

echo $language-&gt;evaluate('reverse(&quot;JoliCode&quot;)'); // Output: edoCiloJ
</code></pre><p>To integrate a lambda calculus parser into Symfony's ExpressionLanguage, you can extend it by adding custom functions that parse and evaluate lambda expressions. Here's how you can achieve this:</p><ul><li>Implement a Lambda Calculus Parser: Develop a parser that can interpret lambda calculus expressions. You can create your own or utilize existing libraries.</li><li>Create a Custom Expression Function: Define a custom function within Symfony's ExpressionLanguage that leverages your lambda calculus parser. This involves registering a new function that can parse and evaluate lambda expressions.</li></ul><pre><code class="language-php">use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;

// Assuming you have a LambdaParser class that can evaluate lambda expressions
$lambdaParser = new LambdaParser();

$expressionLanguage = new ExpressionLanguage();
$expressionLanguage-&gt;addFunction(new ExpressionFunction(
    'lambda',
    function ($expression) {
        // This is the compiler representation; adjust as needed
        return sprintf('$lambdaParser-&gt;evaluate(%s)', $expression);
    },
    function ($arguments, $expression) use ($lambdaParser) {
        // Evaluate the lambda expression using your parser
        return $lambdaParser-&gt;evaluate($expression);
    }
));

// Example usage
$result = $expressionLanguage-&gt;evaluate('lambda(&quot;(\u03bbx.x)(5)&quot;)');
echo $result; // Outputs: 5
</code></pre><h3>Utilize the Custom Function in Expressions</h3><p>With the custom <code>lambda</code> function registered, you can now use it within your expressions:</p><pre><code class="language-php">$expression = 'lambda(&quot;(\u03bbx.x + 1)(5)&quot;)';
$result = $expressionLanguage-&gt;evaluate($expression);
echo $result; // Outputs: 6
</code></pre><p>By following these steps, you can extend Symfony's ExpressionLanguage to parse and evaluate lambda calculus expressions, integrating functional programming principles into your Symfony applications.</p><h2>What is the lambda language</h2><p>To define a language for parsing Lambda Calculus, you can refer to:
🔗 <a href="https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf">Introduction to Lambda Calculus</a></p><pre><code>&lt;expression&gt; := &lt;name&gt; | &lt;function&gt; | &lt;application&gt;
&lt;function&gt; := λ &lt;name&gt;.&lt;expression&gt;
&lt;application&gt; := &lt;expression&gt;&lt;expression&gt;
</code></pre><h2>What is a compiler ?</h2><p>Compilers transform source code into another form, whether it's machine code, an intermediate representation, or another programming language. At their core, compilers follow these steps:</p><ul><li>Lexing: Converting raw code into tokens.</li><li>Parsing: Constructing an abstract syntax tree (AST).</li><li>Transformation: Modifying the AST to optimize or change its structure.</li><li>Code Generation: Producing the final output.</li></ul><p>In this article, we'll implement a functional compiler that takes lambda calculus expressions and compiles them into executable PHP closures.</p><h2>Implementing a Minimal Functional Compiler</h2><p>To create a minimalist compiler, we can take inspiration from The Super Tiny Compiler:
? <a href="https://github.com/jamiebuilds/the-super-tiny-compiler">The Super Tiny Compiler</a></p><p>A compiler consists of three main components. We implement a Lambda interpreter in PHP by building:</p><ol><li>Tokenizer: Converts expressions into tokens.</li><li>Parser: Builds an AST (Abstract Syntax Tree).</li><li>Evaluator: Interprets the AST and produces output.</li></ol><h3>Lexing (Tokenization)</h3><p>The lexer breaks input into tokens. For example, given the expression <code>λx.x</code>, we tokenize it into:</p><pre><code class="language-php">$tokens = [
    ['type' =&gt; 'lambda', 'value' =&gt; 'λ'],	
    ['type' =&gt; 'identifier', 'value' =&gt; 'x'],
    ['type' =&gt; 'dot', 'value' =&gt; '.'],
    ['type' =&gt; 'identifier', 'value' =&gt; 'x']
];
</code></pre><h3>Parsing into an Abstract Syntax Tree (AST)</h3><p>The parser converts tokens into an AST:</p><pre><code class="language-php">$ast = [
    'λ', 'x', ['identifier', 'x']
];
</code></pre><p>Using recursion, we evaluate the AST into executable code.</p><h3>Evaluation using the Y Combinator</h3><p>Using the Y combinator, we can implement recursion:</p><pre><code class="language-php">$handle = static function (string $expression, array $params) {
    $job = new LambdaJob($expression);
    $result = array_reduce($params, static fn ($carry, $param) =&gt; empty($carry) ? $job($param) : $carry($param));
    $encodedParams = array_map(static fn ($param) =&gt; $param instanceof Closure ? 'Closure' : (is_object($param) ? get_class($param) : $param), $params);
    echo 'Evaluating ' . $expression . ' with params ' . json_encode($encodedParams) . ' : ' . $result . &quot;\n&quot;;
};

// | Y         | Y-Fixed point |                   |         | `λa.(λb(a(bb))(λb(a(bb))))` | `a =&gt; (b =&gt; b(b))(b =&gt; a(c =&gt; b(b)(c)))` |                                                      | 1           |
$handle('λf.(λx.f (λy.(x x) y)) (λx.f (λy.(x x) y))', [
    static function ($factorial) {
        return static function (YFlowData $data) use ($factorial): YFlowData {
            return new YFlowData(
                $data-&gt;id,
                $data-&gt;number,
                ($data-&gt;number &lt;= 1) ? 1 : $data-&gt;number * $factorial(new YFlowData($data-&gt;id, $data-&gt;number - 1, $data-&gt;result - 1))-&gt;result
            );
        };
    },
    new YFlowData(1, 6),
]);
// output Evaluating λf.(λx.f (λy.(x x) y)) (λx.f (λy.(x x) y)) with params [&quot;Closure&quot;,&quot;Flow\\Examples\\Model\\YFlowData&quot;] : 720
</code></pre><h2>Practical Use Cases</h2><p>This functional compiler allows for:</p><ul><li>Interpreting Lambda Calculus expressions in PHP.</li><li>Creating DSLs (Domain-Specific Languages) with combinatory logic.</li><li>Building extensible and reusable functional components.</li></ul><p>We can extend this to compile more complex expressions, optimize computations, or generate PHP code dynamically.</p><h2>Programming with Nothing</h2><p>Tom Stuart wrote about how to make complex transformations with minimal rules:
🔗 <a href="https://tomstu.art/programming-with-nothing">Programming with Nothing</a></p><h2>Conclusion</h2><p>By leveraging functional programming and combinatory logic, we have built a simple functional compiler in PHP. This showcases how lambda calculus, the Y combinator, and pure functions work together to create a concise, expressive, and mathematically elegant way of writing code. Concept can be applied in a real-world PHP implementation.</p><p>Further exploration could include optimizing the AST, supporting more combinators, or integrating with <a href="https://flow.darkwood.com">Flow</a> to enhance automation and orchestration.</p><h2>Resources</h2><ul><li>Wikipedia Lambda calculus : https://en.wikipedia.org/wiki/Lambda_calculus</li><li>Introduction to the Lambda Calculus : https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf</li><li>Lambda syntax : https://opendsa.cs.vt.edu/ODSA/Books/PL/html/Syntax.html</li><li>Parsing Lambda Calculus in Scala : https://web.archive.org/web/20130802034031/http://zeroturnaround.com/rebellabs/parsing-lambda-calculus-in-scala</li><li>7 lines of code, 3 minutes: Implement a programming language from scratch : https://matt.might.net/articles/implementing-a-programming-language</li><li>The smallest compiler ever : https://github.com/jamiebuilds/the-super-tiny-compiler</li><li>Expression Langage from symfony : https://github.com/symfony/symfony/tree/7.3/src/Symfony/Component/ExpressionLanguage</li><li>Lambda calculus interpreter in PHP https://github.com/igorw/lambda-php</li><li>A curated list of combinators in PHP https://github.com/loophp/combinator</li><li>Flow that use Asynchrone and functional programming https://github.com/darkwood-com/flow</li><li>Programming with Nothing : https://tomstu.art/programming-with-nothing</li><li>Adding PHP Function to Symfony ExpressionLanguage, The Simple Way ? : https://jolicode.com/blog/adding-php-function-to-symfony-expressionlanguage-the-simple-way</li><li>PHP et programmation fonctionnelle : https://knot.gheb.dev/blog/php-programmation-fonctionnelle</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/create-a-lambda-interpreter-in-php</link><guid>https://blog.darkwood.com/article/create-a-lambda-interpreter-in-php</guid><enclosure url="http://darkwood.com/media/articles/67dd0c38a96d4012925969.png" /></item><item><title>Coder comme un DJ, mixer comme un dev</title><pubDate>Fri, 21 Mar 2025 22:24:48 +0000</pubDate><description><![CDATA[
🎧 Quand le code rencontre les platines : l&#039;alliance naturelle entre DJing et développement
Pendant la journée, je développe. Le soir, je mixe. Deux mondes à première vue très différents, mais qui partagent bien plus qu&#039;on ne l&#039;imagine.
Je m&#039;appelle Mathieu...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67dde730af216835165222.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/xunjpoyhRLs" title="DJMatyo91" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h1>🎧 Quand le code rencontre les platines : l'alliance naturelle entre DJing et développement</h1><p>Pendant la journée, je développe. Le soir, je mixe. Deux mondes à première vue très différents, mais qui partagent bien plus qu'on ne l'imagine.</p><p>Je m'appelle Mathieu — développeur web, passionné par l'automatisation, les architectures propres… et aussi DJ sous le nom de DJ Matyo. Si vous êtes curieux, voici un de mes derniers sets :<br />
🎶 <a href="https://www.youtube.com/watch?v=xunjpoyhRLs">Écouter le mix sur YouTube</a></p><p>Et aujourd'hui, j'ai envie d'explorer ce qui relie ces deux univers que je pratique au quotidien.</p><h2>🎛 La logique des patterns : boucles, samples, fonctions</h2><p>En code comme en musique, tout part de patterns. Le développeur écrit des fonctions réutilisables, le DJ utilise des loops, des breaks, des transitions.</p><p>Une track bien construite fonctionne comme un bon morceau de code :</p><ul><li>une intro pour installer le contexte,</li><li>un build-up pour préparer la montée,</li><li>un drop qui délivre l'émotion,</li><li>une sortie propre pour laisser place à la suite.</li></ul><p>Et dans les deux cas, on raffine, on optimise, on coupe ce qui dépasse.</p><h2>🧠 L'écoute active : comprendre pour mieux synchroniser</h2><p>En tant que DJ, tu ne joues pas pour toi, mais pour la vibe du moment. Tu écoutes. Tu ressens. Tu anticipes.<br />
C'est exactement ce que fait un développeur à l'écoute de ses utilisateurs, de son équipe, ou d'un système distribué en train de saturer.</p><p>La bonne transition dans un mix, comme le bon refactoring dans un projet, se fait en douceur, sans casser le rythme.</p><h2>🔁 Le flow : cet état où tout devient fluide</h2><p>Il y a ce moment magique, où tu perds la notion du temps.<br />
Tu enchaînes les sons ou les lignes de code avec fluidité.<br />
C'est le flow state.<br />
Le point de rencontre entre concentration extrême, plaisir, et performance.</p><p>C'est cette sensation que je cherche, que je cultive. Elle existe autant derrière un DAW que derrière un terminal.</p><h2>🎤 Une double identité assumée</h2><p>Longtemps, j'ai gardé ces deux mondes séparés. Mais aujourd'hui, j'assume :<br />
Je suis développeur et DJ.<br />
Créer du code propre ou des mixes inspirants, c'est pour moi la même quête : celle d'un équilibre entre logique et émotion.</p><p>👉 <a href="https://www.youtube.com/watch?v=xunjpoyhRLs">DJ Matyo – Dernier set sur YouTube</a></p><p>💡 Et vous ? Vous avez aussi une activité parallèle qui nourrit votre pratique pro ?</p>
]]></content:encoded><link>https://blog.darkwood.com/article/coder-comme-un-dj-mixer-comme-un-dev</link><guid>https://blog.darkwood.com/article/coder-comme-un-dj-mixer-comme-un-dev</guid><enclosure url="http://darkwood.com/media/articles/67dde730af216835165222.png" /></item><item><title>Darkwood 1.0.0 is Here</title><pubDate>Fri, 11 Apr 2025 07:07:24 +0000</pubDate><description><![CDATA[It is with great joy that I announce the official release of Darkwood version 1.0.0.
This milestone marks not only the return of Darkwood in all its strategic and mysterious glory, but also a bold step forward. After months of development, battles, and feed...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67f8bfac5ddf5847683116.png" /></p><p>It is with great joy that I announce the official release of Darkwood version 1.0.0.</p><p>This milestone marks not only the return of Darkwood in all its strategic and mysterious glory, but also a bold step forward. After months of development, battles, and feedback from our amazing community, Darkwood has reached its first full version.</p><p>More than 4,000 players have already joined the adventure. To each and every one of you: thank you. Your presence, your strategies, your suggestions and your passion have shaped what Darkwood is today.</p><p>What’s new in version 1.0.0?</p><ul><li>A fully stable core system, based on modern architecture</li><li>Improved balance and mechanics</li><li>Enhanced performance and smoother gameplay</li><li>Dozens of bugs crushed under the boots of progress</li></ul><p>And that's not all...</p><p>Darkwood is open source. Released under the MIT license, anyone is free to explore the code, suggest improvements, or even contribute directly. Whether you're a developer, a designer, a writer, or just a fan with ideas — the door is wide open.</p><p>You can find the repository here: <a href="https://github.com/darkwood-com/darkwood-com">GitHub - darkwood-project</a></p><p>Darkwood has always been a land of strategy, cunning, and honor. Now it is also a land of creation and collaboration.</p><p>We’re just getting started.</p><p>While the best may rise, all paths are still open. Sharpen your mind. Choose your moves. Enter the forest.</p><p>I hope you enjoy your time on Darkwood!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-1-0-0-is-here-1</link><guid>https://blog.darkwood.com/article/darkwood-1-0-0-is-here-1</guid><enclosure url="http://darkwood.com/media/articles/67f8bfac5ddf5847683116.png" /></item><item><title>Transforming Your Voice into a Blog Post with GPT and Meteor</title><pubDate>Sun, 13 Apr 2025 06:19:23 +0000</pubDate><description><![CDATA[
🎯 Project Overview
This project combines several modern tools to streamline creative output:

⚛ Meteor.js – for the real-time frontend chat application
🧠 OpenAI APIs – Whisper for transcription and GPT-4 for content generation
💧 Uniflow – an open-source au...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67fbfe52eda78377465430.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/17TVuSF46Tg?si=9kCWkYEtRhl63GW4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>🎯 Project Overview</h2><p>This project combines several modern tools to streamline creative output:</p><ul><li>⚛ <a href="https://www.meteor.com">Meteor.js</a> – for the real-time frontend chat application</li><li>🧠 <a href="https://openai.com">OpenAI APIs</a> – Whisper for transcription and GPT-4 for content generation</li><li>💧 <a href="https://uniflow.io">Uniflow</a> – an open-source automation engine</li><li>🌏 <a href="https://api.darkwood.com">Darkwood API</a> – for article publication</li></ul><p>Whether you're a developer, content creator, or automation enthusiast, this setup shows how voice-driven content creation can integrate into a complete publishing workflow.</p><h2>🔧 Part 1 – Building the Meteor Application</h2><p>The first step was to create a Meteor-based chat app that actively listens to your microphone 🎤 and sends the audio to OpenAI for processing. The application was inspired by classic tutorials like Meteor's Todo example, but extended to support modern voice-to-text workflows.</p><h3>🚀 Setup Instructions</h3><pre><code class="language-bash">curl https://install.meteor.com/ | sh
meteor create vocal-chat-app
cd vocal-chat-app
meteor npm install react react-dom react-mic axios
</code></pre><p>Additional Meteor packages:</p><pre><code class="language-bash">meteor add static-html react-meteor-data
</code></pre><h3>🎤 Capturing and Transcribing Voice</h3><p>Using <code>react-mic</code>, the app provides a simple &quot;Record&quot; and &quot;Stop&quot; button to capture voice input. Once the audio is captured, it is sent to OpenAI's Whisper API for transcription. This provides a text base that is used for content generation.</p><h3>✍ Article Generation with GPT-4</h3><p>The transcript is passed into a GPT-4o prompt like this:</p><blockquote><p><em>&quot;Write me a blog post about no-life geek developers who eat pizza 🍕 and drink beer 🍺 to finish their project before tomorrow's deadline 💀.&quot;</em></p></blockquote><p>The result is a complete article formatted in Markdown or HTML, ready to be displayed inside the chat interface. The layout is styled in CSS to match a minimal chat UI, with messages from the user and AI clearly distinguished.</p><h2>🔁 Part 2 – Publishing the Article Automatically</h2><p>Once the article is generated, the second phase is about automation: pushing the content live without needing a CMS or manual intervention.</p><h3>🧩 The Uniflow Workflow</h3><p>The Uniflow workflow is structured into three blocks:</p><ol><li>Text input – the article body is pasted into a text block.</li><li>Title generation – a GPT-4 call generates a SEO-optimized title from the article.</li><li>API publishing – two HTTP requests are made to the Darkwood API:
<ul><li>First: create an <code>Article</code></li><li>Second: create an <code>ArticleTranslation</code> using the IRI returned by the first call</li></ul></li></ol><h3>🧬 Example JavaScript Logic Using Axios</h3><pre><code class="language-javascript">let token = null;
let rawTitle = aiTitle.value;
let slug = rawTitle
  .toLowerCase()
  .normalize(&quot;NFD&quot;)
  .replace(/[\u0300-\u036f]/g, &quot;&quot;)
  .replace(/\s+/g, &quot;-&quot;)
  .replace(/[^a-z0-9\-]/g, &quot;&quot;);

// Step 1 – Authenticate
axios.post('http://api.darkwood.localhost:8092/auth', {
  email: 'darkwood',
  password: 'darkwood'
}, {
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  }
})
.then(function(authResponse) {
  token = authResponse.data.token;

  // Step 2 – Create Article
  return axios.post('http://api.darkwood.localhost:8092/api/articles', {
    tags: [],
    comments: []
  }, {
    headers: {
      'Authorization': 'Bearer ' + token,
      'Content-Type': 'application/ld+json',
      'Accept': 'application/ld+json'
    }
  });
})
.then(function(articleResponse) {
  const articleIri = articleResponse.data['@id'];

  // Step 3 – Create ArticleTranslation
  return axios.post('http://api.darkwood.localhost:8092/api/article_translations', {
    locale: &quot;fr&quot;,
    article: articleIri,
    title: rawTitle,
    slug: slug,
    content: article_content,
    imageName: &quot;&quot;,
    active: true
  }, {
    headers: {
      'Authorization': 'Bearer ' + token,
      'Content-Type': 'application/ld+json',
      'Accept': 'application/ld+json'
    }
  });
})
.then(function(translationResponse) {
  console.log(&quot;✅ Article and translation published successfully!&quot;);
})
.catch(function(error) {
  console.error(&quot;❌ Publication error:&quot;, error);
});
</code></pre><h2>✅ What This Project Demonstrates</h2><p>This project brings together:</p><ul><li>🎤 Voice as input</li><li>✨ AI as a creative assistant</li><li>⚙ Automation as a publishing engine</li></ul><p>It's a powerful setup for any developer or solo creator who wants to move faster and reduce manual steps in the publishing pipeline.</p><h2>📢 Learn More</h2><p>🧪 Source code avalaible on Github <a href="https://github.com/matyo91/vocal-chat-app">https://github.com/matyo91/vocal-chat-app</a></p><p>If you're interested in creating your own automation tools, or want to build end-to-end workflows like this one, I've created a full training to help you get started:</p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Check out my Bonzai automation course</a></div><p>Thanks for reading,<br />
and keep building 🔧 — your ideas deserve to be automated.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/transforming-your-voice-into-a-blog-post-with-gpt-and-meteor</link><guid>https://blog.darkwood.com/article/transforming-your-voice-into-a-blog-post-with-gpt-and-meteor</guid><enclosure url="http://darkwood.com/media/articles/67fbfe52eda78377465430.png" /></item><item><title>Darkwood v1.0.1 released</title><pubDate>Mon, 14 Apr 2025 06:45:11 +0000</pubDate><description><![CDATA[Here is a new release for Darkwood v1.0.1

Add tests
Players must defeat the previous enemy before challenging the current one.
Add new Api endpoints : Page, PageTranslation, Article, ArticleTranslation.

checkout changes on Github
]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/67fcaef7b88ee345273594.png" /></p><p>Here is a new release for Darkwood v1.0.1</p><ul><li>Add tests</li><li>Players must defeat the previous enemy before challenging the current one.</li><li>Add new Api endpoints : Page, PageTranslation, Article, ArticleTranslation.</li></ul><p>checkout changes on <a href="https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.1">Github</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-v1-0-1-released</link><guid>https://blog.darkwood.com/article/darkwood-v1-0-1-released</guid><enclosure url="http://darkwood.com/media/articles/67fcaef7b88ee345273594.png" /></item><item><title>DJ Matyo Live repost tracks</title><pubDate>Tue, 22 Apr 2025 01:03:35 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · DJ Matyo Live repost tracks
Nouvelle session DJ Matyo basée sur des reposts Souncloud
Tracklist

Unproven - Started A Fire - Unproven https://soundcloud.com/unproven-nl/unproven-started-a-fire
Hell Division - Move It (Free Dow...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6806eb1128837354098619.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/V6spBe488zI?si=ys3MfkVmfKnU-brh" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2082768897&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/dj-matyo-live-repost-tracks" title="DJ Matyo Live repost tracks" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo Live repost tracks</a></div></div><p>Nouvelle session DJ Matyo basée sur des reposts Souncloud</p><p>Tracklist</p><ul><li>Unproven - Started A Fire - Unproven https://soundcloud.com/unproven-nl/unproven-started-a-fire</li><li>Hell Division - Move It (Free Download) - Hell Division https://soundcloud.com/hell_division/hell-division-move-it</li><li>Revelation Ft. Vetufice - Fake Friends (FREE DOWNLOAD) - officialRevelation https://soundcloud.com/officialrevelationnl/revelation-ft-vetufice-fake-friends-free-download</li><li>TukkerTempo - Brutal Mash (Radical Redemption Mashup) - Tukkertempo https://soundcloud.com/tukkertempo/tukkertempo-brutal-mash-radical-redemption-mashup</li><li>Rihanna - Don't Stop The Music (Lady Dammage Bootleg) - Lady Dammage https://soundcloud.com/ladydammage/rihanna-dont-stop-the-music-lady-dammage-bootleg</li><li>Kraken Oldschool Streets (Mashup) - S-Kill https://soundcloud.com/skill-official-952784452/kraken-oldschool-streets-mashup</li><li>Putu - The Extreme Uptempo Mash - Up (Malice Tribute) - Putu Official https://soundcloud.com/valeputuputu/putu-the-extreme-uptempo-mash-up-malice-tribute</li><li>D-Fuzion-trebles (free download) - D-Fuzion https://soundcloud.com/dfuzion2022/d-fuzion-trebles-free-download</li><li>Stadiumfest 2022 - Beano (TIOS Digital) https://soundcloud.com/beanodj/stadiumfest-2022</li><li>We Share This Love - MC Darkside (THC) https://soundcloud.com/darksidethc/we-share-this-love</li><li>Flakee + Darwin feat allison - dream surprise - Allison McLauchlan ?? https://soundcloud.com/allisonm/flakee-darwin-feat-allison</li><li>Holiday Mix 2022 - DJ Jimmer : https://soundcloud.com/jimmer-mcallister/holiday-mix-2022</li><li>Andy Lund - Lion - Andy Lund : https://soundcloud.com/dnzrecords/andy-lund-lion</li><li>Greenblue09.mp3 - RUBULOME - https://open.spotify.com/intl-fr/artist/0IaKmQmmTc9LrvZVdErjlD</li></ul><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live-repost-tracks</link><guid>https://blog.darkwood.com/article/dj-matyo-live-repost-tracks</guid><enclosure url="http://darkwood.com/media/articles/6806eb1128837354098619.jpg" /></item><item><title>Ask codex</title><pubDate>Tue, 22 Apr 2025 06:49:42 +0000</pubDate><description><![CDATA[
🚀 Codex is OpenAI&#039;s newly open-sourced CLI tool for local agents. Just five days after its release, I jumped in to explore how I could take it further. In this article, I&#039;ll walk you through how I connected Codex with Uniflow to automate code understanding...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68073c0646b75739592709.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/VZsqIjcuqzs?si=i4GdFQbTZSy2UjLT" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>🚀 Codex is OpenAI's newly open-sourced CLI tool for local agents. Just five days after its release, I jumped in to explore how I could take it further. In this article, I'll walk you through how I connected <strong>Codex with Uniflow</strong> to automate code understanding and summarization.</p><h2>✨ What Is Codex?</h2><p>🔗 Codex lets you ask questions about your codebase via the terminal. You install it with:</p><pre><code class="language-bash">npm install -g openai/codex
</code></pre><p>Then you can run prompts like:</p><pre><code class="language-bash">codex -q --json &quot;explain utils.ts&quot;
</code></pre><p>This example is one of the official use cases published by OpenAI on <a href="https://github.com/openai/codex">their GitHub repository</a>.</p><h2>⚖️ Why Automate It With Uniflow?</h2><p>I didn't just want to run commands manually. I wanted to <strong>industrialize the interaction</strong> and make Codex a callable tool inside Uniflow. This allows ChatGPT to delegate execution to Codex and return human-readable insights.</p><h2>🌍 Building the Workflow</h2><p>Inside Uniflow, I created a new project called <code>AskCodex</code>. Using Uniflow's Node client, I structured the workflow to:</p><ol><li>Set the <code>OPENAI_API_KEY</code> as an ENV variable</li><li>Define a custom prompt such as: <code>Use Codex to explain utils.ts</code></li><li>Register <code>runCodex</code> as a tool inside the ChatGPT request</li><li>Have ChatGPT call <code>runCodex</code> with the prompt</li><li>Execute the CLI tool via Uniflow's batch bridge</li><li>Summarize Codex's output using a second call to ChatGPT</li></ol><h2>🦄 Example Output</h2><p>In my test, Codex successfully read and explained <code>utils.ts</code>. It identified helper functions like:</p><ul><li><code>sleep()</code> – creates a delay</li><li><code>isNil()</code> – returns true for <code>null</code> or <code>undefined</code></li><li><code>saveAsJSON()</code> – handles object persistence</li></ul><p>After the tool runs, ChatGPT then provides a clean summary of the file.</p><h2>🌧 Limitations and Future Ideas</h2><p>❌ Codex currently doesn't maintain context across calls. It would be amazing to have a persistent interactive API mode where the model can ask clarifying questions.</p><p>🧠 Until then, we simulate interactivity with Uniflow by re-prompting GPT with additional information.</p><h2>🏫 Run It Yourself</h2><p>If you want to test locally:</p><pre><code class="language-bash">npm install -g openai/codex
export OPENAI_API_KEY=your_key
codex -q &quot;explain utils.ts&quot; --json
</code></pre><h2>🔥 Try the Full Automation</h2><p>To reproduce what I did in this video, run your own flow inside Uniflow using its Node client. My example uses the CLI + Docker API and connects to Uniflow locally at port 9016.</p><p>Here is the resources I used</p><p>Flows :</p><ul><li>Object
Variable : <code>env = { openai_api_key: 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 }</code></li><li>Text
Variable : codex_prompt = <code>Use Codex tool and ask him to &quot;explain utils.ts&quot;</code></li><li>Function
Code :</li></ul><pre><code class="language-javascript">// Tool function to run Codex CLI
function runCodex(prompt) {
  console.log(`?️ Running Codex with prompt:\n${prompt}`);
  try {
    const sanitizedPrompt = prompt.replace(/&quot;/g, '\\&quot;');
    const command = `OPENAI_API_KEY=${env.openai_api_key} codex -q &quot;${sanitizedPrompt}&quot; --json`;
    const output = Bash.exec(command, { encoding: 'utf-8' });
    return output;
  } catch (error) {
    return 'Codex error: ' + (error.stderr || error.message);
  }
}

// Function to call ChatGPT with fetch
function askChatGPT(prompt) {
  console.log(`? Asking ChatGPT:\n${prompt}`);
  return fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + env.openai_api_key,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'gpt-4',
      tools: [
        {
          type: 'function',
          function: {
            name: 'runCodex',
            description: 'Executes Codex CLI with a given prompt',
            parameters: {
              type: 'object',
              properties: {
                prompt: { type: 'string', description: 'Prompt to send to Codex CLI' }
              },
              required: ['prompt']
            }
          }
        }
      ],
      messages: [
        {
          role: 'system',
          content: 'You are an automation assistant that can call a custom CLI tool named &quot;codex&quot;.'
        },
        {
          role: 'user',
          content: prompt
        }
      ]
    })
  });
}

// Full flow execution
askChatGPT(codex_prompt)
  .then(res =&gt; res.json())
  .then(data =&gt; {
    const toolCalls = data.choices?.[0]?.message?.tool_calls || [];

    if (toolCalls.length === 0) {
      console.log('ℹ️ No tool calls detected in the response.');
      return Promise.resolve('No output from Codex.');
    }

    const executions = toolCalls.map(call =&gt; {
      if (call.function?.name === 'runCodex') {
        const args = JSON.parse(call.function.arguments);
        return runCodex(args.prompt);
      }
      return Promise.resolve(null);
    });

    return Promise.all(executions);
  })
  .then(outputs =&gt; {
    const content = outputs.join('\n');
    console.log('? Codex Output:\n', content);

    // Summarize Codex result with ChatGPT
    return askChatGPT(`Summarize this content:\n\n${content}`);
  })
  .then(res =&gt; res.json())
  .then(result =&gt; {
    const summary = result.choices?.[0]?.message?.content || '❌ No summary generated.';
    console.log('? Final Summary:\n', summary);
  })
  .catch(error =&gt; {
    console.error('❌ Flow error:', error.message);
  });
</code></pre><h3>📌 Run Flow</h3><p>go to <code>library/uniflow-client-node</code></p><p>Generate <code>dist/node.js</code></p><pre><code class="language-bash">npm run build:dev
</code></pre><p>Run Flow with Uniflow Node Client</p><pre><code>node dist/node.js --env=dev --api-key=zxtl1facmgbapyvjg581oip28sinzyr4 ask-codex
</code></pre><h2>👏 Conclusion</h2><p>We saw how Codex can become much more powerful when plugged into an orchestrator like Uniflow. This combination turns raw CLI outputs into refined, automated summaries. Perfect for DevOps, onboarding, or code review pipelines.</p><h3>🚀 Want to build your own workflows?</h3><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Check out my Bonzai automation course</a></div><p>🎥 Watch the video on YouTube and don't forget to like, share, and subscribe. See you soon!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/ask-codex</link><guid>https://blog.darkwood.com/article/ask-codex</guid><enclosure url="http://darkwood.com/media/articles/68073c0646b75739592709.png" /></item><item><title>Build a Game for the largest game dev competition in the world</title><pubDate>Sun, 27 Apr 2025 20:56:23 +0000</pubDate><description><![CDATA[
The Game Development World Championship (GDWC) is a fantastic global competition for indie developers. This year, they introduced a special category: Best Discord Game, sponsored by Discord itself. The winner will receive $5,000 💰 and be featured on Discor...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/680e99f73b82c451532043.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/vMePhtKbTc0?si=o-Z2AQtWj29CFNZC" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>The Game Development World Championship (<a href="https://thegdwc.com">GDWC</a>) is a fantastic global competition for indie developers. This year, they introduced a special category: Best Discord Game, sponsored by Discord itself. The winner will receive $5,000 💰 and be featured on Discord's discovery surfaces — a huge boost for visibility!</p><p>In this blog post, I'm not offering a tutorial. Instead, I want to share my journey: learning how to integrate the Discord Embedded App SDK and building my very first Discord Activity. 💪</p><h2>🛠️ Getting Started: Building a Discord Game</h2><p>To participate in the Best Discord Game category, you need to integrate the Discord Embedded App SDK into your project. This allows you to leverage Discord's powerful social features — voice, chat, presence, matchmaking, and more.</p><ul><li>💬 <a href="https://discord.com/invite/discord-developers">Join the Discord Developer Server</a></li><li>🌍 <a href="https://discord.com/developers/docs/activities/overview">Discord Activities Overview</a></li></ul><p>If there's interest, I could later dive deeper into Development Patterns, How Activities Work, and Design Patterns.</p><h3>📚 Build Your First Discord Activity</h3><p>For a step-by-step guide, here's the <a href="https://discord.com/developers/docs/activities/building-an-activity">official documentation</a>.</p><h2>🌟 Best Discord Game Award Entry</h2><p>Our team, Darkwaar, submitted our game: Vite.</p><ul><li>👥 <a href="https://thegdwc.com/pages/team.php?l=darkwaar">Team Darkwaar Page</a></li><li>🎮 <a href="https://thegdwc.com/pages/game.php?game_guid=0c0cef88-62dd-46b3-8a3c-0db09ca2e2a5">Vite Game Page</a></li></ul><h2>🛜 Setting Up the Environment: Decompiling Vite</h2><p>First, I needed to set up Rust 🧙‍♂️. After installing it, remember to restart your shell to properly set up your environment variables.</p><pre><code class="language-bash">rustc --version
# rustc 1.86.0 (05f9846f8 2025-03-31)
</code></pre><pre><code class="language-bash">cargo run --help
</code></pre><p>Additionally, I explored running Windows XP in a Docker container to attempt decompiling my old TI-89 BASIC game &quot;Vite.&quot; Here's the setup:</p><ul><li>📉 <a href="https://www.youtube.com/watch?app=desktop&amp;v=2EEzKlF7miA">Tutorial: Run Windows XP in Docker</a></li><li>💾 <a href="https://archive.org/details/windows-xp-all-sp-msdn-iso-files-en-de-ru-tr-x86-x64">Windows XP ISO files</a></li></ul><p>Example QEMU Command:</p><pre><code class="language-bash">qemu-system-i386 -cpu pentium -m 4G -hda /isos/xp.vhd -cdrom /isos/en_winxp_pro_with_sp2.iso -boot d -nic user,model=e1000,hostfwd=tcp::8888-:80 -soundhw ac97
</code></pre><h2>🎮 About Vite: The Game Concept</h2><p>Vite is a pixel-style survival game where you help a character, Mathieu LEDRU, survive in a desert after being exiled from &quot;PC City&quot; for using a Mac 🖥️.</p><p>Gameplay Mechanics:</p><ul><li>🛋️ Move Mathieu towards a target pixel.</li><li>💸 Earn credits and upgrade your abilities.</li><li>⏱️ Survive as long as possible before time runs out.</li></ul><p>Variables and Game States:</p><ul><li>Credits, Time, Speed, Size, Level, State, X, Y, TargetX, TargetY, LevelupChoice.</li><li>States: 'intro', 'play', 'levelup', 'end'.</li></ul><p>Full logic is built around updating states based on user input and game timing.</p><h2>🌐 Deep Dive: My Development Journey</h2><p>In my video, I shared everything from initial setup to how I adapted my old TI-89 game for the GDWC 2025 Best Discord Game Award:</p><ul><li>Competition Overview: The GDWC offers 4 categories, including Best Discord Game with a $5,000 prize.</li><li>Preparation: Learned the Discord Embedded App SDK by following the &quot;Build Your First Activity&quot; guide. No live coding — full preparation first! 📈</li><li>Technical Stack:
<ul><li>📚 Frontend: Vanilla HTML + Node.js.</li><li>🚀 Server: Node.js backend with simple API authentication.</li><li>☁️ Tunnel: Used Cloudflare Tunnel to expose local servers.</li></ul></li><li>Challenges:
<ul><li>🔧 Attempted to decompile my TI-89 BASIC program.</li><li>🌐 Explored Docker virtualizations with Windows XP.</li><li>🎹 Used open-source tools like TIO2 (Rust decompiler) and TI simulators.</li></ul></li><li>Game Design Inspiration:
<ul><li>🎮 Based on my original TI-89 &quot;Vite&quot; game.</li><li>👉 Movement using keyboard arrows.</li><li>🏆 Level-up system offering speed, size, or time bonuses.</li></ul></li></ul><h3>🚀 Final Outcome: Vite Activity</h3><p>Once everything was connected and authenticated, I could run Vite as a live Discord Activity:</p><ul><li>📅 Intro Scene: Displays credits, speed, size, time, and level.</li><li>🚶‍♂️ Play Scene: Move Mathieu to the target pixel.</li><li>📊 Level-up Scene: Choose upgrades.</li><li>🎉 End Scene: Displays congratulations message.</li></ul><p>The entire flow is managed via a simple game loop running at 30 FPS. ⏳</p><h2>📚 Resources I Used</h2><ul><li><a href="https://thegdwc.com">The game development world championship</a></li><li><a href="https://darkwaar.com">Darkwaar project</a></li><li><a href="https://apps.darkwood.com/ti89">Darkwood apps TI89</a></li><li><a href="https://discord.com/developers/docs/developer-tools/community-resources">Discord community resources</a></li><li><a href="https://www.npmjs.com/package/@discord/embedded-app-sdk">@discord/embedded-app-sdk</a></li><li><a href="https://github.com/discord/embedded-app-sdk-examples?tab=readme-ov-file#community-curated-examples">embedded-app-sdk-examples</a></li><li><a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads">Cloudflared</a></li><li>📂 <a href="https://github.com/TabulateJarl8/tio2">TiO2: TI-BASIC Interpreter/Compiler/Decompiler</a></li><li>👾 <a href="https://ti89-simulator.com">TI-89 Simulator</a></li><li><a href="https://en.wikibooks.org/wiki/TI-Basic_89_Programming/A_Basic_Program">TI-Basic 89 Programming/A Basic Program</a></li><li><a href="https://www.ocf.berkeley.edu/~pad/emu/">Pad/emu</a></li><li>🕹️ <a href="https://tiplanet.org/emu68k_fork">Javascript TI-89/TI-92+/TI-V200 Emulator</a></li><li><a href="https://github.com/Acksop">Emmanuel ROY A.K.A Acksop</a></li><li><a href="https://github.com/TabulateJarl8/tio2">TiO2 decompilator</a></li><li><a href="https://github.com/TabulateJarl8/ti842py">ti842py is a TI-BASIC to Python 3 transpiler</a></li><li>📊 <a href="https://dogbolt.org">Decompiler Explorer</a></li><li>👩‍💻 <a href="https://www.rust-lang.org">Rust Programming Language</a></li><li><a href="https://code.visualstudio.com/docs/languages/rust">Rust in Visual Studio Code</a></li><li><a href="https://www.reddit.com/r/TI_Calculators/comments/96v69a/ti89_any_pc_program_editor_for_tibasic/">TI-89: any PC program editor for TI-Basic?</a></li><li><a href="https://www.virtualbox.org">Virtualbox</a></li><li><a href="https://www.youtube.com/watch?v=2EEzKlF7miA">Run Windows XP in a Docker Container!</a></li><li><a href="https://www.youtube.com/watch?v=PXUWpbcCL6A">Run Windows 98 in a Docker Container!</a></li><li>🌐 <a href="https://github.com/dockur/windows">Windows Docker Projects</a></li><li>💾 <a href="https://archive.org/details/win98se_fr">Windows 98 ISO</a></li><li><a href="https://school.gamecodeur.fr/stage-dungeon-crawler-old-school-academy">Code Camp : Dungeon Crawler Old School Academy</a></li><li>Background credit: 📸 <a href="https://unsplash.com/fr/photos/une-chambre-avec-une-bibliotheque-et-des-chaises-dGHgnEPPH3w">Luiz Cent</a></li></ul><p>If you're thinking of building a Discord game, I hope this gives you a clear idea of what the journey looks like! Feel free to ask if you want deeper tutorials or tips ✨ — and stay tuned for a future post on how I submitted my game officially to the GDWC! 🚀</p><h2>🔗 Interested in Game Development Consulting?</h2><p>Check out my consulting services for Jeux et Vidéo Ludique here</p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/k219_2165/consulting-jeux-et-video-ludique">Consulting Jeux et Vidéo Ludique</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/build-a-game-for-the-largest-game-dev-competition-in-the-world</link><guid>https://blog.darkwood.com/article/build-a-game-for-the-largest-game-dev-competition-in-the-world</guid><enclosure url="http://darkwood.com/media/articles/680e99f73b82c451532043.png" /></item><item><title>DJ Matyo Live</title><pubDate>Tue, 29 Apr 2025 06:49:13 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · DJ Matyo Live
Nouvelle session DJ Matyo basée sur des reposts Souncloud
Tracklist

Music Makes Me Happy ....... ( The Multi Choonage Adventure Mix ) ? https://soundcloud.com/dj-des-2009-1/music-make-me-happy-the-multi
Flakee +...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6810766999f4d540690660.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/hRYdJYpaLi4?si=b6DDFCJ0O7X1jgTi" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2086959750&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/2025-04-28-dj-matyo-live" title="DJ Matyo Live" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo Live</a></div></div><p>Nouvelle session DJ Matyo basée sur des reposts Souncloud</p><p>Tracklist</p><ul><li>Music Makes Me Happy ....... ( The Multi Choonage Adventure Mix ) ? https://soundcloud.com/dj-des-2009-1/music-make-me-happy-the-multi</li><li>Flakee + Darwin feat allison - dream surprise [31919812] https://soundcloud.com/allisonm/flakee-darwin-feat-allison?si=1c8338a0cf914cbbbff7a1ade761aa33</li><li>DJ Pulse shake that ass  (Dj Mix) [1451650675] https://soundcloud.com/djpulsepodcast/dj-pulse-shake-that-ass-dj-mix?si=f3b8b54ee31849d99501e2a8e08a1a6e</li><li>FREE DOWNLOAD silence denny remix [1256978329] https://soundcloud.com/deejay-denny-2/silence?si=88ec16ab9da847bc868c0f2efde18b93</li><li>HARDCORE LEGENDS OF GLORY 2022 DJ STE MAJOR MIX [1343595232] https://soundcloud.com/steven-major-106691550/hardcore-legends-of-glory-dj-ste-major-mix-2022?si=43e5a6c290bf4027a2373b108a34b787</li><li>Jowsey - Closing Time [1362617848] https://soundcloud.com/rewiredrecordsuk/jowsey-closing-time?si=e72685b5db5c4891bcaedebcea3a078d</li><li>Uproar Friday Session Feat JPS &amp; Big Stu [1460896900] https://soundcloud.com/uproar1/friday-sessions-with-jps-n-big-stu?si=f072e92a957148d59415e2b43354d66c</li><li>Podcast 100 (Part One) [1306342732] https://soundcloud.com/dj-murphy-4/podcast-100-part-one?si=77d904219cfb474cbc190cfc9c16fe33</li><li>24.7.22 [1310649904] https://soundcloud.com/41rossco/24722a?si=d2cd7d2c136c44f9a556af846b1565f9</li><li>DRIFT &amp; STOCKO - MY HOUSE (FREE DOWNLOAD) [1385315554] https://soundcloud.com/tarrondjdriftbennett/drift-stocko-my-house-free-download?si=6bba0c59a1014d1993bf34c6dd2cb771</li><li>M-Series - Side Effects (Bounce Assassins remix) - OUT NOW [1274439151] https://soundcloud.com/cheekytracks/side-effects-bounce-assassins?si=08930333608d4ed7befb19d15c728be7</li><li>Johnnie Zone - Rewired Session [1511722735] https://soundcloud.com/johnniezone/johnnie-zone-rewired-session?si=fa27a68948c844108f6ab894ce8ecaa0</li><li>Thank You For The Support 3 (Paradox &amp; Rocca Running Up That Hill) [1329668554] https://soundcloud.com/itssarah-itsbilly/new-one-duplicated-upload?si=9b50d827128f4900b5ab2822a96c970b</li><li>Podge - Celebrate The Summer Remix 2022 Clip [1284171448] https://soundcloud.com/dj-podge/podge-celebrate-the-summer-remix-2022-clip?si=85930ad7ed314cc0853aa0813241dede</li><li>DJ AMMO - T - HALLOWEEN SPECIAL 2022 - 182 BPM [1372111282] https://soundcloud.com/mcbouncin2/dj-ammo-t-halloween-special-2022-182-bpm?si=e3c152578b5f4256af5102e24247115f</li><li>Dmb Vs Gillies - Endless Journey (FREE DOWNLOAD) [1320215881] https://soundcloud.com/dj-gillies/dj-dmb-vs-dj-gillies-endless-journey?si=61302bd3c3b34f5a812696fb5747e33d</li><li>RyDOW - Freddy Went To Heaven [1381032742] https://soundcloud.com/popsoundz/rydow-freddy-went-to-heaven?si=5f582ab877344732bf8343c1cc4efc4c</li><li>Charlie D Better Of Alone Full Free Track [1327763383] https://soundcloud.com/charlie_d/charlie-d-better-of-alone-full-free-track?si=4b2055477e564d4f9e204c1bfc9b3206</li><li>Dmb &amp; Clenn - Its Over Now Remix [1349501872] https://soundcloud.com/thenewmonkey_official/dmb-clenn-its-over-now-remix?si=858ecddc8299473e9f1df05cc7d5b185</li><li>MURPHY BURST THE VIRUS VOL.6 [1373082583] https://soundcloud.com/chris-murphy-mixes/murphy-burst-the-virus-vol6?si=cc610a1ba77a47e3ba6f22cb92269076</li><li>SethroW - Front To Back [1348754974] https://soundcloud.com/dnzrecords/sethrow-front-to-back?si=b21ceafbddbb4408b73d0a17391594ab</li></ul><p>Cover credit : <a href="https://fr.pinterest.com/pin/313281717849022782/">Fatma</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live</link><guid>https://blog.darkwood.com/article/dj-matyo-live</guid><enclosure url="http://darkwood.com/media/articles/6810766999f4d540690660.jpg" /></item><item><title>Supercharge Your Job Search: Automate with MCP, Astra, Langflow and Arize</title><pubDate>Sun, 04 May 2025 17:40:25 +0000</pubDate><description><![CDATA[
Are you struggling to find the right job? Well, it&#039;s time to level up your job search with technology! Today, I&#039;m going to show you how to enhance your job search by building an MCP server and automating the entire process with cutting-edge tools like Astr...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6817a6897e26a085165114.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/Xy2mj1jbPp4?si=pmCcw0Dz4cl4nNhl" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Are you struggling to find the right job? Well, it's time to level up your job search with technology! Today, I'm going to show you how to enhance your job search by building an MCP server and automating the entire process with cutting-edge tools like Astra and Arize.</p><p>By the end of this post, you'll understand how to set up your own server to search for companies that align with your interests and even experiment with AI agents to make your search more efficient and tailored to your needs. Let's dive in! 🎯</p><h2>🏢 Using the &quot;Recherche d'Entreprise&quot; API</h2><p>The Recherche d'Entreprise API, offered by the French government, is an open-source tool you can leverage to gather data on thousands of businesses. By integrating this into your search, you can refine your results based on criteria like postal code, department, and region. 🌎</p><p>This API is an excellent resource for anyone who's in search of potential employers or clients. It's a fast and efficient way to access public business data. To get started, you can access the API <a href="https://recherche-entreprises.api.gouv.fr/openapi.json">here</a>. 🔗</p><h2>🤖 Why Use MCP for Job Searching?</h2><p>What is MCP (Model Context Protocol)? Simply put, MCP is an open protocol that turns traditional LLM (Large Language Models) chatbots into intelligent agents capable of performing specific tasks based on user input. By creating your own MCP server, you can prompt your IDE (Integrated Development Environment) to help with tasks like job searching while you code! How cool is that? 💡</p><p>In this step, you'll configure a simple MCP Server for Job Searching, which can handle requests from your job search queries. The beauty of MCP is that it works seamlessly with various tools to retrieve precise information about companies you're interested in. You can even specialize your searches to find businesses that match your specific criteria.</p><p>To set up your own MCP server, follow the step-by-de in this <a href="https://jolicode.com/blog/mcp-the-open-protocol-that-turns-llm-chatbots-into-intelligent-agents">tutorial from Jolicode</a>. 🔧</p><h2>🔧 Integrating Astra for Data Storage</h2><p>Once you've set up your MCP server, it's time to integrate AstraDB. AstraDB is a cloud-native database solution that allows you to easily store, manage, and query large datasets.</p><p>To make your searches even more efficient, you can vectorize your documents using Astra, so that each search query returns highly relevant results. All of the business data retrieved from the Recherche d'Entreprise API can be stored in AstraDB. 📊</p><p>To start using AstraDB, sign up <a href="https://www.datastax.com">here</a> and connect it with your MCP server. You'll need to add your Astra API keys to your project for it to work seamlessly.</p><h2>📈 Monitoring with Arize</h2><p>Once your MCP server is up and running with Astra, it's time to monitor the performance of your AI models using Arize. Arize is a monitoring platform designed for AI models, helping you track performance and improve your models over time. 🌟</p><p>Arize makes it easy to see how well your search models are performing, allowing you to adjust parameters and experiment with different AI agents. This is crucial to ensure that your search queries are being processed as accurately and efficiently as possible. 🔍</p><p>To sign up for Arize and start monitoring your models, visit <a href="https://dtsx.io/3GzL6hW">this link</a>. 📱</p><h2>🤖 Experimenting with Langflow for RAG Models</h2><p>Now, let's take it a ther by integrating Langflow. Langflow is a tool for building RAG (Retrieve, Augment, Generate) models, which allow you to combine the strengths of large language models (LLMs) with external data sources, like your Astra database.</p><p>With Langflow, you can create intelligent chatbots capable of answering specific queries based on your job search results. You can integrate it with the Astra database and Arize to track performance and improve accuracy.</p><p>Follow the <a href="https://dtsx.io/4lVtkWG">Langflow setup guide</a> to integrate it into your system. 🧑‍💻</p><h2>🏁 Putting It All Together</h2><p>At this point, you have:</p><ul><li>MCP Server to handle job search queries.</li><li>AstraDB to store and vectorize company data.</li><li>Arize to monitor and improve your AI models.</li><li>Langflow to create advanced RAG models for smarter, more efficient searches.</li></ul><p>All of these tools combined will supercharge your job search, allowing you to focus on high-priority companies and specific roles, while automating much of the data retrieval and analysis process. 🔄</p><h2>🧪 Checkout the source code</h2><p>You can checkout the source code of this article on Github <a href="https://github.com/matyo91/recherche-entreprise-mcp-server">here</a></p><h3>🚀 Want to build your own workflows?</h3><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Check out my Bonzai automation course</a></div><h2>Let's take your career to the next level with technology! 🚀</h2><p>Feel free to reach out for any questions, and don't forget to share this with friends who might benefit from automating their job search. Happy vibe coding! 🎉</p><h2>Ressources</h2><ul><li>API Recherche d’Entreprises : https://www.data.gouv.fr/fr/dataservices/api-recherche-dentreprises</li><li>rag-playground in Python : https://github.com/acantarero/rag-playground</li><li>Real-time document Q&amp;A using Pulsar, Cassandra, and langchain : https://github.com/acantarero/wikipedia_demo</li><li>📨 Build an Email-Powered AI Agent (using Langflow and Twilio) : https://www.youtube.com/watch?v=Nkek6TCCUzE</li><li>Arize AI : https://github.com/Arize-ai</li><li>Phoenix : https://github.com/Arize-ai/phoenix</li><li>Arize Python SDK Reference : https://arize-client-python.readthedocs.io/en/latest/</li><li>Create an experiment with Arize : https://github.com/datastaxdevs/build_accurate_ai_langflow_arize/blob/main/langflow_arize.ipynb</li><li>How to Build a Real-World RAG Chatbot That Actually Works (N8N + Vectorize) : https://www.youtube.com/watch?v=o6QHoUXXnaM</li><li>How To Get The Most Out Of Vibe Coding | Startup School : https://www.youtube.com/watch?v=BJjsfNO5JTo</li><li>Background credit Slidebean : https://unsplash.com/photos/turned-on-pendant-lamps-TpGIpUF67po</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/supercharge-your-job-search-automate-with-mcp-astra-langflow-and-arize</link><guid>https://blog.darkwood.com/article/supercharge-your-job-search-automate-with-mcp-astra-langflow-and-arize</guid><enclosure url="http://darkwood.com/media/articles/6817a6897e26a085165114.png" /></item><item><title>DJ Matyo Live</title><pubDate>Tue, 06 May 2025 07:18:50 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · 2025-06-05 DJ Matyo Live
Nouvelle session DJ Matyo basée sur des reposts Souncloud
Tracklist

DJ AMMO T AKA MC BOUNCIN - OFFICIAL · DJ AMMO - T - HALLOWEEN SPECIAL 2022 - 182 BPM https://soundcloud.com/mcbouncin2/dj-ammo-t-hal...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6819b7da24a8c365975616.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/HUpKKcS-5UY?si=joXuQ83ZdigTL4tz" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2090902023&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/2025-06-05-dj-matyo-live" title="2025-06-05 DJ Matyo Live" target="_blank" style="color: #cccccc; text-decoration: none;">2025-06-05 DJ Matyo Live</a></div></div><p>Nouvelle session DJ Matyo basée sur des reposts Souncloud</p><p>Tracklist</p><ul><li>DJ AMMO T AKA MC BOUNCIN - OFFICIAL · DJ AMMO - T - HALLOWEEN SPECIAL 2022 - 182 BPM https://soundcloud.com/mcbouncin2/dj-ammo-t-halloween-special-2022-182-bpm</li><li>Dj Gillies &amp; Dj Enemy · Dj Gillies Vs Dj Enemy - North East Nailers https://soundcloud.com/dj-gillies/dj-gillies-vs-dj-enemy-north-east-nailers</li><li>Dj Wilson (official) · Uproar Wilson Alectrona Takeover(featuring james ross and mc double g) https://soundcloud.com/steven-j-wilson-2/uproar-wilson-alectrona-takeoverfeaturing-james-ross-and-mc-double-g</li><li>DJ LEE-C - Detonation · DJ LEE-C 1000K FOLLOWERS VINYL MIX https://soundcloud.com/dj-lee-c-1/dj-lee-c-1000k-followers-vinyl-mix</li><li>Jupiter · Jupiter &amp; rydow - catch me (remix) free download https://soundcloud.com/tranzfuzion-productions/jupiter-rydow-catch-me-remix-free-download</li><li>Matty Owers · DJ MATTY O &amp; MC DOUBLE M - ELYSIUM 26/11/22 https://soundcloud.com/djmatty-o/mc-double-m-elysium-261122</li><li>https://www.mini-mammoth.co.uk/ · Jack Gibson - Intoxicated https://soundcloud.com/minimammothofficial/jack-gibson-intoxicated</li><li>Dj Alectrona · DJ Alectrona, JGS &amp; INTENT - All I Want For Christmas Is You (MP3).mp3(sample) https://soundcloud.com/michelle-hoey-1/dj-alectrona-jgs-intent-all-i</li><li>makina radji/dj wkd · Dj (1)bouncy makina https://soundcloud.com/deanr4/dj-1bouncy-makina</li><li>DJ Chud · DJ Chud DJ Vida - MC Crazy T https://soundcloud.com/user-160683401/dj-chud-dj-vida-mc-crazy-t</li><li>Synthetik · Synthetik - Lookin Good https://soundcloud.com/synthetikproductions/synthetik-lookin-good</li><li>DJ PARADOX · LET ME HEAR THE MAKINA - VOL 1 https://soundcloud.com/djparadox79/let-me-hear-the-makina-vol-1</li><li>DJ STEVIE D · In The Mix Makina December 2022 https://soundcloud.com/steven-douglas-651158229/01-rec-2022-12-05</li><li>Daz Rapid · DJ'S CHUD &amp; VIDA - MC COBRA &amp; DAZ RAPID https://soundcloud.com/daz-rapid-1/djs-chud-vida-mc-cobra-daz-rapid</li><li>SHUGG · The New Monkey - Shugstylerz, Mc Banks &amp; Mc Gav B - Facebook Live 07-06-22 https://soundcloud.com/shugg_official/the-new-monkey-shugstylerz-mc</li><li>Trinitystyle · Dj Erupt Mc Banks Halloween Special 2022 Vol 1 https://soundcloud.com/trinitystyle/dj-erupt-mc-banks-halloween</li><li>DK Productions - Daz King · DK Productions - Chandelier - OUT NOW ON EXCITE DIGITAL https://soundcloud.com/dk-productions-music/dk-productions-chandelier-coming-to-excite-digital-24062022</li><li>Double Naughty Events - DJ Chris Smith · Makina @ the Moor - Oct '22 / Rush B2B Selector C - Blast Daz Rapid https://soundcloud.com/doublenaughtyevents/makina-the-moor-oct-22-rush-b2b-selector-c-blast-daz-rapid</li></ul><p>Cover credit : <a href="https://ar.pinterest.com/pin/26669822787359899/">Zepeto People</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live-3</link><guid>https://blog.darkwood.com/article/dj-matyo-live-3</guid><enclosure url="http://darkwood.com/media/articles/6819b7da24a8c365975616.jpg" /></item><item><title>Automating Gmail and Google Calendar with PHP Agents ?⚡</title><pubDate>Sun, 11 May 2025 21:21:04 +0000</pubDate><description><![CDATA[
Want to read your unread Gmail emails and book a meeting slot to reply — all while coding? In this article, I&#039;ll show you how I automated that entire process using a custom MCP server in PHP, connected to Gmail and Google Calendar through Composio, and wra...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/682114c07a2de995683586.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/nJTKL0k_QRw?si=LjcrGer8h2NV9Pk6" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Want to read your unread Gmail emails and book a meeting slot to reply — all while coding? In this article, I'll show you how I automated that entire process using a custom MCP server in PHP, connected to Gmail and Google Calendar through Composio, and wrapped it all up with an AI agent using Uniflow and Neuron AI.</p><p>Let's dive into the full stack! 🧠✨</p><h2>Build a PHP MCP Server ⚙️</h2><p>First, I created an MCP server using the excellent <a href="https://github.com/php-mcp/server">php-mcp/server</a> package. This gave me a production-ready, flexible setup with support for annotations, dependency injection, custom transports (HTTP, STDIO, etc.), and advanced logging.</p><pre><code class="language-bash">composer create-project symfony/skeleton
composer require php-mcp/server
</code></pre><p>Then I added a basic <code>Tool</code> (e.g. <code>Adder</code>) to test interactions with MCP clients like Cursor or LangChain.</p><h2>Set Up Nix Instead of Docker 🐧</h2><p>To ensure a clean and reproducible environment, I used <a href="https://nixos.org/">Nix</a> instead of Docker. With the <a href="https://github.com/phploop/nix-chain">nix-chain template</a>, I got PHP, Composer, Symfony CLI, PHPStan, PHPUnit and more preconfigured.</p><pre><code class="language-bash">make nix
</code></pre><p>This keeps my environment declarative and lightweight, perfect for sharing or onboarding others.</p><h2>Connect Gmail &amp; Google Calendar via Composio 📧📅</h2><p>Composio is like Zapier for devs. I plugged it into my MCP server using their PHP SDK (inspired by the <a href="https://github.com/ComposioHQ/composio-js">official JS SDK</a>) and added tools like:</p><ul><li><code>GMAIL_FETCH_EMAILS</code></li><li><code>GMAIL_SEND_EMAIL</code></li><li><code>GOOGLECALENDAR_CREATE_EVENT</code></li><li><code>GOOGLECALENDAR_FIND_FREE_SLOTS</code></li></ul><p>Using the CLI:</p><pre><code class="language-bash">php bin/console app:generate-tools \
  --entityId default \
  --action GMAIL_FETCH_EMAILS \
  --action GOOGLECALENDAR_FIND_FREE_SLOTS \
  ...
</code></pre><p>Now, my PHP server could dynamically fetch actions based on API keys and entity IDs.</p><h2>Build an AI Agent with Neuron AI 🧠</h2><p>Next, I wired everything up with <a href="https://www.neuron-ai.dev">Neuron AI</a>, which lets you create <strong>AI agents</strong> that can call MCP tools directly. My agent receives a prompt like:</p><blockquote><p>&quot;Please find my unread important emails and schedule a calendar slot to respond.&quot;</p></blockquote><p>…and autonomously triggers the Gmail and Calendar tools.</p><h2>Run the Workflow with Uniflow 🛠️</h2><p>To complete the workflow, I used <a href="https://uniflow.com">Uniflow</a> and its PHP Client to execute the agent's logic:</p><ul><li>Read important emails</li><li>Summarize them</li><li>Book a free time slot on Google Calendar</li></ul><p>Uniflow's PHP SDK makes it easy to plug this into a broader automation system or SaaS.</p><h2>Why PHP? 💡</h2><p>While most Composio and LLM tooling is JS- or Python-centric, I wanted to prove we can do full agent-based automation in PHP — and it works beautifully!</p><p>The result: an AI agent that reads your inbox, prioritizes what matters, and gives you back your time. ❤️</p><h2>Bonus Tips &amp; Resources 💡</h2><ul><li>Use <code>.cursor/mcp.json</code> to declare your MCP tools project by project</li><li>Switch from Docker to Nix for OS-level reproducibility</li><li>Explore <a href="https://www.youtube.com/watch?v=L4Pe8MMhgsg">Langflow's</a> Vibe Coding Tips for building smarter workflows</li><li>Observe your agent via <a href="https://inspector.dev">inspector.dev</a> for debugging</li></ul><h2>🧪 Checkout the source code</h2><p>You can checkout the source code of this article on Github <a href="https://github.com/matyo91/composio-php-mcp-server">here</a></p><h2>👋 Ready to Automate Your Workflows?</h2><p>If this post inspired you, and you want help automating your own processes (email, marketing, scheduling, scraping...), I've got something for you!</p><p>👉 <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process"><strong>Click here to get my personal help</strong></a> — and let's start building together. 🚀</p><h2>Resources</h2><ul><li>Top 10 VIBE CODING TIPS for Agent-Driven Workflows ? https://www.youtube.com/watch?v=L4Pe8MMhgsg</li><li>js2php : https://github.com/jakubkulhan/js2php</li><li>background credit Nastuh Abootalebi : https://unsplash.com/fr/photos/couloir-entre-les-portes-a-panneaux-de-verre-yWwob8kwOCk</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents</link><guid>https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents</guid><enclosure url="http://darkwood.com/media/articles/682114c07a2de995683586.png" /></item><item><title>DJ Matyo Live DJ Cotts selection</title><pubDate>Tue, 13 May 2025 07:08:27 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · DJ Matyo Live DJ Cotts selection
Nouvelle session DJ Matyo basée sur le live mix de DJ Cotts
Tracklist

Ravegenix - Keep Me Up All Night [Future Breakz Records] https://www.beatport.com/release/keep...
Van Heden x Deepaim - El...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6822efeb794b4799110976.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/nrYYvswKMrE?si=rlKhN2F0QQ-NgMx5" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2097827580&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/1ac503ff-6545-4e2e-be3d-4fbf291298de" title="DJ Matyo Live DJ Cotts selection" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo Live DJ Cotts selection</a></div></div><p>Nouvelle session DJ Matyo basée sur <a href="https://www.youtube.com/watch?v=t8SsBeKZVqs">le live mix de DJ Cotts</a></p><p>Tracklist</p><ul><li>Ravegenix - Keep Me Up All Night [Future Breakz Records] <a href="https://www.beatport.com/release/keep-me-up-all-night/4819942">https://www.beatport.com/release/keep...</a></li><li>Van Heden x Deepaim - El Bangero [Bionic Bear] <a href="https://www.beatport.com/release/el-bangero/4618555">https://www.beatport.com/release/el-b...</a></li><li>Gammer, Dougal &amp; Echos - Music Never Stops [Dancing Dead] <a href="https://www.beatport.com/release/ravers-in-harmony/4847660">https://www.beatport.com/release/rave...</a></li><li>Pie Star - Dreaming Pie Star - Dreaming [Electric Fox] <a href="https://www.beatport.com/release/dreaming/4996208">https://www.beatport.com/release/drea...</a></li><li>Da Tweekaz &amp; Destructive Tendencies - We Are Fighters (Joey Riot Remix) [Electric Fox] <a href="https://www.beatport.com/release/we-are-fighters-joey-riot-remix/4606936">https://www.beatport.com/release/we-a...</a></li><li>Getty - Rave Simulator [Hardcore Tano*C] <a href="https://tanoc.bandcamp.com/album/rave-simulator">https://tanoc.bandcamp.com/album/rave...</a></li><li>JTS &amp; Technikore - With You [OneSeventy] <a href="https://www.beatport.com/release/with-you/4601384">https://www.beatport.com/release/with...</a></li><li>Pokkun - Gotta Have Your Love [OneSeventy] <a href="https://www.beatport.com/release/gotta-have-your-love/4485861">https://www.beatport.com/release/gott...</a></li><li>Jakka-B &amp; Mike Reverie ft. Lula Brooks - All That I Need [Barong Family] <a href="https://www.beatport.com/release/all-that-i-need-extended-mix/4994041">https://www.beatport.com/release/all-...</a></li><li>DJ Saria - Come ’n Get Some (JAKAZiD Remix) [Shin Sekai] <a href="https://ssekainet.bandcamp.com/album/at-my-core">https://ssekainet.bandcamp.com/album/...</a></li><li>Technikore &amp; Weaver - Can’t Stop Us Now [OneSeventy] <a href="https://www.beatport.com/release/cant-stop-us-now/4938214">https://www.beatport.com/release/cant...</a></li><li>Getty - Void [DROP FREVKER] <a href="https://getty8getty.bandcamp.com/album/void">https://getty8getty.bandcamp.com/albu...</a></li><li>Jakka-B - I Can’t Take It [Bonkers] <a href="https://www.beatport.com/release/i-cant-take-it/4920138">https://www.beatport.com/release/i-ca...</a></li><li>No Hero &amp; Quickdrop - Guide You [Playbox Music] <a href="https://www.beatport.com/release/guide-you-extended-mix/4895418">https://www.beatport.com/release/guid...</a></li><li>Joey Riot &amp; Matty Matrix - Acid Rocker [Electric Fox] <a href="https://www.beatport.com/release/acid-rocker/4774431">https://www.beatport.com/release/acid...</a></li><li>DJ Saria &amp; JAKAZiD - Something In The Music [Shin Sekai] <a href="https://ssekainet.bandcamp.com/album/at-my-core">https://ssekainet.bandcamp.com/album/...</a></li><li>Technikore feat Lisa Abbott - My Intention (HTID Mix) [OneSeventy] <a href="https://www.beatport.com/release/my-intention/4968575">https://www.beatport.com/release/my-i...</a></li><li>Technikore x No Hero - Walk Away [OneSeventy] <a href="https://www.beatport.com/release/walk-away/4778237">https://www.beatport.com/release/walk...</a></li><li>NextJen - Red Flags [OneSeventy] <a href="https://www.beatport.com/release/red-flags/4563168">https://www.beatport.com/release/red-...</a></li><li>JTS - Only A Dream [OneSeventy] <a href="https://www.beatport.com/release/only-a-dream/4926516">https://www.beatport.com/release/only...</a></li><li>Fracus feat. Fraz - Save Our Love (2025 Remix) [Music Blocks] <a href="https://fracus.bandcamp.com/album/save-our-love-2025-remix">https://fracus.bandcamp.com/album/sav...</a></li><li>Akagitune - Breaking The Rules [Free Release] <a href="https://soundcloud.com/akagitune/akagitune-breaking-the-rules">akagitune-breaking-the-rules</a></li><li>Weaver &amp; S3RL - Redlining [EMFA Music] <a href="https://www.beatport.com/release/redlining-dj-edit/4536177">https://www.beatport.com/release/redl...</a></li></ul><p>Cover credit : <a href="https://ar.pinterest.com/pin/26669822787359899/">Zepeto People</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live-dj-cotts-selection</link><guid>https://blog.darkwood.com/article/dj-matyo-live-dj-cotts-selection</guid><enclosure url="http://darkwood.com/media/articles/6822efeb794b4799110976.jpg" /></item><item><title>Automatically Generate Custom Ghibli-Style YouTube Thumbnails with PHP and AI</title><pubDate>Mon, 19 May 2025 06:03:55 +0000</pubDate><description><![CDATA[
Have you ever dreamed of creating stunning YouTube thumbnails in the style of Studio Ghibli, like Sam Altman did with his X profile picture? 🎨 Good news: I&#039;ve built an open-source MCP (Model Control Protocol) server in PHP that allows you to generate your...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/682ac9cb8bea4913257352.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/SNMSRDZvQBg?si=5mUKZyXiFP9yq_pV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Have you ever dreamed of creating stunning YouTube thumbnails in the style of Studio Ghibli, like <a href="https://x.com/sama">Sam Altman</a> did with his X profile picture? 🎨 Good news: I've built an open-source MCP (Model Control Protocol) server in PHP that allows you to generate your own custom Ghibli-style thumbnails automatically using your photos and AI models via Replicate. ✨</p><h2>What You Need to Know 📊</h2><p>This project uses a combination of:</p><ul><li>Replicate API (for model training and image generation)</li><li><a href="https://github.com/php-llm/mcp-sdk">php-llm/mcp-sdk</a> for MCP tool integration</li><li>Custom tools built with <code>#[AsTool]</code> annotations</li><li>Flux LORA trainer to fine-tune a model with your own images</li><li>Studio Ghibli style model to stylize the result</li></ul><h2>Workflow Overview 🔧</h2><ol><li>You upload 5–10 personal images</li><li>We train a custom LORA model on Replicate using <a href="https://replicate.com/ostris/flux-dev-lora-trainer/train">Flux</a></li><li>You provide a prompt like <code>ME as a cyberpunk samurai</code></li><li>We generate an image using your model and the <code>ME</code> token</li><li>We pipe the result into the <a href="https://replicate.com/karanchawla/studio-ghibli">Studio Ghibli model</a></li><li>Voilà! You receive your cinematic thumbnail 📷</li></ol><h2>Why Not Hugging Face? ❓</h2><p>I explored the Hugging Face route too (<a href="https://medium.com/@heyamit10/hugging-face-vs-replicate-a-hands-on-comparison-for-data-scientists-460cb214f548">comparison here</a>), but ultimately chose Replicate for its simplicity and API integration. I'm a PHP dev, not a full-time ML engineer, so the ability to plug and play was key. 💻</p><h2>Try It Yourself 🚀</h2><p>You can explore the open-source code and run your own version locally or on the cloud:</p><ul><li><a href="https://github.com/matyo91/thumbnail-mcp">Thumbnail MCP - GitHub</a></li><li><a href="https://blog.darkwood.com/article/automatise-la-creation-de-vignettes-youtube">How I first automated thumbnails (blog post)</a></li></ul><h2>What's Next? 📖</h2><p>I'll be integrating this into <a href="https://uniflow.io">Uniflow.io</a> to allow automated thumbnail creation as part of your video production pipeline. 🦾 You could use this in a flow that:</p><ul><li>Uploads video</li><li>Generates a thumbnail</li><li>Transcribes your video</li><li>Publishes on YouTube</li></ul><h2>Resources 📚</h2><ul><li><a href="https://replicate.com/ostris/flux-dev-lora-trainer">Flux LORA trainer</a></li><li><a href="https://replicate.com/karanchawla/studio-ghibli">Ghibli style image generator</a></li><li><a href="https://github.com/php-llm/ecosystem">PHP AI &amp; LLM Ecosystem</a></li><li><a href="https://refer.tella.com/mathieu-ledru">Tella - screen recorder I used for the video</a></li></ul><h2>Need Help Automating Your Creative Workflow? 🤖</h2><p>I offer 30-minute coaching sessions to help creators like you automate your processes, whether it's for thumbnail generation, video publishing, or broader workflows. <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Book your free session here</a> 📞</p><p>Thanks for reading! 👋</p>
]]></content:encoded><link>https://blog.darkwood.com/article/automatically-generate-custom-ghibli-style-youtube-thumbnails-with-php-and-ai</link><guid>https://blog.darkwood.com/article/automatically-generate-custom-ghibli-style-youtube-thumbnails-with-php-and-ai</guid><enclosure url="http://darkwood.com/media/articles/682ac9cb8bea4913257352.png" /></item><item><title>🇪🇺 DJ Matyo Live special Eurovision 2025 🌟</title><pubDate>Tue, 20 May 2025 07:24:39 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · ?? DJ Matyo Live special Eurovision 2025 ?
Nouvelle session DJ Matyo sur l&#039;eurovision 2025
Tracklist

JJ – Wasted Love (LIVE) | Austria 🇦🇹 | Grand Final | Winner of Eurovision 2025
Tommy Cash - Espresso Macchiato (LIVE) | Eston...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/682c2e379ea85968728994.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/WU3Ex7CzhZc?si=Jg0aAIME_xCbUyYK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2098913505&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/dj-matyo-live-special-eurovision-2025" title="?? DJ Matyo Live special Eurovision 2025 ?" target="_blank" style="color: #cccccc; text-decoration: none;">?? DJ Matyo Live special Eurovision 2025 ?</a></div></div><p>Nouvelle session DJ Matyo sur <a href="https://www.youtube.com/watch?v=onOex2WXjbA&amp;list=PLmWYEDTNOGULVWCDVT-FmL2uQLzNy6PVq">l'eurovision 2025</a></p><p>Tracklist</p><ul><li>JJ – Wasted Love (LIVE) | Austria 🇦🇹 | Grand Final | Winner of Eurovision 2025</li><li>Tommy Cash - Espresso Macchiato (LIVE) | Estonia 🇪🇪 | Grand Final | Eurovision 2025</li><li>Melody - ESA DIVA (LIVE) | Spain 🇪🇸 | Grand Final | Eurovision 2025</li><li>Abor &amp; Tynna – Baller (LIVE) | Germany 🇩🇪 | Grand Final | Eurovision 2025</li><li>Käärijä &amp; Baby Lasagna - #eurodab at the Grand Final | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Erika Vikman – ICH KOMME (LIVE) | Finland 🇫🇮 | Grand Final | Eurovision 2025</li><li>KAJ - Bara Bada Bastu (LIVE) | Sweden 🇸🇪 | Grand Final | Eurovision 2025</li><li>Klavdia – Asteromáta (LIVE) | Greece 🇬🇷 | Grand Final | Eurovision 2025</li><li>Public Vote - The Televote Results of Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Justyna Steczkowska - GAJA (LIVE) | Poland 🇵🇱 | Grand Final | Eurovision 2025</li><li>Lucio Corsi - Volevo Essere Un Duro (LIVE) | Italy 🇮🇹 | Grand Final | Eurovision 2025</li><li>Nemo - Unexplainable at the Grand Final | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Winner's Performance: JJ - Wasted Love ✨ | Austria 🇦🇹 | Eurovision 2025</li><li>Ziferblat - Bird of Pray (LIVE) | Ukraine 🇺🇦 | Grand Final | Eurovision 2025</li><li>Shkodra Elektronike - Zjerm (LIVE) | Albania 🇦🇱 | Grand Final | Eurovision 2025</li><li>Louane – maman (LIVE) | France 🇫🇷 | Grand Final | Eurovision 2025</li><li>Yuval Raphael – New Day Will Rise (LIVE) | Israel 🇮🇱 | Grand Final | Eurovision 2025</li><li>VÆB - RÓA (LIVE) | Iceland 🇮🇸 | Grand Final | Eurovision 2025</li><li>Remember Monday – What The Hell Just Happened? | United Kingdom 🇬🇧 | Grand Final | Eurovision 2025</li><li>Kyle Alessandro - Lighter (LIVE) | Norway 🇳🇴 | Grand Final | Eurovision 2025</li><li>Nemo - The Code - Opening Act at the Grand Final | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Zoë Më - Voyage (LIVE) | Switzerland 🇨🇭 | Grand Final | Eurovision 2025</li><li>Tautumeitas – Bur Man Laimi (LIVE) | Latvia 🇱🇻 | Grand Final | Eurovision 2025</li><li>Claude - C'est La Vie (LIVE) | Netherlands 🇳🇱 | Grand Final | Eurovision 2025</li><li>PARG – SURVIVOR (LIVE) | Armenia 🇦🇲 | Grand Final | Eurovision 2025</li><li>Laura Thorn - La Poupée Monte Le Son (LIVE) | Luxembourg 🇱🇺 | Grand Final | Eurovision 2025</li><li>Miriana Conte – SERVING (LIVE) | Malta 🇲🇹 | Grand Final | Eurovision 2025</li><li>NAPA - Deslocado (LIVE) | Portugal 🇵🇹 | Grand Final | Eurovision 2025</li><li>Sissal – Hallucination (LIVE) | Denmark 🇩🇰 | Grand Final | Eurovision 2025</li><li>Katarsis – Tavo Akys (LIVE) | Lithuania 🇱🇹 | Grand Final | Eurovision 2025</li><li>Gabry Ponte - Tutta L'Italia (LIVE) | San Marino 🇸🇲 | Grand Final | Eurovision 2025</li><li>Grand Final recap | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Switzerland's Eurovision Legacy at the Grand Final | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Fragile Goods at the Grand Final | Eurovision 2025 | #UnitedByMusic ​🇨🇭</li><li>Sandra Studer and Michelle Hunziker - Eurovision Dream at the Grand Final | Eurovision 2025​ 🇨🇭</li></ul><p>Inscrit toi à Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/969188782346297629/">EasyFR</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live-special-eurovision-2025</link><guid>https://blog.darkwood.com/article/dj-matyo-live-special-eurovision-2025</guid><enclosure url="http://darkwood.com/media/articles/682c2e379ea85968728994.jpg" /></item><item><title>🚀 Sylius Days 2025: What We Learned from the Front Lines of eCommerce Innovation</title><pubDate>Fri, 23 May 2025 05:21:09 +0000</pubDate><description><![CDATA[Sylius Days 2025 has just wrapped up — and what a lineup! 🎉 From AI to green performance, automation to internationalization, this year’s conference was a whirlwind of technical insights and actionable ideas for developers, product owners, and digital comme...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/683005c6081ef934643139.png" /></p><p>Sylius Days 2025 has just wrapped up — and what a lineup! 🎉 From AI to green performance, automation to internationalization, this year’s conference was a whirlwind of technical insights and actionable ideas for developers, product owners, and digital commerce leaders alike. Let’s break down the highlights from each speaker so you can catch up or revisit what matters most.</p><h2>🤖 AI Meets Sylius — Real Projects, Real Impact</h2><p>🎤 Sabrine Ferchichi &amp; Alexandre Haroutunian (ACSEO) : <a href="https://www.linkedin.com/company/acseo/">LinkedIn - ACSEO</a><br />
AI is no longer a buzzword — it's here, it’s practical, and it’s being deployed in Sylius! Alexandre and Sabrine walked us through concrete use cases showing how AI boosts automation, personalizes experiences, and optimizes performance in eCommerce setups. From concept to deployment, their talk served as a blueprint for AI-native Sylius projects. 🧠💡</p><p><strong>Revolutionizing B2B E-Commerce with AI: ACSEO's Clara Assistant for Sylius</strong></p><p>At the SyliusCon stage, ACSEO, a French digital agency with 15 years of experience, unveiled an ambitious AI integration into Sylius that is set to transform B2B e-commerce workflows. With Alexandre, the Project Director, and Sabrine, Lead Sylius Developer, at the helm, their talk explored how conversational AI can elevate user experience and drive sales by simplifying and personalizing the purchasing process.</p><p><strong>From Chaos to Clarity: The Problem Statement</strong></p><p>ACSEO painted a relatable picture: late-night bar orders scribbled on paper, fragmented messages sent to sales reps, and manual data entry into complex ERP systems. This traditional workflow is error-prone and time-consuming. The challenge was clear: streamline this chaos into a cohesive, intelligent order management system.</p><p><strong>Meet Clara: The AI-Powered Assistant</strong></p><p>Enter Clara, a conversational AI assistant that interfaces directly with Sylius via API. Clara recognizes customers by phone number, remembers order history, custom pricing, and suggests products based on stock and promotions. Through WhatsApp, users simply chat their needs—&quot;3 cases of Coca-Cola&quot;—and Clara understands context, auto-fills carts, and guides users through to checkout.</p><p>Key features include:</p><ul><li><strong>Natural language processing</strong> for order input via text, voice, or image (OCR).</li><li><strong>Product recommendations</strong> based on purchase history and promotions.</li><li><strong>Magic link authentication</strong> for passwordless login.</li><li><strong>Custom business logic</strong>, including price visibility controls and ERP synchronization.</li></ul><p><strong>Under the Hood: Technology and Implementation</strong></p><p>Clara uses OpenAI for natural language understanding and integrates Sylius APIs for cart and order management. The AI module includes prompt engineering for tailored conversations and blocks to prevent hallucinations or inappropriate responses. Importantly, all interactions are logged and overseen by human sales reps, maintaining accountability.</p><p>The AI model, affectionately dubbed &quot;Tino,&quot; is designed to be adaptable. It handles speech-to-text, OCR, and fetches data from the ERP in real time. Security and data privacy considerations are addressed through contractual agreements in the B2B context, with plans to explore GDPR-compliant local models in the future.</p><p><strong>Real-World Impact</strong></p><p>ACSEO's implementation of Clara has already shown impressive results. In less than a month post-launch, 50% of orders were digitalized for a major distributor. Implementation timelines have dramatically shortened—from a year for the first client to less than a day for new distributors using the same ERP.</p><p><strong>Key Takeaways for E-Commerce Innovators</strong></p><ul><li><strong>AI as a UX Interface</strong>: Clara shifts the paradigm from web navigation to conversation-driven commerce.</li><li><strong>Sylius API Power</strong>: Its flexibility enables deep customization and seamless AI integration.</li><li><strong>Scalability</strong>: Once integrated with a central ERP, new distributors can onboard rapidly.</li><li><strong>Practical AI</strong>: This isn't futuristic fluff—it's a working solution delivering measurable value today.</li></ul><p>For forward-thinking merchants and e-commerce leaders, ACSEO's work is a compelling blueprint. It demonstrates how even small teams can leverage AI to revolutionize customer interactions and operational efficiency. With Sylius as the foundation, Clara proves that smart commerce is not just for tech giants anymore.</p><h2>🌍 Translation Without Pain</h2><p>🎤 Mathieu Santostefano : <a href="https://www.linkedin.com/in/msantostefano/">LinkedIn</a><br />
Tired of redeploying your app just to fix a typo in a translation? Mathieu showed us how to streamline UI translations in Sylius using Symfony’s translation tools. Better yet, he offered strategies for involving non-tech translators — meaning faster, smoother content localization across the board. 🗺️💬</p><p><strong>Mastering UI Translation in Sylius: Best Practices and Tools</strong></p><p>At SyliusCon, Mathieu from SensioLabs, a Symfony core team member, shared an essential talk on managing UI translations in Sylius applications. With a deep dive into standards, workflows, and Symfony-powered tools, this session demystified the often-overlooked but crucial domain of translating static and dynamic content.</p><p><strong>Dynamic vs. Static Content in Sylius</strong></p><p>Sylius already provides solid language support for dynamic content through its admin panel. Product names, descriptions, and meta-data can be localized per channel and language. However, translating static UI elements—buttons, labels, error messages, etc.—requires a different strategy. These reside in translation files, which aren’t editable via the UI.</p><p><strong>Core Translation Concepts</strong></p><p>Mathieu clarified key concepts using standard numeronyms:</p><ul><li><strong>T9n</strong>: Translation (converting text from source to target language)</li><li><strong>I18n</strong>: Internationalization (designing software to be locale-adaptable)</li><li><strong>L10n</strong>: Localization (adapting software for a specific locale)</li><li><strong>G11n</strong>: Globalization (combining I18n and L10n)</li></ul><p><strong>Translation Standards and Formats</strong></p><p>The industry-standard file format for translations is XLIFF (XML Localization Interchange File Format), particularly versions 1.2 and 2.0. XLIFF provides structured metadata, supports multiple locales, and indicates translation statuses (e.g., fuzzy, deprecated).</p><p>For message formatting, Mathieu recommended the ICU MessageFormat. It allows for advanced pluralization, gender handling, and contextual variations, making it ideal for diverse audiences.</p><p><strong>Workflow Optimization with TMS Tools</strong></p><p>To streamline translation workflows, Mathieu advocates using a Translation Management System (TMS) like Localazy, Crowdin, or Phrase. These tools integrate with Symfony via official providers, enabling:</p><ul><li>Automatic extraction of translation keys</li><li>Syncing to and from TMS via CLI</li><li>Collaborative, UI-based translation editing</li></ul><p><strong>Developer and Translator Roles</strong></p><p>Mathieu outlined clear roles:</p><ul><li><strong>Developers</strong>: Define naming conventions, extract keys using Symfony CLI, avoid hardcoding static text.</li><li><strong>Translators</strong>: Use the TMS to translate and validate content.</li><li><strong>Product owners/QAs</strong>: Monitor and fine-tune translations across environments.</li></ul><p><strong>Best Practices for Seamless Integration</strong></p><ol><li><strong>Avoid direct editing</strong> of XLIFF/YAML files.</li><li><strong>Centralize static content</strong> with translation keys.</li><li><strong>Automate key extraction</strong> using Symfony’s <code>translation:extract</code>.</li><li><strong>Push/pull translations</strong> with <code>translation:push</code> and <code>translation:pull</code>.</li><li><strong>Use identity translator</strong> in test environments to avoid brittle tests.</li><li><strong>Leverage Symfony UX Translator</strong> to expose translations to JavaScript.</li><li><strong>Optimize cache management</strong> to prevent unnecessary invalidations.</li></ol><p><strong>Pro Tips</strong></p><ul><li>Use libraries like <code>libphonenumber</code> for handling international phone formats.</li><li>Automate translation updates via Symfony Scheduler or Synolia plugin.</li><li>Isolate translation cache for more efficient cache invalidation.</li></ul><p><strong>Conclusion</strong></p><p>Mathieu’s talk provided a masterclass in making translation a first-class citizen in Sylius applications. By aligning roles, leveraging the right tools, and embracing automation, teams can ensure accurate, localized experiences for users worldwide—without the headaches.</p><p>Forward-thinking e-commerce teams that embrace this workflow can eliminate bottlenecks, reduce errors, and scale effortlessly across markets. Translation, when done right, becomes a superpower.</p><h2>💳 Stripe Integration Demystified</h2><p>🎤 Francis Hilaire : <a href="https://www.linkedin.com/in/francis-hilaire-28317aa3/">LinkedIn</a><br />
Francis went deep under the hood of Sylius’ integration with Stripe. The highlight? Payment Request support via Flux-SE/SyliusStripePlugin. His session laid out the technical architecture and the long-term benefits for stores that want fast, secure, and modern payment solutions. ⚙️💸</p><p><strong>Modernizing E-Commerce Payments: Sylius Payment Request with Stripe Integration</strong></p><p>At SyliusCon, Francis Hilaire, a core contributor to the Sylius ecosystem and developer at Harman International, delivered an insightful presentation on the new Payment Request architecture in Sylius and its integration with Stripe. This talk outlined a robust, API-first solution for handling payments—especially vital for headless commerce scenarios.</p><p><strong>The Problem with Payum</strong></p><p>Traditional Sylius payments relied on Payum, a library effective for monolithic applications but limiting for headless architectures. Payum's UI dependency and rigid redirection flow made it unsuitable for modern, API-driven e-commerce setups.</p><p><strong>The Vision: Sylius Payment Request</strong></p><p>Sylius Payment Request introduces a flexible, message-based architecture for payments. Key benefits include:</p><ul><li><strong>Headless support</strong>: Fully decoupled from UI, enabling seamless integration with any frontend.</li><li><strong>Unified flow</strong>: Standardized endpoints for creating, capturing, notifying, and tracking payment status.</li><li><strong>Symfony Messenger</strong>: Asynchronous or synchronous handling through messages, ensuring scalability and control.</li></ul><p><strong>Payment Flow Breakdown</strong></p><ol><li><strong>Initiate Payment</strong>: A user places an order, triggering a <code>payment request</code> message.</li><li><strong>Capture Action</strong>: Custom handlers manage the payment initiation (e.g., redirecting to Stripe's checkout or embedding a payment form).</li><li><strong>Notify</strong>: Stripe or another gateway sends a webhook or safe notify callback to update payment status.</li><li><strong>Status Tracking</strong>: The status is fetched and acted upon (success redirects to a thank-you page, failure prompts retry).</li></ol><p><strong>Stripe Plugin Implementation</strong></p><p>Francis detailed the Stripe integration:</p><ul><li><strong>Checkout Session vs Payment Intent</strong>: Support for both full-page portals and embedded forms.</li><li><strong>HTTP Response Layer</strong>: Customizable responses for UI or headless workflows.</li><li><strong>Webhook Handling</strong>: Robust message parsing and state management.</li><li><strong>Live Component Enhancements</strong>: Added dynamic form fields in the Sylius admin for multi-webhook configuration.</li></ul><p><strong>Testing and Developer Experience</strong></p><p>To streamline testing in headless setups:</p><ul><li><strong>Mocking Stripe API</strong>: A caching service stores request/response expectations.</li><li><strong>Profiler Integration</strong>: Full visibility of Stripe interactions via Symfony HTTP client.</li></ul><p><strong>Next Steps and Community Call</strong></p><p>Francis emphasized the need for:</p><ul><li>Enhanced documentation.</li><li>Shared traits and services to simplify plugin development.</li><li>Broader adoption and feedback from the community.</li></ul><p><strong>Key Takeaways</strong></p><ul><li><strong>Payment Request</strong> transforms Sylius into a future-proof e-commerce platform with modern payment flexibility.</li><li><strong>Stripe plugin</strong> exemplifies how to leverage this new system for headless, API-first setups.</li><li><strong>Developers gain full control</strong> over the flow, enabling customized UIs and robust integrations.</li></ul><p>Forward-thinking merchants and integrators now have a powerful toolkit to streamline and scale their payment experiences. With Payment Request, Sylius takes a bold step into the modern commerce era.</p><h2>🛍️ Searchandising Gets Smarter</h2><p>🎤 Romain Ruaud : <a href="https://www.linkedin.com/in/romain-ruaud-5a001a20/">LinkedIn</a><br />
&quot;Searchandising&quot; — the sweet spot between search and merchandising — was the theme of Romain’s talk on Gally. With real-time indexing, rule-based recommendations, and better UX control, Gally makes Sylius stores not just functional, but delightful to shop. 🔍✨</p><p><strong>Elevating E-Commerce Search with Gali: Open Source Merchandising for Sylius</strong></p><p>At SyliusCon, Romain from Smile unveiled Gali, a powerful open-source search and merchandising platform tailored to modern e-commerce challenges. Designed to extend beyond traditional search, Gali empowers merchants with control, customization, and intelligent tooling—all while remaining extensible for agencies and developers.</p><p><strong>What is Searchandising?</strong></p><p>Searchandising blends search optimization with merchandising strategy. It ensures that what users see in search results is not only relevant but also aligned with business goals. Gali addresses this by combining robust search capabilities with intuitive ranking and product management tools.</p><p><strong>From Frustration to Flexibility</strong></p><p>Typical SaaS search platforms like Algolia or Doofinder are black boxes: powerful but unchangeable. Gali flips the script with an open-source model. Built on Symfony and API Platform, Gali gives developers the keys to customize behavior and integrate deeply with the merchant's ecosystem.</p><p><strong>Core Features</strong></p><ol><li><p><strong>Search Intelligence</strong>:</p><ul><li>Full-text search with typo tolerance, synonyms, and multi-language support.</li><li>Vector search for semantic understanding using pretrained or custom LLMs.</li><li>Cross-entity search (products, content, pages, etc.)</li></ul></li><li><p><strong>Advanced Merchandising</strong>:</p><ul><li>Manual and dynamic product ranking.</li><li>Virtual categories driven by rules (e.g., price &lt; $50).</li><li>Time-bound boosts and bury rules for sales and campaigns.</li><li>In-depth explainability tools for debugging product positions.</li></ul></li><li><p><strong>Frontend Flexibility</strong>:</p><ul><li>API-first architecture enables integration with Sylius frontends or headless frameworks like React.</li><li>Real-time UI updates via the Gali back office for filters, synonyms, and sort orders.</li></ul></li></ol><p><strong>Vector Search in Action</strong></p><p>One standout feature is Gali's support for vector search. Using embeddings, Gali matches user queries like &quot;ski outfit for my wife&quot; to semantically relevant products—even if exact terms don't appear in the catalog. This leap from keyword to intent unlocks a new level of user satisfaction.</p><p><strong>Sylius Integration</strong></p><p>Thanks to a dedicated plugin initially developed by the community and updated for Sylius 2.0, integrating Gali into a Sylius store is straightforward. Taxons, products, and attributes can sync seamlessly, with dynamic updates reflected immediately based on merchant-configured rules.</p><p><strong>Upcoming Features</strong></p><p>Gali's roadmap includes behavioral analytics for personalization, recommendations (&quot;people also bought&quot;), and performance dashboards to monitor search efficiency and conversion impact.</p><p><strong>Licensing Model</strong></p><p>Gali is dual-licensed:</p><ul><li><strong>Open Source Tier</strong>: Full indexing, search, manual merchandising.</li><li><strong>Enterprise Tier</strong> (~€10,000/year, negotiable): Boosts, thesaurus, vector search, virtual categories, with full source code and extensibility.</li></ul><p><strong>Key Takeaways</strong></p><ul><li><strong>Open Source Merchandising</strong>: Total flexibility for agencies and merchants.</li><li><strong>Developer-Friendly</strong>: Symfony-based, API-first, and fully hackable.</li><li><strong>Smarter Search</strong>: Combining semantics, rules, and UX for higher conversion.</li></ul><p>For Sylius users, Gali is more than a search tool—it's a merchandising powerhouse ready to unlock next-level e-commerce experiences. As open commerce grows, Gali’s open-core foundation ensures it evolves with your ambitions.</p><h2>🔄 Connect Everything: Automation in Practice</h2><p>🎤 Jacques Bodin-Hullin : <a href="https://www.linkedin.com/in/%F0%9F%A6%84-jacques-bodin-hullin-9a36081a/">LinkedIn</a><br />
Jacques showed us how automation isn’t just hype — it’s a productivity booster. Using n8n, he demonstrated how to wire up Sylius to external tools for data sync, notifications, and even customer workflows. If you’re scaling or juggling lots of systems, this was a must-see. ⚡🔗</p><p><strong>Streamlining E-Commerce with Sylius and N8N: Automations Made Simple</strong></p><p>At SyliusCon, Jacques from MrBiz showcased how automation can transform e-commerce operations using Sylius and N8N, a powerful open-source workflow automation tool. His demos covered real-world scenarios that combined practicality, creativity, and technical finesse—highlighting how developers and merchants can save time and scale effortlessly.</p><p><strong>Why Automations Matter</strong></p><p>From elevators to CI/CD pipelines, automation simplifies tasks we no longer need to do manually. In e-commerce, automation can enhance customer experience, improve internal workflows, and ensure seamless operations from checkout to customer follow-up.</p><p><strong>Core Components of Automation in Sylius</strong></p><ol><li><strong>Event Listeners</strong>: Symfony events (e.g., order placed, customer registered) act as triggers.</li><li><strong>Webhooks</strong>: Events are forwarded to N8N via HTTP requests.</li><li><strong>N8N Workflows</strong>: Visual, node-based sequences that perform actions like sending emails, updating CRMs, or interacting with AI services.</li></ol><p><strong>Real-World Use Cases</strong></p><ol><li><p><strong>Customer Onboarding</strong>:</p><ul><li>A listener captures the <code>customer.registered</code> event.</li><li>A webhook sends data to N8N.</li><li>N8N adds the contact to Mautic (marketing automation platform).</li></ul></li><li><p><strong>Order Confirmation and Alerts</strong>:</p><ul><li>Upon payment, the system sends a text message to the customer.</li><li>Notion is updated with order details for internal teams.</li><li>Slack alerts notify the team for high-value orders.</li></ul></li><li><p><strong>Shipping Notifications</strong>:</p><ul><li>Once a tracking number is added in Notion, N8N updates the order in Sylius.</li><li>Customers receive SMS confirmation.</li></ul></li><li><p><strong>Review Moderation with AI</strong>:</p><ul><li>N8N analyzes sentiment of product reviews using built-in AI nodes.</li><li>Positive reviews are auto-approved.</li><li>Negative ones trigger Slack alerts for human review.</li></ul></li><li><p><strong>AI-Powered Customer Service Routing</strong>:</p><ul><li>Contact form submissions are classified by AI.</li><li>Requests are prioritized and routed to the correct department (e.g., GDPR or support).</li><li>Follow-ups are logged in ticketing tools like Redmine.</li></ul></li></ol><p><strong>Why N8N?</strong></p><ul><li><strong>Open Source</strong>: Fully extensible and self-hosted.</li><li><strong>API-Rich</strong>: Integrates with CRMs, Slack, Notion, Stripe, OpenAI, etc.</li><li><strong>Low Code</strong>: JavaScript and Python nodes allow for advanced logic.</li><li><strong>Debugging Tools</strong>: Pin data, inspect executions, and test workflows live.</li></ul><p><strong>Best Practices</strong></p><ul><li>Use a single webhook entry point with switch nodes for scalability.</li><li>Separate high-priority logic (e.g., legal compliance) from marketing flows.</li><li>Use conditional nodes to filter sensitive or high-value transactions.</li></ul><p><strong>Future Outlook</strong></p><p>Jacques plans to develop a dedicated N8N node for Sylius, making it even easier to automate tasks natively. This would abstract API interactions and enable deeper integration into merchant workflows.</p><p><strong>Key Takeaways</strong></p><ul><li><strong>Automation amplifies efficiency</strong>, freeing teams from manual tasks.</li><li><strong>N8N and Sylius are a powerful match</strong>, ideal for agencies and e-commerce platforms alike.</li><li><strong>Use cases span marketing, logistics, AI moderation, and customer support</strong>.</li></ul><p>For forward-thinking e-commerce teams, embracing automation with Sylius and N8N is not just a productivity booster—it’s a strategic advantage.</p><h2>🌱 Fast = Green</h2><p>🎤 Guillaume Moigneu (Platform.sh) : <a href="https://www.linkedin.com/in/guillaumemoigneu/">LinkedIn</a><br />
Can faster performance also mean a smaller carbon footprint? Guillaume says yes — and he has data to prove it. By optimizing CPU, using intelligent caching, and selecting the right infrastructure, you can cut both costs and emissions. Sustainability meets tech, beautifully. 🌍⚡</p><p>Thanks for your patience! Here’s a structured summary of Guillaume’s talk at SyliusCon, tailored for a blog post audience of e-commerce developers and decision-makers:</p><h2>Unlocking Greener Commerce: A Practical Guide to Eco-Friendly Web Infrastructure</h2><p>In a talk that fused technical strategy with environmental urgency, Guillaume tackled the rising carbon footprint of IT and how e-commerce professionals can actively counter it. With predictions showing IT could account for up to <strong>26% of global carbon emissions by 2040</strong>, the message was clear: <em>sustainability starts with smart engineering</em>.</p><h3>The Cost of Carbon in the Cloud</h3><p>Guillaume broke down the main sources of emissions in modern cloud infrastructure:</p><ul><li><strong>Compute (CPU &amp; RAM)</strong>: ~46% of carbon emissions</li><li><strong>Storage</strong>: ~17%</li><li><strong>Networking</strong>: ~30%</li><li><strong>Human Time</strong>: Often overlooked, but costly</li></ul><p>Cloud services charge for resource allocation—not usage. That means unused but allocated CPUs still burn carbon.</p><h3>Three Levers for Greener Hosting</h3><ol><li><p><strong>Deploy in Greener Regions</strong>: Countries like France, Sweden, and Quebec have low-carbon energy grids, unlike Germany or the U.S.</p></li><li><p><strong>Increase Density</strong>: Avoid underused infrastructure. Target 90%+ CPU utilization to maximize value and minimize waste.</p></li><li><p><strong>Optimize Everything</strong>:</p><ul><li><strong>Compute</strong>: Lean code, heavy caching</li><li><strong>Storage</strong>: Deduplication, image optimization</li><li><strong>Network</strong>: Minify pages, compress assets, use CDNs close to your users</li></ul></li></ol><h3>Cache Is King</h3><p>From database query results to full-page content and API responses, caching is the easiest and most impactful performance and sustainability tool. Guillaume highlighted Symfony’s built-in strategies, the power of HTTP cache layers like Fastly or Cloudflare, and reminded us: <em>even APIs can be cached</em>.</p><h3>Redis vs Valkey &amp; Scaling Lessons</h3><p>He recommended <strong>Valkey</strong> as a modern Redis alternative and covered best practices in scaling:</p><ul><li><strong>Vertical scaling</strong> for stateful services (e.g., databases)</li><li><strong>Horizontal scaling</strong> for stateless services (e.g., PHP apps)</li><li>Beware Redis’ single-threaded limits—split cache roles for scalability.</li></ul><h3>Load Testing &amp; Performance Budgets</h3><p>Using tools like Blackfire and CI-integrated performance testing, Guillaume urged developers to set <strong>realistic performance budgets</strong> for key transactions. Regular regression testing ensures performance doesn’t degrade with new code.</p><h3>AI’s Carbon Conundrum</h3><p>Guillaume tackled the AI paradox: while AI consumes huge resources (1,000 images ≈ 1kg CO₂), it may eventually enable massive efficiency gains. The question is whether AI will end up <em>amplifying or mitigating</em> our tech footprint.</p><h3>Takeaway: Make Performance a Cultural Priority</h3><p>He ended with a call to action: performance and sustainability are <em>not</em> just technical concerns. Everyone—developers, marketers, execs—must align around expectations, budgets, and goals. Only then can we build faster, smarter, and greener commerce.</p><h2>🧬 FrankenPHP + Sylius = ❤️</h2><p>🎤 Kévin Dunglas : <a href="https://www.linkedin.com/in/dunglas/">LinkedIn</a><br />
In classic Dunglas fashion, we got a peek into the future. FrankenPHP isn’t just cool — it’s practical. Kévin explained how this cutting-edge web server improves response times, simplifies deployments, and is fully compatible with Sylius. If performance and DX matter to you, take note. 🧟‍♂️🚀</p><p><a href="https://frankenphp.dev/docs/"><img src="https://tse3.mm.bing.net/th?id=OIP.fyLW4zgXOq_eiVVSNJTqiwHaEJ&amp;pid=Api" alt="FrankenPHP: the modern PHP app server" /></a></p><p>At SyliusCon 2025, Kévin Dunglas introduced FrankenPHP, a groundbreaking application server designed to enhance PHP performance and streamline deployment, particularly for Sylius-based e-commerce platforms.(<a href="https://dunglas.dev/2024/11/frankenphp-1-3-massive-performance-improvements-watcher-mode-dedicated-prometheus-metrics-and-more/?utm_source=chatgpt.com" title="FrankenPHP 1.3: Massive Performance Improvements, Watcher Mode ...">dunglas.dev</a>)</p><h2>⚙️ What Is FrankenPHP?</h2><p>FrankenPHP is a modern PHP application server built atop the Caddy web server and written in Go. It integrates the official PHP interpreter directly into the server, eliminating the need for traditional setups like Nginx with PHP-FPM. This consolidation simplifies deployment and enhances performance. (<a href="https://frankenphp.dev/docs/" title="FrankenPHP: the modern PHP app server">frankenphp.dev</a>, <a href="https://frankenphp.dev/" title="FrankenPHP: the modern PHP app server">frankenphp.dev</a>)</p><h2>🚀 Key Features and Technical Innovations</h2><h3>1. <strong>Worker Mode</strong></h3><p>FrankenPHP's optional &quot;worker mode&quot; keeps the application booted in memory, allowing it to handle multiple requests without reinitializing. This approach significantly reduces response times and resource consumption. Benchmarks indicate that Sylius applications running in worker mode can achieve up to 80% faster response times and support over 1,000 concurrent clients on a single AWS EC2 instance, compared to 150 clients with standard PHP-FPM setups.</p><h3>2. <strong>Early Hints (HTTP 103) Support</strong></h3><p>FrankenPHP uniquely supports the HTTP 103 status code, enabling the server to send resource hints to the browser before the full response is ready. This feature can improve the Largest Contentful Paint (LCP) metric by up to 30%, enhancing user experience and potentially boosting conversion rates.</p><h3>3. <strong>Real-Time Capabilities with Mercure</strong></h3><p>Built-in support for the Mercure protocol allows FrankenPHP to push real-time updates to connected clients efficiently. This is particularly beneficial for e-commerce platforms requiring live notifications, such as inventory changes or order updates. (<a href="https://frankenphp.dev/docs/performance/" title="Performance optimization - FrankenPHP: the modern PHP app server">frankenphp.dev</a>)</p><h3>4. <strong>Simplified Deployment</strong></h3><p>FrankenPHP offers a self-contained binary and Docker image, bundling the PHP engine, web server, and necessary extensions. This setup reduces complexity, minimizes dependencies, and accelerates deployment processes.</p><h2>🛒 Practical Value for E-Commerce</h2><p>For e-commerce businesses, FrankenPHP presents several advantages:</p><ul><li><p><strong>Performance Boost</strong>: Faster response times lead to improved user experience and potentially higher conversion rates.</p></li><li><p><strong>Cost Efficiency</strong>: Reduced resource consumption can lower hosting expenses.</p></li><li><p><strong>Scalability</strong>: Enhanced ability to handle concurrent users supports business growth.</p></li><li><p><strong>Developer Experience</strong>: Simplified setup and deployment streamline development workflows.</p></li></ul><h2>🔑 Key Takeaways</h2><ul><li><p><strong>FrankenPHP</strong> is a modern, high-performance PHP application server that simplifies deployment and enhances performance.(<a href="https://thephp.foundation/blog/2025/05/15/frankenphp/" title="FrankenPHP Is Now Officially Supported by The PHP Foundation">thephp.foundation</a>)</p></li><li><p><strong>Worker mode</strong> significantly reduces response times and resource usage by keeping the application in memory.</p></li><li><p><strong>Support for HTTP 103 Early Hints</strong> improves page load times, enhancing user experience.</p></li><li><p><strong>Built-in real-time capabilities</strong> enable efficient client updates, crucial for dynamic e-commerce platforms.(<a href="https://medium.com/%40iskenderatasoy/frankenphp-the-new-star-in-the-php-ecosystem-73c17c6f710f" title="FrankenPHP: The New Star in the PHP Ecosystem - Medium">Medium</a>)</p></li><li><p><strong>Simplified deployment</strong> through self-contained binaries and Docker images accelerates development and reduces complexity.</p></li></ul><p>FrankenPHP represents a significant advancement in PHP application servers, offering tangible benefits for e-commerce platforms seeking performance, scalability, and streamlined operations.</p><h2>💬 Wrapping Up</h2><p>Sylius Days 2025 confirmed what many already feel: modern eCommerce is no longer just about having a cart and a checkout. It’s about smart integrations, sustainable performance, global reach, and powerful automation.</p><p>✨ Whether you’re a developer building the future or a founder scaling your store, the Sylius ecosystem continues to deliver powerful tools and ideas to stay ahead.</p><h3>🎁 Bonus for Creators &amp; Builders</h3><p>If you're looking to go further and automate your own workflows — be it thumbnail generation, video publishing, or custom flows like those shown during Sylius Days — I offer free 30-minute coaching sessions tailored to creators like you. Let's bring your ideas to life!</p><p>👉 <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Book your free session here</a> 📞</p>
]]></content:encoded><link>https://blog.darkwood.com/article/sylius-days-2025-what-we-learned-from-the-front-lines-of-ecommerce-innovation</link><guid>https://blog.darkwood.com/article/sylius-days-2025-what-we-learned-from-the-front-lines-of-ecommerce-innovation</guid><enclosure url="http://darkwood.com/media/articles/683005c6081ef934643139.png" /></item><item><title>🚀 From Zero to Hero with Sylius: Inside the Practical Essentials Workshop</title><pubDate>Sat, 24 May 2025 07:33:22 +0000</pubDate><description><![CDATA[If you&#039;re new to Sylius or looking to solidify your foundations, Gracjan Józefczyk, BitBag Developer &amp;amp; Sylius Key Contributor. It was a workshop at Sylius Days 2025 was a masterclass in eCommerce architecture. 💡
Mastering Sylius Fundamentals: From Resou...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/683176423c880853136372.png" /></p><p>If you're new to Sylius or looking to solidify your foundations, <a href="https://www.linkedin.com/in/gracjan-jozefczyk/"><strong>Gracjan Józefczyk</strong></a>, BitBag Developer &amp; Sylius Key Contributor. It was a workshop at Sylius Days 2025 was a masterclass in eCommerce architecture. 💡</p><h2>Mastering Sylius Fundamentals: From Resource Configuration to Grids</h2><p>In a hands-on Sylius workshop led by key contributor and Sylius Academy creator Grazian, experienced Symfony developers explored the foundation of Sylius through live coding, architectural insights, and real-world implementation strategies. This post distills the core technical knowledge from the session—focused on understanding Sylius' dual identity as a platform and a framework, the power of the ResourceBundle and GridBundle, and effective customization approaches.</p><h3>Problem Context:</h3><p>Sylius is a Symfony-based eCommerce solution that aims to be both developer-friendly and enterprise-ready. However, getting started or extending it (e.g., creating custom resources or interfaces) often feels daunting due to its opinionated architecture and dependency on its own bundles. Developers entering a Sylius project must first understand how the core entities, services, and configurations interplay to avoid friction later.</p><h3>Solution Breakdown:</h3><ul><li>Understanding Sylius as a Framework and Platform</li></ul><p>Sylius provides a bootstrap-based shop frontend, an admin panel, and a complete API out of the box. It combines the flexibility of a Symfony framework with the plug-and-play capabilities of an eCommerce platform.</p><p>Admin Panel: Uses Symfony Security firewalls to distinguish between admin and customer logins.</p><p>API: Built with API Platform. Endpoints are exposed for both shop and admin, with clear separation via /shop and /admin prefixes.</p><ul><li>Resource Configuration with ResourceBundle</li></ul><p>The SyliusResourceBundle abstracts away common CRUD operations by leveraging configuration-based entity declarations. To define a new resource:</p><pre><code class="language-yaml">sylius_resource:
    resources:
        app.brand:
            driver: doctrine/orm
            classes:
                model: App\Entity\Brand
</code></pre><p>This single block enables:</p><ul><li>Controller instantiation (via ResourceController)</li><li>Factory, FormType, and Repository autowiring</li><li>Service autoconfiguration and routing</li></ul><p>Bonus: Use debug:sylius:resource to inspect resource bindings.</p><ul><li>Exposing Routes with Symfony Routing Config</li></ul><p>Once declared, resource routes are exposed via:</p><pre><code class="language-yaml">sylius_admin_brand:
    resource: &quot;sylius.resource&quot;
    type: sylius.resource
    section: admin
    alias: app.brand
    templates: SyliusAdminBundle:Crud
    redirect: update
    grid: sylius_admin_brand
</code></pre><ul><li>Data Listing with GridBundle</li></ul><p>SyliusGridBundle enables admin-side grids for data visualization and interaction (filters, actions, bulk operations).</p><pre><code class="language-yaml">sylius_grid:
    grids:
        sylius_admin_brand:
            driver:
                name: doctrine/orm
                options:
                    class: App\Entity\Brand
            fields:
                name:
                    type: string
                    label: sylius.ui.name
            filters:
                name:
                    type: string
</code></pre><p>Grids integrate seamlessly with ResourceBundle. They support:</p><ul><li>Column filters</li><li>Inline and bulk actions</li><li>Easy frontend rendering via Bootstrap-based templates</li></ul><h3>Extensibility and Community Practices</h3><p>Advanced use cases showcased during the workshop:</p><ul><li>Migrating from Sylius 1.14 to Sylius 2 (major changes in Grid rendering, ResourceBundle internals)</li><li>Using new PHP attribute-based resource declarations (#[AsResource]) to remove YAML verbosity</li><li>Replacing Winzou state machine with Symfony Workflow for order transitions</li><li>Integration strategies for CMS, PIM, or search backends (Elasticsearch)</li></ul><p>A key strength of Sylius is its active community, maintaining open-source plugins (Stripe, Admin UI, etc.) and contributing back through GitHub and Slack support.</p><p>Result/Impact: Participants left with a production-ready Sylius setup, configured Docker environment, and practical knowledge to:</p><p>Extend Sylius with custom entities:</p><ul><li>Use declarative configuration for rapid CRUD</li><li>Customize admin grids</li><li>Migrate to newer Sylius versions</li><li>This approach boosts maintainability, developer onboarding, and speeds up initial development cycles.</li></ul><p>Key Takeaways:</p><ul><li>SyliusResourceBundle eliminates boilerplate for CRUD.</li><li>SyliusGridBundle provides production-grade admin listings with minimal config.</li><li>Symfony integration is first-class, enabling smooth DX.</li><li>Community contributions and practices are critical for scaling Sylius.</li><li>Use YAML or PHP Attributes based on your project scale and team conventions.</li></ul><h2>🔧 Mastering Sylius Customizations and Plugins — Advanced Developer Insights</h2><p>During the advanced Sylius workshop, developers dived deep into two critical aspects of customizing enterprise-level e-commerce: <strong>tailoring the business logic via entity, form, and template overrides</strong>, and <strong>building modular, reusable plugins</strong> that remain maintainable and compatible across Sylius versions.</p><h3>🧩 The Challenge</h3><p>Modern e-commerce implementations often require tailored logic (e.g., product configurators, vendor-specific data, layered promotions). The default Sylius setup is flexible, but not always turn-key for these advanced needs.</p><p>Key developer goals include:</p><ul><li>Extending entities without breaking inheritance or Doctrine mappings.</li><li>Injecting new fields into Symfony forms.</li><li>Overriding templates in a future-proof way.</li><li>Developing reusable plugins with test environments and version compatibility.</li></ul><h2>🛠️ Technical Implementation</h2><h3><strong>Extending Entities and Forms</strong></h3><h4>Example: Adding a <code>brand</code> relation to <code>Product</code></h4><pre><code class="language-php">// src/Entity/Product.php
class Product extends BaseProduct
{
    #[ORM\ManyToOne(targetEntity: Brand::class)]
    private ?Brand $brand = null;

    public function getBrand(): ?Brand { return $this-&gt;brand; }
    public function setBrand(?Brand $brand): void { $this-&gt;brand = $brand; }
}
</code></pre><h4>Inject the field in the admin form using a Form Type Extension:</h4><pre><code class="language-php">// src/Form/Extension/ProductTypeExtension.php
class ProductTypeExtension extends AbstractTypeExtension
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder-&gt;add('brand', EntityType::class, [
            'class' =&gt; Brand::class,
            'choice_label' =&gt; 'name',
            'required' =&gt; false,
        ]);
    }

    public static function getExtendedTypes(): iterable
    {
        return [ProductType::class];
    }
}
</code></pre><h3><strong>Template Overrides with Twig Hooks</strong></h3><p>Instead of copying entire templates, you can inject custom logic using <strong>Twig Hooks</strong>, introduced in Sylius 1.11+.</p><pre><code class="language-twig">{ % hook 'sylius.admin.product.form.tab' % }
    { { render(controller('App\\Controller\\BrandController::index')) } }
{ % endhook % }
</code></pre><p>You can inspect hook names and usage via the Symfony Profiler. Each hook accepts:</p><ul><li>A priority (for order)</li><li>Parameters (passed to the template)</li><li>Optional pre/post hook zones</li></ul><h3><strong>Building Robust Plugins</strong></h3><h4>Plugin Skeleton</h4><p>Sylius plugins follow a Symfony bundle structure:</p><pre><code>src/
  MyPlugin/
    Controller/
    Entity/
    Repository/
    DependencyInjection/
    MyPlugin.php
</code></pre><p>They register configuration, routes, and services via dedicated manifests. Common use cases include:</p><ul><li>Payment integrations (Stripe, Mollie, PayPal)</li><li>SEO features (sitemaps, structured data)</li><li>Import/Export functionality</li><li>Custom promotions, attributes, or checkout logic</li></ul><h4>Shared Test Application (New Approach)</h4><p>Historically, each plugin had to ship with a full Sylius test app — creating maintenance nightmares across multiple versions.</p><p>Now, the community provides a <strong>shared test app package</strong>:</p><pre><code class="language-bash">composer require --dev sylius/plugin-test-application
</code></pre><p>This allows per-version CI matrix testing with automatic config patching based on Sylius/Symfony versions.</p><pre><code class="language-yaml">sylius:
    version: [&quot;1.11&quot;, &quot;1.12&quot;, &quot;1.13&quot;, &quot;1.14&quot;, &quot;2.0&quot;]
    symfony: [&quot;5.4&quot;, &quot;6.4&quot;]
</code></pre><p>No more <code>Kernel.php</code> hacks — this makes plugin dev faster and far more maintainable.</p><h2>📈 Outcome and Benefits</h2><ul><li><strong>Extensibility</strong>: Business-specific needs are encapsulated cleanly with zero coupling to Sylius core.</li><li><strong>Testability</strong>: Plugins run isolated with full CI and test apps.</li><li><strong>Compatibility</strong>: Supports multiple Sylius/Symfony versions easily.</li><li><strong>Developer Experience (DX)</strong>: Tools like Twig Hooks and <code>sylius:make:resource</code> speed up implementation dramatically.</li></ul><h2>✅ Key Takeaways for Developers</h2><p>✅ Use Doctrine inheritance and <code>FormTypeExtension</code> to <strong>extend entities and forms cleanly</strong>.<br />
✅ Leverage <strong>Twig Hooks</strong> to inject UI logic without overriding full templates.<br />
✅ Structure your plugins like Symfony bundles and follow best practices (non-final repositories, isolated services).<br />
✅ Use the new <strong>test application tool</strong> to make your plugins compatible with multiple versions of Sylius and Symfony.<br />
✅ <strong>Extract reusable logic</strong> into plugins (payment, import/export, Elasticsearch, wishlists…) to scale across projects.</p><h2>✅ Why This Matters</h2><p>This workshop wasn't just theoretical — it was built for action. If you're building scalable, customizable, and developer-friendly eCommerce solutions, mastering Sylius is a no-brainer. And Gracjan’s guidance made that journey 10x faster. ⚡</p><h2>SyliusCon 2025</h2><p>SyliusCon 2024 was a pivotal moment for the Sylius community, and the excitement is already building for <a href="https://sylius.com/conference-2025">SyliusCon 2025</a>, promising even deeper insights, technical showcases, and community-driven innovation in the evolving e-commerce landscape.</p><h2>Ressources</h2><p>Sylius components</p><ul><li>RessourceBundle : https://github.com/Sylius/SyliusResourceBundle</li><li>GridBundle : https://github.com/Sylius/SyliusGridBundle</li><li>Twig hooks : https://afup.org/talks/4929-creer-des-interfaces-d-administration-rapidement-avec-symfony-ux-et-sylius</li><li>SyliusRecipes : https://github.com/Sylius/SyliusRecipes</li><li>SyliusStandard : https://github.com/Sylius/Sylius-Standard</li><li>SyliusDemo : https://github.com/Sylius/SyliusDemo</li></ul><p>Plugins</p><ul><li>Stripe plugin : https://github.com/FLUX-SE/SyliusPayumStripePlugin</li><li>SyliusElasticsearchPlugin : https://github.com/BitBagCommerce/SyliusElasticsearchPlugin</li><li>SEO plugin</li><li>import export (Friend of Sylius) https://github.com/FriendsOfSylius/SyliusImportExportPlugin</li><li>whishlist</li><li>GDPR plugin (synolia)</li><li>Gift card</li><li>Invoices</li></ul><h2>💡 Bonus for Creators &amp; Builders</h2><p>Want to automate your own processes like thumbnail creation, video publishing, or workflow management?</p><p>👉 I offer <strong>30-minute free coaching sessions</strong> to help creators like you move faster.
Let’s simplify your stack, together.
📞 <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">Book your free session here</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/from-zero-to-hero-with-sylius-inside-the-practical-essentials-workshop</link><guid>https://blog.darkwood.com/article/from-zero-to-hero-with-sylius-inside-the-practical-essentials-workshop</guid><enclosure url="http://darkwood.com/media/articles/683176423c880853136372.png" /></item><item><title>🚀 Du développement à la production : déployer une API Symfony avec Upsun</title><pubDate>Mon, 26 May 2025 06:47:15 +0000</pubDate><description><![CDATA[
Are you looking to scale your Symfony or Laravel projects with ease? Want to deploy your apps like a pro while staying efficient and eco-friendly? 🌱 Well, that’s exactly what I walked through in my latest video.
Let me break it down for you 👇
🧩 What is Ups...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68340e73a0e16351803821.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/YTBKaYUOi7Y?si=tUEwjVql9Aff-7cC" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Are you looking to scale your Symfony or Laravel projects with ease? Want to deploy your apps like a pro while staying efficient and eco-friendly? 🌱 Well, that’s exactly what I walked through in my latest video.</p><p>Let me break it down for you 👇</p><h2>🧩 What is Upsun?</h2><p>Upsun is a cloud platform built on the foundation of <a href="https://platform.sh">Platform.sh</a>. It makes deployment simple and secure for all kinds of applications: Symfony, Laravel, Next.js, Rails, Django, even LangChain for AI enthusiasts 🤖</p><p>They say it best: *&quot;Simply turning code into secure production applications.&quot;- ✅</p><p>Best of all? It’s fast, green, and made for developers like you and me 🧑‍💻</p><h2>🛠 What Did I Deploy?</h2><p>Instead of a standard demo app, I deployed Uniflow’s API (a Symfony-based project powered by Sylius 2.0.7). Here’s how it went:</p><p>📁 Copied the Uniflow API code into a local working directory<br />
🧬 Initialized Git and committed the base project<br />
🌍 Created a new project on Upsun, selecting the OVH region (my favorite 🇫🇷)<br />
🖥 Connected the Git repo to the Upsun remote<br />
🛠 Added configuration files: <code>.upsun/config.yaml</code>, <code>routes.yaml</code>, and <code>services.yaml</code><br />
🎯 Defined:</p><ul><li>PHP 8.2 runtime</li><li>PostgreSQL 15 as a service</li><li>Required extensions like <code>sodium</code></li><li>Proper <code>DATABASE_URL</code> from environment variables</li></ul><p>🔁 Ran <code>git push upsun 1.x</code> and... the magic started! 🎩✨</p><p>Upsun installed all Composer dependencies, ran migrations, created my DB, installed JWT keys, and more — even provisioned my HTTPS certs automatically. ✅</p><h2>🧑‍🔬 What I Liked About Upsun</h2><ul><li>The web UI is clear and intuitive</li><li>CLI deployment is smooth and fast 💨</li><li>Green cloud infrastructure ♻️</li><li>Excellent integration with Symfony &amp; Laravel</li><li>Built-in support for Horizon (if you're into Laravel queues)</li></ul><p>Bonus: <a href="https://medium.com/deploy-friday/deploying-laravel-with-horizon-on-upsun-5b543db39c1c">Guillaume Moigneux’s blog post on Laravel + Horizon on Upsun</a> is worth the read if you're in the Laravel ecosystem 🔥</p><h2>⚙️ Useful Links</h2><p>🌐 <a href="https://upsun.com">Upsun Website</a><br />
📚 <a href="https://docs.upsun.com/get-started/stacks/symfony/get-started.html">Symfony + Upsun Official Docs</a><br />
🧪 <a href="https://medium.com/deploy-friday/deploying-laravel-with-horizon-on-upsun-5b543db39c1c">Laravel + Horizon on Upsun</a></p><h2>💬 Want to Automate Your Process?</h2><p>If you're a creator looking to scale or automate your production workflows — from thumbnail generation, to video publishing, or end-to-end content workflows, I’m here to help 💡</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate your processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let’s build smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/du-developpement-a-la-production-deployer-une-api-symfony-avec-upsun</link><guid>https://blog.darkwood.com/article/du-developpement-a-la-production-deployer-une-api-symfony-avec-upsun</guid><enclosure url="http://darkwood.com/media/articles/68340e73a0e16351803821.png" /></item><item><title>▶️ 2025-05-26 DjMatyo Soundcloud set with MC</title><pubDate>Tue, 27 May 2025 07:53:01 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · ▶️ 2025-05-26 DjMatyo Soundcloud set with MC
Nouvelle session DJ Matyo sur des tracklists soundcloud avec MC !
Tracklist

01 - Dj Erupt Mc Banks Halloween Special 2022 Vol 1 :: Trinitystyle :: https://soundcloud.com/trinitystyl...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68356f5d4042d230154507.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/V3VSaqmM17Y?si=RguvtC-vaBJDaPK8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2102945304&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/2025-05-26-djmatyo-soundcloud-set-with-mc" title="▶️ 2025-05-26 DjMatyo Soundcloud set with MC" target="_blank" style="color: #cccccc; text-decoration: none;">▶️ 2025-05-26 DjMatyo Soundcloud set with MC</a></div></div><p>Nouvelle session DJ Matyo sur des tracklists soundcloud avec MC !</p><h2>Tracklist</h2><ul><li>01 - Dj Erupt Mc Banks Halloween Special 2022 Vol 1 :: Trinitystyle :: https://soundcloud.com/trinitystyle/dj-erupt-mc-banks-halloween</li><li>02 - DJ'S CHUD &amp; VIDA - MC COBRA &amp; DAZ RAPID :: Daz Rapid :: https://soundcloud.com/daz-rapid-1/djs-chud-vida-mc-cobra-daz-rapid</li><li>03 - Clenn Daz Rapid - Blast Buzzing Horney :: dj clenn :: https://soundcloud.com/dj-clenn/clenn-daz-rapin-blast-buzzing-horney</li><li>04 - Wilson Genno Rockeye Uproar :: Dj Wilson (official) :: https://soundcloud.com/steven-j-wilson-2/wilson-genno-rockeye-uproar</li><li>05 - DJ Chud - Elysium Promo Mix :: DJ Chud :: https://soundcloud.com/user-160683401/dj-chud-old-school-vibes</li><li>06 - Djs Speed and Ads Mcs Len Ricky C Wiiser Crash :: DJ Mark Speed :: https://soundcloud.com/djmarkspeeduk/djs-speed-and-ads-mcs-len</li><li>07 - HALLOWEEN SPECIAL: Project 88 &amp; Cole - Rockeye &amp; Genno D @Tropi's Bar Live :: Project 88 - High &amp; Heskey :: https://soundcloud.com/project_88/halloween-special-project-88-1</li><li>08 - THE KITCHEN CHRONICLES - DJ NOBLE MC TNT - 01 09 2022 Mp3 :: MC TNT :: https://soundcloud.com/user612131789/the-kitchen-chronicles-dj-noble-mc-tnt-01-09-2022-mp3</li><li>09 - Tripi-D B2b ADS ft. Mc Horney &amp; Reload :: Dean Harvey / Tripi-D / Unknwn Origin / De-Halve :: https://soundcloud.com/deanjharvey/tripi-d-b2b-ads-ft-mc-horney-reload</li><li>10 - The New Monkey Live Stream :: Dj Carrzy :: https://soundcloud.com/rob-carrzy-carr/the-new-monkey-live-stream</li><li>11 - DJ BINKSY MC LAM b2b MC SIMPSON :: Josh (MC Simpson) :: https://soundcloud.com/josh-mc-simpson/dj-binksy-mc-lam-b2b-mc</li><li>12 - DJ EXPRESS MC RICKY C MC FURY - HISTERIA SUMMER SPECIAL :: Hysteria Dance :: https://soundcloud.com/hysteria-dance/dj-express-mc-ricky-c-mc-fury-histeria-summer-special</li><li>13 - DJ BASHA MC IMPULSE B2B MC TEMPO :: THE POSHEND :: https://soundcloud.com/theposhenddanceevent/dj-basha-mc-tempo-b2b-impulse</li><li>14 - Elliot - Breath Of Life (Makina Remix) (Sample) :: DJ Elliot :: https://soundcloud.com/elliot-david-wilkinson/elliot-breath-of-life-makina-remix-sample</li><li>15 - Reaction Live! Dj A.D.S Mc’s Burty B2B Ricky C 26/08/2022 @The Quinn’s Inn  - Spennymoor :: Reaction Events Spennymoor :: https://soundcloud.com/mattyg31/reaction-live-dj-a-d-s-mcs</li><li>16 - DJs Ollie-B &amp; Alert MCs Letrix Retro Melo-D Crazy-B Clash Of The Titans :: DJ ALERT :: https://soundcloud.com/ash-cooper-520852787/dj-alert-mcs-letrix-retro</li><li>17 - DJ ACCESS - KITCHEN MIXIN :: Reece Chow :: https://soundcloud.com/reecechow/dj-access-kitchen-mixinwav</li><li>18 - DJ KEL-Y MC'S BANKS, INTENT, SIMPSON (TRIPLE XL &amp; STATIC PRODUCTION SET) :: DJ KEL-Y 💗💜🎶 :: https://soundcloud.com/user-581677016/dj-kel-y-mcs-banks-intent-simpson-triple-xl-static-production-set</li><li>19 - DJ SIMO MC ELESDEE MC WIZARD  mc energize mc kicking old skool classics yesaaaa :: MC ELESDEE :: https://soundcloud.com/user-956944541/18-8-22-set-1-mix1-mst-mp3</li></ul><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/969188782603322168/">EasyFR</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/2025-05-26-djmatyo-soundcloud-set-with-mc</link><guid>https://blog.darkwood.com/article/2025-05-26-djmatyo-soundcloud-set-with-mc</guid><enclosure url="http://darkwood.com/media/articles/68356f5d4042d230154507.jpg" /></item><item><title>🎶 Open Mic du Groover Club - Mai 🧡</title><pubDate>Thu, 29 May 2025 07:11:31 +0000</pubDate><description><![CDATA[Mon premier Open Mic au Groover Club en tant que DJ Matyo91 ✨

🎧 Le Groover Club : un tremplin pour les artistes indépendants
Le Groover Club est une initiative portée par Groover, la plateforme qui connecte les artistes avec les médias, labels et pros de l...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/683808a3d85ce627182626.jpg" /></p><p>Mon premier Open Mic au Groover Club en tant que DJ Matyo91 ✨</p><p><img src="/blog/images/articles/groover-club/open-mic.jpg" alt="Le bar Open Mic" /></p><h2>🎧 Le Groover Club : un tremplin pour les artistes indépendants</h2><p>Le Groover Club est une initiative portée par <a href="https://groover.co/fr/lp/groover-club/">Groover</a>, la plateforme qui connecte les artistes avec les médias, labels et pros de l'industrie musicale. Le Club, c'est une série d'événements musicaux organisés en physique, où les artistes de la communauté Groover peuvent monter sur scène, partager leur univers, et se connecter les uns aux autres dans une ambiance bienveillante.</p><p>Chaque Open Mic est un moment unique, rassemblant une vingtaine d'artistes pour des performances de 10 minutes. Le public y découvre une palette de styles allant du pop-folk au rap, en passant par l'électro ou la chanson française.</p><p>Mais le Groover Club, c’est bien plus qu’une scène ouverte :</p><ul><li>🎓 Une formation : plus de 10h de contenu vidéo exclusif conçu par des expert·e·s de la musique pour tout comprendre de la promotion musicale.</li><li>🤝 Un accompagnement personnalisé : des sessions de coaching avec des professionnel·le·s de l’industrie pour t’aider à structurer ta carrière.</li><li>🌐 Une communauté active : un espace en ligne dédié aux membres du Groover Club avec événements et ateliers live réservés aux artistes.</li></ul><p>Le Groover Club, c’est un véritable écosystème pour booster son projet musical, tout en construisant des liens durables dans le milieu indépendant.</p><h2>🎉 Mon premier événement en tant que DJ Matyo91</h2><p>Ce Mercredi 28 mai 2025, j'ai eu l'immense plaisir de participer à mon premier Open Mic au sein du Groover Club. L'événement se tenait au Tennessee, un lieu intimiste au cœur de Paris. Pour l'occasion, j'ai préparé un set Happy Hardcore – un genre rapide, euphorique, et sans compromis – qui a cloturé la soirée.</p><p>C'était aussi ma première apparition en public sous le nom de DJ Matyo91, un projet que je développe en parallèle de mes activités de développeur. À travers ce set de 10 minutes, j'ai voulu transmettre une énergie pure, un hommage à la scène rave et à mes inspirations comme S3RL, Gammer ou DJ Cotts.</p><p>J'ai joué sur une table analogique Behringer X1622USB, sans platine ni contrôleur DJ. Un défi technique, mais qui m'a permis de me concentrer sur la transmission d'émotion et de son.</p><h3>Tracklist de la soirée</h3><ul><li>Adizzle - Koopa Troopa Beach (175 BPM) — intro rétro ludique.</li><li>S3RL - MTC2 (160.29 BPM) — montée en puissance mélodique.</li><li>Dougal &amp; Gammer feat. Lisa Marie - Open Your Eyes — vocal &amp; euphorie.</li><li>DJ Cotts - Gabber Youtube Mix (extrait) — transition + surprise.</li><li>S3RL - Feels Like Heaven (175 BPM) — final en apothéose.</li></ul><h2>🎤 Les artistes du soir : un panorama éclectique</h2><p>Voici la liste des artistes ayant participé à cette édition de l'Open Mic du Groover Club, chacun avec son univers, son énergie et sa singularité musicale. Cette diversité a offert au public une véritable traversée sonore, du piano néo-classique aux beats endiablés de la drum and bass, en passant par la pop, le rap et les expérimentations électroniques.</p><ul><li>MARIIE – Variété / Pop FR-EN. Une ouverture toute en douceur et sincérité avec une voix touchante et un répertoire bilingue.</li><li>Versiara – Pop / Soul / RnB. Une voix amoureuse portée par des influences américaines, chaleureuse et envoûtante.</li><li>Myrtska – Latino et acoustique piano voix. Une artiste polymorphe qui oscille entre rythmes latins et moments de pure émotion au piano.</li><li>Gaelle Mechaly – Néo-classique, cinématographique. Un moment suspendu grâce à une prestation instrumentale profonde et poétique.</li><li>Iammilan – Electro Pop. Une performance moderne et rythmée, aux sonorités actuelles.</li><li>Emma Blune – Pop Folk / guitare. Une bulle de douceur, guitare en main, pour une atmosphère intime.</li><li>Louise Roy – Pianiste / Chanteuse. Une belle présence scénique et une interprétation sincère.</li><li>Taliy – Rap / RnB. Un flow authentique et des textes prometteurs.</li><li>Rikko – Drum &amp; Bass / Guitare. Une fusion étonnante entre beats rapides et envolées guitare.</li><li>Eriops Tie – Synthpop. Une expérience rétro-futuriste qui nous a plongés dans un univers sonore unique.</li><li>Robin Viovy – Pop guitare + pedalboard. Un travail sonore méticuleux et un songwriting affirmé.</li><li>Héloïse DSB – Pop-Folk guitare voix. Une artiste émergente à la voix claire et sensible.</li><li>Nicolas Maizeroi – Pop Soul. Une belle maîtrise vocale au service de compositions personnelles.</li><li>Mayel – Rock / chanson française. Accompagnée de Pierre Chérèze à la guitare, elle a revisité ses trois albums avec conviction.</li><li>Lil-Izi Offishall – RAP / Projet Ghost Offishall. Une performance énergique et un teaser de projet à venir.</li><li>Kuro – HIP-HOP RAP. Une signature forte, brute et créative.</li><li>RAF – Pop rap / reggae / rock. Une palette de styles assumée, servie avec naturel.</li><li>Tinezmar – Rap français / pop urbaine. Un flow affirmé et des textes ancrés dans le réel.</li><li>DJ Leeon – House Mélodique. Une transition parfaite vers la danse, dans une vibe estivale.</li><li>DJ Matyo91 – Happy Hardcore. Une clôture explosive et euphorique pour finir la soirée en apothéose.</li></ul><p>Chaque passage a contribué à la richesse de cette soirée, mettant en lumière des talents variés et prometteurs.</p><p>Une soirée inoubliable, des artistes inspirants, et un premier pas pour moi dans le monde du live musical.</p><p>Merci au Groover Club et à l'équipe de Coachs France pour cette opportunité ✨</p><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/open-mic-du-groover-club-mai</link><guid>https://blog.darkwood.com/article/open-mic-du-groover-club-mai</guid><enclosure url="http://darkwood.com/media/articles/683808a3d85ce627182626.jpg" /></item><item><title>🎮 Créer un mini-jeu Discord avec VITE : un retour d&#039;expérience</title><pubDate>Sat, 31 May 2025 11:20:58 +0000</pubDate><description><![CDATA[
Le Game Development World Championship (GDWC) est un concours international annuel pour les créateurs de jeux indépendants. Cette année, Discord s&#039;est associé au GDWC pour lancer une catégorie unique : Best Discord Game. Le prix ? 5 000 dollars et une mise...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/683ae61adb7ee927031896.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/CF4pU7Hhgdw?si=chYH09OXjz8dgT4y" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Le Game Development World Championship (GDWC) est un concours international annuel pour les créateurs de jeux indépendants. Cette année, Discord s'est associé au GDWC pour lancer une catégorie unique : Best Discord Game. Le prix ? 5 000 dollars et une mise en avant sur Discord.</p><p>En tant que développeur indépendant et créateur de contenus interactifs, je me suis lancé le défi de créer un jeu 100% intégré à Discord, jouable directement dans un salon vocal. Et c'est ainsi qu'est né VITE.</p><h2>🎮 VITE : un jeu de survie pixelisé jouable dans Discord</h2><h3>👾 Installe le jeu sur ton serveur Discord</h3><p>🔗 Voici le lien pour installer Vite sur ton serveur Discord : <a href="https://discord.com/discovery/applications/1365733516154896505">https://discord.com/discovery/applications/1365733516154896505</a></p><h3>🍀 L'histoire</h3><p><em>Il était une fois un citoyen de PC Ville, Mathieu LEDRU, qui fut exilé dans le désert pour avoir osé utiliser un Macintosh. Son seul espoir ? Atteindre le pixel de salut avant de mourir de faim ou de soif...</em></p><h3>⚖️ Les mécaniques</h3><ul><li>Vous incarnez Mathieu, un point à déplacer vers un pixel cible.</li><li>Chaque réussite rapporte des crédits, à dépenser pour améliorer votre vitesse, votre taille, ou gagner du temps.</li><li>Le jeu fonctionne à travers un game loop à 30 FPS dans un navigateur Discord grâce au SDK &quot;Discord Embedded App&quot;.</li></ul><h3>📊 Un jeu simple, mais complet</h3><ul><li>⏰ Temps limite</li><li>💸 Crédits d'amélioration</li><li>🌟 Niveaux progressifs avec menu &quot;level-up&quot;</li><li>↑️ Système de choix d'amélioration</li></ul><h2>🚀 Comment je l'ai développé ?</h2><p>J'ai suivi le guide &quot;Build Your First Discord Activity&quot;, utilisé Node.js côté client et serveur, Cloudflare Tunnel pour les tests locaux, et le SDK Discord pour l'authentification et l'affichage in-app.</p><p>J'ai aussi tenté de décompiler mon ancien jeu TI-89 pour m'en inspirer, avec quelques galères à la clé (Docker, Rust, simulateurs...). Mais j'ai fini par recoder le gameplay en JavaScript vanilla à partir de mes souvenirs.</p><h2>🤝 Tu veux ton propre jeu Discord ?</h2><p>Je propose un accompagnement personnalisé pour créer des jeux interactifs dans Discord (mini-jeux, expériences communautaires, onboarding ludiques...)</p><p>🔗 <a href="https://www.bonzai.pro/matyo91/shop/k219_2165/consulting-jeux-et-video-ludique">Consulting Jeux et Vidéo Ludique avec Matyo91</a></p><h2>🌐 Lien vers le jeu VITE</h2><ul><li><a href="https://thegdwc.com/pages/game.php?game_guid=0c0cef88-62dd-46b3-8a3c-0db09ca2e2a5">Page GDWC de VITE</a></li><li><a href="https://thegdwc.com/pages/team.php?l=darkwaar">Team Darkwaar</a></li></ul><p>Merci d'avoir lu jusqu'ici ! Partagez cette initiative si vous aimez l'idée de jouer directement dans vos salons Discord !</p>
]]></content:encoded><link>https://blog.darkwood.com/article/creer-un-mini-jeu-discord-avec-vite-un-retour-dexperience</link><guid>https://blog.darkwood.com/article/creer-un-mini-jeu-discord-avec-vite-un-retour-dexperience</guid><enclosure url="http://darkwood.com/media/articles/683ae61adb7ee927031896.png" /></item><item><title>▶️ 2025-06-16 DJMatyo Live reunion</title><pubDate>Tue, 17 Jun 2025 08:34:58 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · ▶️ DJ Matyo Live Reunion
Tracklist

Zaho de Sagazan – La symphonie des éclairs
Gazo &amp;amp; Tiakola – MAMI WATA
Petit Biscuit – Sunset Lover
Youssoupha – DIEU EST GRANDE
Chinese Man – Get Up
Chilla – Si j’étais un homme
Caballero...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/d97vJRX98n4?si=cME4zN9VcUOd13_C" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2114763759&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/dj-matyo-live-reunion" title="▶️ DJ Matyo Live Reunion" target="_blank" style="color: #cccccc; text-decoration: none;">▶️ DJ Matyo Live Reunion</a></div></div><h2>Tracklist</h2><ul><li>Zaho de Sagazan – La symphonie des éclairs</li><li>Gazo &amp; Tiakola – MAMI WATA</li><li>Petit Biscuit – Sunset Lover</li><li>Youssoupha – DIEU EST GRANDE</li><li>Chinese Man – Get Up</li><li>Chilla – Si j’étais un homme</li><li>Caballero &amp; JeanJass – Constellation</li><li>Jahneration (feat. Naâman) – Control Your Tempa</li><li>Barrett – Embeli</li><li>Nasaya &amp; Sara Diamond</li><li>Demain demain – Blick Bassy…</li><li>Nout' Kiltir – Secteur 410…</li><li>Au café du canal – Pierre Perret…</li><li>Dans Ma Rue – Féfé</li><li>The Lighthouse – Applause</li><li>Kreol Superstar – Secteur 410…</li><li>So Good – SSKYRON</li><li>La symphonie des éclairs – Zaho de Sagazan</li><li>Comic sans MS – Caballero &amp; JeanJass, Adèle Castillon</li><li>Self Reflection – Nagaï</li><li>Let Me Go – Branko, Nonku Phiri &amp; Mr. Carmack</li><li>Cold Was the Ground – The Limiñanas</li><li>Mi Ve Pa Marye – Melanie Pérès</li></ul><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/731342427027520889/">arlequisa almeida</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/2025-06-16-djmatyo-live-reunion</link><guid>https://blog.darkwood.com/article/2025-06-16-djmatyo-live-reunion</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>🔊 2025-06-23 DJMatyo Live</title><pubDate>Tue, 24 Jun 2025 07:55:51 +0000</pubDate><description><![CDATA[Youtube

Soundcloud
DJ Matyo · 🔊 2025-06-23 DJMatyo Live
Tracklist

01 - DK Productions - Chandelier - OUT NOW ON EXCITE DIGITAL
02 - SDJ - Live Set 19/8/23 - Happy Hardcore
03 - Music Makes Me Happy Mix
04 - Bidz &amp;amp; Duddy - Bonkers 31st March Promo Mix...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/685a5a071fd5f827995376.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/YBgKPjFRvIk?si=i9uru05MaL8Mo3oN" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Soundcloud</h2><div class="ratio ratio-16x9"><iframe width="100%" height="300" scrolling="no" frameborder="no" allow="autoplay" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/2118589398&color=%23ff5500&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true&visual=true"></iframe><div style="font-size: 10px; color: #cccccc;line-break: anywhere;word-break: normal;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; font-family: Interstate,Lucida Grande,Lucida Sans Unicode,Lucida Sans,Garuda,Verdana,Tahoma,sans-serif;font-weight: 100;"><a href="https://soundcloud.com/djmatyo91" title="DJ Matyo" target="_blank" style="color: #cccccc; text-decoration: none;">DJ Matyo</a> · <a href="https://soundcloud.com/djmatyo91/2025-06-23-djmatyo-live" title="🔊 2025-06-23 DJMatyo Live" target="_blank" style="color: #cccccc; text-decoration: none;">🔊 2025-06-23 DJMatyo Live</a></div></div><h2>Tracklist</h2><ul><li>01 - DK Productions - Chandelier - OUT NOW ON EXCITE DIGITAL</li><li>02 - SDJ - Live Set 19/8/23 - Happy Hardcore</li><li>03 - Music Makes Me Happy Mix</li><li>04 - Bidz &amp; Duddy - Bonkers 31st March Promo Mix</li><li>05 - SDJ - August 2022 UK Hardcore Mix</li><li>06 - SDJ - Live Set 3/4/23 - The Holiday Mix!</li><li>07 - DANNY R - CORE FT PAUL REPLEAY - ISLAND IN THE SEA (ORIGINAL MIX)</li><li>08 - these tunes Squad-e</li><li>09 - Klubfiller - Feel Alive (DJC Remix)</li><li>10 - Best Of Dj Alan Benn 23 Track Mix</li><li>11 - PEACHES - Jack Black (WYLD REMIX)   Free Download</li><li>12 - The Classics Mix</li><li>13 - Tunesday/Tear Out Tuesday's 130722</li><li>14 - Mob - Ravers Reunited AIR NYE 22-23</li><li>15 - Dictiondj, Perkins &amp; Samurai DJ - Goodfellas (Original Mix)</li><li>16 - Banging Bounce Podcast Episode 05 FEAT DJ Fish.mp3</li><li>17 - Mikey Cee - UK BOUNCE .....⭐️</li><li>18 - Slamma production mix by AntX</li><li>19 - Corefinity Presents - The Winter Warm Up - Promo Mix - Defective</li><li>20 - MellowD - Come Closer</li><li>21 - SD216 Brett Cooper - Leave Me Alone. Release 29/03/2023</li><li>22 - Jay G &amp; Arnie Here Forever (Out Now)</li><li>23 - Mikey P &amp; Gee - This Is The Future</li><li>24 - Core Control 137</li><li>25 - FREE DOWNLOAD -R3hab &amp; NERVO &amp; Ummet Ozcan - Revolution (GANAH'S POWERBOOTY)</li><li>26 - Defective - Weekend <em>OUT NOW ON BANDCAMP</em></li><li>27 - Tranquilla [Radio Edit] OUT NOW</li></ul><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/731342427027520889/">arlequisa almeida</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/2025-06-23-djmatyo-live</link><guid>https://blog.darkwood.com/article/2025-06-23-djmatyo-live</guid><enclosure url="http://darkwood.com/media/articles/685a5a071fd5f827995376.jpg" /></item><item><title>How I Connected Cursor to Slack to Automate My AI Workflows</title><pubDate>Sun, 29 Jun 2025 17:29:12 +0000</pubDate><description><![CDATA[

“Write me a Symfony app.”
That’s all it takes — if you say it to Cursor inside Slack.
But what if you want to automate that request?

In this article, I’ll show you how I integrated Cursor, the AI-powered IDE, directly into Slack, and then went one step f...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/686aa38c34965057983880.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/lrmWUjyn0I4?si=t6VG3JkIh8AL0-6u" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><blockquote><p><em>“Write me a Symfony app.”</em>
That’s all it takes — if you say it to Cursor inside Slack.
But what if you want to automate that request?</p></blockquote><p>In this article, I’ll show you how I integrated Cursor, the AI-powered IDE, directly into Slack, and then went one step further by building a custom Slack app in Symfony to automate those interactions. Finally, I’ll show how I used Flow, my functional orchestration system, to scale the whole process.</p><h2>🧠 Why Connect Cursor to Slack?</h2><p>Cursor recently introduced a native Slack integration: you can now simply write <code>@Cursor fix the login bug</code> in a channel, and it will launch a background agent that:</p><ul><li>Reads the conversation context</li><li>Applies fixes to your repo</li><li>Creates a pull request on GitHub</li></ul><p>It’s magical — especially for fast-paced teams working in Slack all day.</p><p>Official docs: <a href="https://docs.cursor.com/slack">https://docs.cursor.com/slack</a></p><h2>⚙️ Connect Cursor to Slack</h2><p>From your Cursor dashboard:</p><ol><li>Go to Integrations</li><li>Click Connect Slack</li><li>Choose a repo, configure your default settings</li><li>You’re done — now just mention <code>@Cursor</code> in Slack!</li></ol><p>From there, you can use commands like:</p><pre><code class="language-text">@Cursor settings
@Cursor list my agents
@Cursor [repo=my-org/project, branch=main] fix validation
</code></pre><p>It’s already powerful. But what if you want to automate it?</p><h2>🛠️ Build a Slack App with Symfony</h2><p>To automate Slack messages, I created a custom Slack app with OAuth 2.0. The app retrieves a user token (<code>xoxp-...</code>) that allows my Symfony backend to:</p><ul><li>List Slack conversations</li><li>Post messages</li><li>Retrieve users (to mention <code>@Cursor</code> by ID)</li></ul><p>Using <code>ngrok</code> to expose my local server, I implemented an OAuth callback in Symfony and configured the Slack app with:</p><ul><li><code>chat:write</code></li><li><code>channels:read</code></li><li><code>users:read</code></li></ul><p>👉 Full code available here:
📦 <a href="https://github.com/matyo91/cursor-slack-symfony">https://github.com/matyo91/cursor-slack-symfony</a></p><h2>🤖 Automate with Flow</h2><p>Cursor only responds to human mentions of <code>@Cursor</code>.
Slack does not yet allow bots to trigger app mentions like that.</p><p>But here’s the workaround: I used Flow, my automation orchestrator (built in Symfony), to:</p><ul><li>List Slack channels</li><li>Identify the right one (e.g. <code>#social</code>)</li><li>Find the user ID for Cursor</li><li>Format the message (<code>&lt;@UXXXXXXX&gt; write me a Hello World in PHP</code>)</li><li>Post the message using a real user token</li></ul><h2>🚀 What’s Next? Try It with Uniflow</h2><p>If you’re tired of cobbling scripts together, you can build this kind of automation visually using <a href="https://uniflow.io">Uniflow</a> — my no-code tool for developers.</p><p>With Uniflow, you can:</p><ul><li>Automate Slack flows without writing boilerplate</li><li>Chain events between GitHub, Slack, Notion, and more</li><li>Deploy orchestrations with logs, retries, and conditionals</li></ul><p>💡 I use Flow as the core engine in Uniflow.
So if you like this article, you’ll love what we’re building at <a href="https://uniflow.io">https://uniflow.io</a></p><h2>🧪 Want to Try It?</h2><p>Check out the full source code for the Slack + Cursor integration on GitHub:
👉 <a href="https://github.com/matyo91/cursor-slack-symfony">https://github.com/matyo91/cursor-slack-symfony</a></p><p>And if you’d rather click than code, head over to:
🌐 <a href="https://uniflow.io">https://uniflow.io</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/how-i-connected-cursor-to-slack-to-automate-my-ai-workflows-2-1</link><guid>https://blog.darkwood.com/article/how-i-connected-cursor-to-slack-to-automate-my-ai-workflows-2-1</guid><enclosure url="http://darkwood.com/media/articles/686aa38c34965057983880.png" /></item><item><title>✨ PHP 8.5&#039;s new operator will change the way you code</title><pubDate>Sun, 06 Jul 2025 16:28:11 +0000</pubDate><description><![CDATA[
PHP 8.5 is just around the corner, and with it comes a long-awaited addition: the pipe operator (|&amp;gt;). This seemingly small feature might have a huge impact on how we write and structure our code—especially for developers who lean toward a more functiona...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/686aa41b75281487120824.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/RbX6YQj5w8g?si=XmzGNhWmMNizmtWq" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>PHP 8.5 is just around the corner, and with it comes a long-awaited addition: the pipe operator (<code>|&gt;</code>). This seemingly small feature might have a huge impact on how we write and structure our code—especially for developers who lean toward a more functional style.</p><p>In this article, I’ll explain what the pipe operator does, why it matters, and how you can start using it to write cleaner, more expressive PHP. We'll also look at practical examples and some caveats to keep in mind.</p><h2>💡 What Is the Pipe Operator?</h2><p>The pipe operator allows you to pass a value to a function as its first argument, making function chaining much more readable.</p><p>Here’s a quick example:</p><pre><code class="language-PHP">$string = &quot; Hello World &quot;
  |&gt; trim(...)
  |&gt; strtolower(...)
  |&gt; fn($string) =&gt; str_replace(' ', ' ', $string);
</code></pre><p>This is equivalent :</p><pre><code class="language-PHP">$string = &quot; Hello World &quot;;
$string = trim($string);
$string = strtolower($string);
$string = str_replace(' ', '-', $string);
</code></pre><p>It’s the same logic—but way more expressive.</p><h2>🧠 Why It Matters</h2><p>The pipe operator brings several benefits:</p><ul><li>✅ Improved readability: Less nesting, more clarity.</li><li>✅ Encourages smaller, pure functions: Perfect for data pipelines.</li><li>✅ Moves PHP closer to functional programming concepts.</li><li>✅ Comes with compiler-level optimization for performance.</li></ul><p>In short: it’s more elegant, less verbose, and aligns PHP with modern programming paradigms.</p><h2>🚫 Limitations to Know</h2><p>Before you go rewriting your entire codebase, here are a few gotchas:</p><ul><li>It only works with functions that accept a single argument.</li><li>It does not support arguments passed by reference.</li><li>It’s currently not compatible with multiple-parameter functions unless partially applied (which isn’t yet part of PHP natively).</li></ul><p>But for common transformations—strings, arrays, filtering, formatting—it’s perfect.</p><h2>🧪 Project source code</h2><p>You can find the source code of this video: <a href="https://github.com/matyo91/php-pipe-operator">https://github.com/matyo91/php-pipe-operator</a></p><h2>🚀 What's Next?</h2><p>PHP 8.5 is set for official release in November 2025. Until then, you can try it by compiling PHP from source or using a Docker image from the nightly builds.</p><h2>⚙️ Bonus: Automate Your Dev Workflows</h2><p>If you’re interested in automating your development workflows (like generating content, syncing code, or publishing releases), check out <a href="https://uniflow.io">Uniflow</a> — the no-code orchestration platform I’m building.</p><p>It integrates perfectly with PHP-based tools and lets you build automations using a visual flow editor — no extra boilerplate needed.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/php-8-5s-new-operator-will-change-the-way-you-code</link><guid>https://blog.darkwood.com/article/php-8-5s-new-operator-will-change-the-way-you-code</guid><enclosure url="http://darkwood.com/media/articles/686aa41b75281487120824.png" /></item><item><title>Symfony AI will change everything!</title><pubDate>Tue, 15 Jul 2025 07:50:57 +0000</pubDate><description><![CDATA[
Symfony AI is here and it&#039;s a game-changer.
On July 11, 2025, Fabien Potencier announced a major new initiative: Symfony AI – a suite of official components to bring artificial intelligence into your PHP applications, natively and powerfully.
This initiati...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/687608614fb75152659730.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/nscptYXOgr0?si=BRlhQJcxoFECkrF_" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Symfony AI is here and it's a game-changer.
On July 11, 2025, Fabien Potencier announced a major new initiative: Symfony AI – a suite of official components to bring artificial intelligence into your PHP applications, natively and powerfully.</p><p>This initiative consolidates and evolves the work done under the <code>php-llm</code> organization into a dedicated monorepo: <a href="https://github.com/symfony/ai"><code>symfony/ai</code></a>. It aims to provide developers with a modern, unified way to interact with LLMs, build agents, and implement Retrieval-Augmented Generation (RAG) workflows directly within Symfony.</p><h2>🧩 Core Components of Symfony AI</h2><p>Symfony AI includes several powerful tools:</p><ul><li><p>Platform Component
A unified abstraction to query OpenAI, Mistral, Anthropic, Google, Azure, and more – write your code once, switch providers anytime.</p></li><li><p>Agent Component
Design intelligent agents capable of reasoning, calling tools, storing memory, and managing dialogues. Ideal for complex workflows and autonomous chatbots.</p></li><li><p>Store Component
Perfect for implementing RAG patterns. Store and retrieve embeddings using vector stores to augment LLM responses with your own domain knowledge.</p></li><li><p>AI Bundle
The glue that integrates all components with Symfony’s ecosystem: services, configuration, and debug tools.</p></li><li><p>MCP SDK &amp; MCP Bundle
These let your Symfony app act as a server or client of the Model Context Protocol (MCP), enabling tool calling and structured communication with agents like Claude or GPT.</p></li></ul><h2>⚙️ Real-world Use Case: Email Assistant with Composio</h2><p>In my demo, I used Symfony AI with the <a href="https://composio.dev">Composio Dev</a> platform to build an AI-powered email reader.</p><p>By combining:</p><ul><li>Composio’s toolchain (Gmail, Calendar, etc.),</li><li>Symfony MCP integration,</li><li>Claude 3.7 via the Agent component,</li><li>And Flow (my own orchestrator),</li></ul><p>…I was able to create a command-line AI agent that fetches and summarizes my latest Gmail messages using a simple prompt:
&quot;Fetch my last email&quot;.</p><p>The agent handled the full chain:</p><ul><li>Identified the tool via MCP</li><li>Called the Gmail API</li><li>Parsed the email content</li><li>Returned a structured, summarized response.</li></ul><h2>🧪 From Demo to Production</h2><p>I showcased how to:</p><ul><li>Install Symfony AI in a project via <code>composer</code></li><li>Configure your <code>.env</code> with the required API keys (OpenAI, Claude, etc.)</li><li>Run the provided demo (including blog RAG indexing)</li><li>Extend it with your own agents using custom tool integrations</li></ul><p>I also used <code>make + nix-shell</code> to run everything locally using PHP 8.3, and demonstrated how to migrate a project from <code>php-llm</code> to Symfony AI with almost no effort.</p><h2>🧠 Orchestrate with Flow</h2><p>In the second part of the video, I integrated Symfony AI into Flow, my orchestrator framework, to chain tasks like:</p><ul><li>Fetching email</li><li>Piping content to Claude</li><li>Formatting or forwarding results</li></ul><p>This modularity allows you to reuse tools and agents across workflows – all in PHP.</p><h2>🙌 Get Involved</h2><p>Symfony AI is still in its early days, and you can help shape it.
➡️ Contribute on GitHub: <a href="https://github.com/symfony/ai">https://github.com/symfony/ai</a>
➡️ Explore open issues, suggest features, or test the demo app.</p><p>Want to go further?
You can also contribute to my open-source project that integrates Symfony AI + Composio + Flow : <a href="https://flow.darkwood.com">https://flow.darkwood.com</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/symfony-ai-will-change-everything</link><guid>https://blog.darkwood.com/article/symfony-ai-will-change-everything</guid><enclosure url="http://darkwood.com/media/articles/687608614fb75152659730.png" /></item><item><title>✈️ I&#039;m going to code in Las Vegas on Symfony AI</title><pubDate>Sun, 20 Jul 2025 23:29:12 +0000</pubDate><description><![CDATA[
When you travel to Las Vegas, people expect poker chips and party lights. I brought a laptop, a terminal, and a crazy idea: build smart agents with Symfony AI.
Why Vegas?
Las Vegas might seem like an odd choice for a developer retreat — unless your goal is...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/687d7bc853d63765085318.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/P4SF1pP2WrE?si=tFp_LXDv1NoAgrfX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>When you travel to Las Vegas, people expect poker chips and party lights. I brought a laptop, a terminal, and a crazy idea: build smart agents with Symfony AI.</p><h2>Why Vegas?</h2><p>Las Vegas might seem like an odd choice for a developer retreat — unless your goal is to escape routine and seek inspiration from organized chaos.</p><p>As a city that never sleeps, Vegas is a strange symphony of light, motion, and endless interaction. And that’s exactly what I needed: a place that feels alive, dynamic, and just a little bit unreal. What better place to reflect on artificial intelligence, orchestration, and system design than a city built on illusion and real-time performance?</p><h2>First Class, First Deployment</h2><p>I boarded a first-class flight — not just for comfort (okay, a little for that), but because I had serious work to do. I’m currently building advanced automation flows with Symfony AI and the Model Context Protocol (MCP).</p><p>Mid-flight, as I was just getting settled with a glass of champagne, I received the classic Slack ping:</p><p>🔴 Urgent: Production is down</p><p>A client had deployed a faulty configuration that caused the entire stack to collapse. No time to panic — just Wi-Fi, ssh, and Symfony AI.</p><p>Agents to the Rescue
Thankfully, I had already started integrating Symfony AI with a custom agent system. These agents are capable of analyzing logs, identifying error patterns, and performing safe rollbacks when necessary.</p><p>In this case, one of my agents scanned the latest logs, traced the issue to a faulty deployment, and triggered a rollback using a predefined ToolAction. I had designed this flow to work as part of a broader Toolbox of smart operations exposed to the AI layer via attributes like AsTool.</p><p>✅ Problem solved.<br />
✅ Client happy.<br />
✅ Uptime preserved — all from 10,000 meters in the air.</p><h2>Walking the Strip, Thinking About Agents</h2><p>Once I landed, I took some time to walk through Las Vegas. The streets are an overwhelming experience: neon signs, massive screens, constant music, and people in all directions. But here’s the thing — it works. Everything is chaotic, yet orchestrated. Each piece — hotels, shows, lights — plays a role in a giant system.</p><p>It reminded me of how I want my automation agents to behave:</p><ul><li>Smart.</li><li>Reactive.</li><li>Coordinated.</li></ul><p>Imagine agents in Symfony AI that know when to trigger, how to execute an action, and how to work in harmony with others — just like the sensory experience of Vegas, built on synchronization.</p><p>Enter MCP: Model Context Protocol
I believe the Model Context Protocol (MCP) is the key to building AI systems that behave more like living organisms. Using Symfony AI + MCP, I’m working on enabling agents that:</p><p>React based on context, not just instructions.</p><p>Share state and intent across flows.</p><p>Execute autonomous decisions via ToolAction and semantic prompts.</p><p>This trip wasn’t just a break — it was a proof of concept, a mindset shift, and a step forward in building Uniflow, my automation tool for developers and creators.</p><p>What’s Next?
I’m currently working on:</p><ul><li>Migrating Uniflow’s interface to Symfony UX</li><li>Publishing the first public MCP demo flows</li><li>Expanding the AI agent architecture using php-llm/llm-chain and mcp-sdk</li></ul><p>If you’re curious, you can already explore:</p><p>📘 The documentation.<br />
🧠 The Uniflow platform.<br />
📰 The blog for regular updates.</p><h2>Final Thoughts</h2><p>This trip reminded me why I love building: because automation isn’t just about saving time — it’s about giving intelligence and rhythm to our tools. Las Vegas may be the city of games, but for me, it became a playground for code.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate your processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let’s build smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/im-going-to-code-in-las-vegas-on-symfony-ai</link><guid>https://blog.darkwood.com/article/im-going-to-code-in-las-vegas-on-symfony-ai</guid><enclosure url="http://darkwood.com/media/articles/687d7bc853d63765085318.png" /></item><item><title>📝 Retour sur le meetup AFUP Paris de juillet : IA, Recrutement &amp; Élection</title><pubDate>Fri, 25 Jul 2025 07:19:49 +0000</pubDate><description><![CDATA[Hier soir, j’ai eu le plaisir de participer au meetup AFUP Paris du jeudi 24 juillet 2025, organisé dans les locaux de Web Atrio, à deux pas du Louvre. Une soirée riche en contenus, en échanges… et en réflexions concrètes sur l’avenir du développement PHP e...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68833c3a684e5946549222.png" /></p><p>Hier soir, j’ai eu le plaisir de participer au meetup AFUP Paris du jeudi 24 juillet 2025, organisé dans les locaux de Web Atrio, à deux pas du Louvre. Une soirée riche en contenus, en échanges… et en réflexions concrètes sur l’avenir du développement PHP et des développeurs eux-mêmes.</p><h2>🧭 Ouverture de la soirée : actualités PHP &amp; vie de l’AFUP</h2><p>C’est <strong>Thomas Dutrion</strong> qui lance la soirée en partageant un tour d’horizon des dernières <strong>actualités de l’écosystème PHP</strong>. Au programme : les nouveautés techniques marquantes, les prochains meetups à noter dans l’agenda, et un rappel sur l’importance des <strong>élections locales de l’AFUP</strong>, qui permettent de faire vivre la communauté à Paris.</p><p>Thomas encourage chacun à <strong>s’impliquer dans l’orientation des contenus à venir</strong> : un QR code a été partagé pour recueillir les idées de talks, les suggestions de sujets ou de formats. L’équipe bénévole fait régulièrement le point en début de mois, pour coller au plus près des attentes de la communauté.</p><p>Il conclut avec un mot chaleureux :</p><blockquote><p>&quot;Merci à <strong>Web Atrio</strong> qui nous accueille ce soir, ce n’est pas la première fois qu’ils ouvrent leurs portes à l’AFUP, et en plus, ils nous offrent l’apéro. C’est toujours un plaisir de collaborer avec eux.&quot;</p></blockquote><h3>🏢 À propos de Web Atrio</h3><p>Un représentant de <strong>Web Atrio</strong> prend ensuite la parole pour une courte présentation. Fondée il y a 12 ans par trois ingénieurs passionnés, <strong>Web Atrio</strong> est une <strong>ESN spécialisée dans le développement d’applications web</strong>. Elle repose sur une culture profondément technique, avec aujourd’hui <strong>plus de 100 collaborateurs</strong> répartis entre les agences de Paris, Lyon et Toulouse.</p><p>Le ton reste informel et sincère :</p><blockquote><p>&quot;On ne va pas vous faire un speech commercial, l’idée c’est surtout de faire partie de l’écosystème, d’échanger entre techs, et de vous accueillir dans les meilleures conditions.&quot;</p></blockquote><p>Pour en savoir plus : <a href="https://web-atrio.com/">web-atrio.com</a></p><h2>Deux talks inspirants pour une communauté en mouvement</h2><h3>🧠 Créer un serveur MCP avec Symfony – <em>Edouard Courty</em></h3><p>Premier à prendre la parole, Edouard Courty nous a présenté comment transformer une IA en véritable agent opérationnel, en lui permettant d’interagir directement avec une application Symfony grâce au protocole MCP (Model Context Protocol).</p><p>À l’aide d’exemples concrets, il a montré comment un serveur MCP peut connecter des LLMs comme GPT à des outils métier, en toute sécurité, via Symfony. Un talk technique, mais limpide, qui ouvre des perspectives impressionnantes pour les développeurs backend qui souhaitent embarquer de l’IA dans leurs projets de manière structurée.</p><blockquote><p>« Donner du pouvoir aux IA, ça passe par Symfony. »</p></blockquote><p>Voici un résumé clair et structuré du talk d’Édouard Courty au meetup AFUP Paris du 24 juillet 2025 :</p><h2>🎙️ <em>Créer un serveur MCP avec Symfony</em> – par Édouard Courty</h2><p>Édouard Courty, développeur chez Cézanne, a présenté un sujet aussi visionnaire que pratique : comment donner à une intelligence artificielle le pouvoir d’agir — et non plus seulement de répondre — grâce à un serveur MCP implémenté en Symfony.</p><h3>📌 Pourquoi MCP ?</h3><p>Edouard part d’un constat simple : les LLMs (comme GPT) sont capables de comprendre et générer du contenu, mais ils ne savent rien faire par eux-mêmes. Impossible pour eux de modifier une playlist Spotify, ou d’interagir avec des services concrets comme une base de données ou une API métier.</p><p>➡️ Le problème : ces IA sont cloisonnées.<br />
➡️ La solution : leur donner accès à des outils réels via un protocole sécurisé.</p><h3>🔧 Qu’est-ce que le MCP (Model Context Protocol) ?</h3><p>Le MCP est un protocole qui permet à une IA (appelée <em>agent</em>) de se connecter à un serveur et d’utiliser des tools, resources ou prompts disponibles sur ce serveur.</p><ul><li>Tools : exécution de logique métier (ex : scrapper une page web)</li><li>Resources : tout type de contenu servi (fichiers, vidéos, etc.)</li><li>Prompts : modèles réutilisables, centralisés, de prompt engineering</li></ul><p>Le fonctionnement repose sur une architecture client/serveur, avec communication via HTTP ou STDIO (dans certains cas locaux).</p><h3>🛡️ Sécurité</h3><p>Edouard insiste sur l’importance de la sécurisation des endpoints : un agent ne doit jamais pouvoir accéder à des outils critiques sans authentification. Le protocole recommande l’usage d’OAuth2 pour encadrer les accès, en plus des bonnes pratiques API classiques.</p><h3>🧰 Symfony au cœur du dispositif</h3><p>Edouard a développé un bundle Symfony open source, appelé <code>MCP Server Bundle</code>, compatible Symfony 6.4 et 7.3.</p><p>Ce bundle permet de :</p><ul><li>gérer le transport et la discovery automatique</li><li>déclarer ses tools avec des attributs PHP</li><li>chaîner les appels pour créer de véritables workflows intelligents</li></ul><h3>⚙️ Démo live : récupérer le HTML d’une URL</h3><p>Il a montré en direct comment une IA pouvait utiliser un tool Symfony pour accéder à une page web, récupérer son HTML, puis enchaîner avec d’autres tools (ex : analyse de contenu).</p><p>💡 Le code est simple : une classe PHP <code>__invoke()</code> décorée d’un attribut <code>#[AsTool]</code> — le reste est géré par le bundle.</p><h3>🔗 Code source et documentation</h3><p>Le code source du bundle MCP Server est disponible sur GitHub : <a href="https://github.com/EdouardCourty/mcp-server-bundle">EdouardCourty/mcp-server-bundle</a></p><p>Ce bundle open source permet d'implémenter facilement un serveur MCP compatible avec le protocole dans sa version <code>2025-06-18</code>. Il offre :</p><ul><li>Une intégration native avec Symfony 6.4 et 7.3</li><li>Un système d'attributs PHP pour déclarer des tools, resources et prompts</li><li>Une gestion automatique des requêtes JSON-RPC</li><li>Des événements pour étendre le comportement par défaut</li><li>Des commandes de debug pour faciliter le développement</li></ul><h3>🔭 Vision</h3><p>Ce talk ne se contente pas de montrer une techno : il ouvre une vision du futur où les agents IA dialoguent avec nos services via MCP, où les développeurs deviennent architectes d’interfaces entre monde réel et intelligence artificielle.</p><blockquote><p>“L’IA est là pour rester. À nous de la rendre utile. MCP est un standard en devenir.”</p></blockquote><h2>🎙️ <em>Comment trouver un job quand le marché est pourri et qu’il n’y a rien à attendre de LinkedIn ?</em> – par Jean-Michel Fayard</h2><p>Le second talk, animé par Jean-Michel Fayard, était plus pragmatique mais tout aussi percutant. Dans un contexte de marché du travail en tension pour les développeurs, il a partagé des stratégies concrètes pour ne pas sombrer dans la spirale de LinkedIn et reprendre le pouvoir sur sa carrière.</p><p>Ses conseils ont résonné auprès de beaucoup d’entre nous : créer du contenu, cibler les bons réseaux, reprendre confiance en sa valeur, et oser aller là où on ne nous attend pas. Un talk motivant qui a déclenché pas mal de discussions après coup — preuve qu’il a touché juste.</p><blockquote><p>« Si tu attends que LinkedIn t’apporte un job, tu risques d’attendre longtemps. »</p></blockquote><p>Dans un ton libre, engagé et souvent drôle, Jean-Michel Fayard a livré une présentation sans filtre sur les dérives du recrutement tech, les erreurs classiques des développeurs en recherche d’emploi… et surtout les clés pour reprendre le pouvoir sur sa carrière.</p><h3>🎯 Objectif : cesser de subir, et redevenir acteur de son recrutement</h3><p>Jean-Michel part d’un constat simple mais brutal : le marché de l’emploi tech en 2025 est tendu. Moins de budget, plus d’attente, plus de concurrence. Et LinkedIn ne suffit plus.</p><p>Plutôt que d’espérer, il invite à changer de posture : ne pas être simplement un “bon dev” mais aussi un “bon candidat” — avec les compétences <em>différentes</em> que cela implique.</p><blockquote><p>« Un bon dev ne fait pas forcément un bon candidat. Et inversement. »</p></blockquote><h3>💡 Concepts clés du talk</h3><p>🔄 Le recrutement est une danse à deux : il faut comprendre les enjeux des recruteurs comme ceux des candidats.<br />
🧠 Le recrutement inversé : comme dans certaines danses sociales, c’est à nous, développeurs, d’initier la démarche, de pitcher, d’identifier ce qu’on veut — et de l’assumer.<br />
🧱 La carrière comme une startup personnelle : branding, marketing, vente, structuration. À chacun de se former et de penser sa carrière comme un produit qu’on sait positionner.</p><h3>🧪 Exemples concrets &amp; mauvaises pratiques</h3><p>Jean-Michel a décortiqué un florilège d’erreurs courantes dans le processus de recrutement :</p><p>❌ Les annonces sans salaires : inefficaces et peu transparentes.<br />
❌ Les recruteurs qui posent des questions de salaires dès le premier appel : illégal, manipulateur, toxique.<br />
❌ Les fiches de poste absurdes : “moutons à cinq pattes”, culture d’entreprise floue, jargon bullshit.<br />
❌ Les entretiens techniques mal calibrés : whiteboard, brain teasers, culture de l’ego.<br />
❌ Les recruteurs qui ne savent pas qu’ils ne savent pas recruter…</p><p>Il dénonce aussi l’hypocrisie généralisée du process : les devs ont des compétences rares et précieuses, mais ils sont souvent mal armés pour “se vendre”.</p><h3>🔄 Le changement de mindset proposé</h3><blockquote><p>« Si tu ne décroches pas d’entretien, ce n’est pas que tu es un mauvais dev. C’est peut-être juste que tu es un mauvais candidat. Et ça, <em>ça s’apprend</em>. »</p></blockquote><p>Jean-Michel insiste sur le fait qu’il ne suffit pas de “monter en compétences” en tech si on ne maîtrise pas les compétences amont (se présenter, pitcher, comprendre les attentes du marché).</p><p>Il propose un raisonnement simple :</p><ul><li>Tu n’as pas d’entretien ? → Tu as un problème de <em>marketing</em>.</li><li>Tu as des entretiens mais tu échoues ? → Tu as un problème de <em>vente</em> (présentation).</li><li>Tu acceptes des postes que tu ne veux pas ? → Tu n’as pas assez clarifié ton <em>positionnement</em>.</li></ul><h3>🧭 Conclusion</h3><p>Jean-Michel ne donne pas une méthode miracle, mais un appel à l’action :
👉 former les développeurs à leur propre <em>emploiabilité</em>,<br />
👉 leur redonner le pouvoir sur leur carrière,<br />
👉 et faire en sorte que ce ne soient plus les plus extravertis qui gagnent… mais les plus conscients.</p><blockquote><p>« Le marché est une jungle. Alors équipez-vous. »</p></blockquote><h3>🔗 Pour aller plus loin</h3><p>Jean-Michel a partagé un article détaillant son intervention sur son blog personnel. Vous y retrouverez ses réflexions complètes sur le recrutement inversé et la recherche d'emploi en période difficile.</p><p>👉 <a href="https://substack.jmfayard.dev/p/meetup-afup-2025">Recherche de taf et recrutement inversé - mon talk au Meetup AFUP Paris</a></p><p>Il y partage également d'autres ressources utiles pour les développeurs en recherche d'emploi, notamment :</p><ul><li>Des articles spécifiques sur les pièges du recrutement</li><li>Son repo GitHub avec des conseils pratiques</li><li>Des moyens de le contacter pour des questions individuelles</li></ul><h2>Une soirée citoyenne : les élections de l’antenne AFUP Paris</h2><p>Le meetup s’est clôturé avec un moment important pour la communauté : les élections de l’antenne locale. Comme chaque année, coordinateur et modérateur ont été (ré)élus pour faire vivre l’AFUP Paris, aidés par de nombreux bénévoles sans qui rien ne serait possible. Merci à eux pour leur engagement continu 🙏</p><h2>Merci à Web Atrio pour l’accueil</h2><p>Un grand merci à Web Atrio pour l’accueil chaleureux dans leurs locaux du 1er arrondissement. Leur engagement pour les bonnes pratiques PHP et la communauté est toujours au rendez-vous, et ça fait plaisir de se retrouver dans un cadre aussi bienveillant que professionnel.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/retour-sur-le-meetup-afup-paris-de-juillet-ia-recrutement-election-1-1</link><guid>https://blog.darkwood.com/article/retour-sur-le-meetup-afup-paris-de-juillet-ia-recrutement-election-1-1</guid><enclosure url="http://darkwood.com/media/articles/68833c3a684e5946549222.png" /></item><item><title>How I generate €10,000/month thanks to Symfony AI</title><pubDate>Sun, 27 Jul 2025 16:10:59 +0000</pubDate><description><![CDATA[
What if your Symfony app could read your emails, qualify leads, generate quotes, and reply with your personal tone — all without you touching a keyboard?
I built exactly that.
And yes, I now generate over €10,000/month with automated workflows powered enti...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68864f93719b8975338630.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/1PcgXd4Y1CA?si=q8MbewH2Si3qpiyx" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>What if your Symfony app could read your emails, qualify leads, generate quotes, and reply with your personal tone — all without you touching a keyboard?</p><p>I built exactly that.</p><p>And yes, I now generate over <strong>€10,000/month</strong> with automated workflows powered entirely by <strong>Symfony AI</strong> and <strong>Uniflow</strong> — my own open automation stack.</p><h3>🧠 From Framework to Workforce: Enter Symfony AI</h3><p>At first, I used Symfony like everyone else: solid backend, admin dashboards, and APIs.</p><p>Then I discovered <strong>Symfony AI</strong> a set of components and bundles that turned Symfony into something bigger:</p><ul><li><strong>Platform</strong>: unified access to OpenAI, Anthropic, Azure, Google, etc.</li><li><strong>Agent</strong>: a framework for creating task-oriented AI agents</li><li><strong>Store</strong>: vector storage with indexing and retrieval</li><li><strong>MCP SDK</strong>: the real gem — it lets agents talk to tools via a clean, typed protocol</li><li><strong>AI Bundle &amp; MCP Bundle</strong>: integration with Symfony for seamless tooling</li></ul><p>With this, I built an agent I now call <em>Bernard</em>.</p><h3>⚙️ What Bernard Does (While I Sleep)</h3><p>Whenever a lead emails me:</p><ul><li>Bernard reads the email</li><li>Analyzes the request via GPT (through <code>symfony/ai-platform</code>)</li><li>Checks my availability</li><li>Generates a quote PDF</li><li>Sends a fully personalized reply</li></ul><p>All of this runs in a Symfony command or can be triggered via Flow UI.</p><p>Result: I’ve closed <strong>12 contracts last month</strong> — and barely opened my inbox.</p><h3>📈 My Stack (You Can Copy It)</h3><ul><li><strong>Symfony AI</strong></li><li><strong>Uniflow</strong> (flow orchestration, publishing, and templates)</li><li><strong>Google Calendar + IMAP</strong> for external data sync</li><li><strong>Mailer</strong> (to send replies with real human tone — still GPT-written)</li></ul><h3>🔥 Why This Works</h3><ul><li>I respond instantly, 24/7</li><li>The tone is <em>me</em> — funny, to the point, and relevant</li><li>I stopped wasting time on cold leads</li><li>I reinvest my time into building new flows (that I can sell)</li></ul><p>Some flows I’ve seen go even further:</p><ul><li>Automated audit generation</li><li>NLP-driven CV screening</li><li>Real-time proposal writing based on incoming briefs</li></ul><h3>🌍 And What’s Coming Next</h3><p>I’m now working on <strong>Uniflow’s full refactor</strong> with Symfony UX, a public flow library, and an open marketplace where you’ll be able to create, share and even sell your automation flows.</p><h3>🚀 Want the Code?</h3><p>→ Visit <a href="https://uniflow.io">https://uniflow.io</a> to try it.<br />
→ Check out the full MCP stack at <a href="https://github.com/symfony/ai">https://github.com/symfony/ai</a>.<br />
→ Need the exact quote template or my Bernard agent config? Drop “AGENT” in the comments or DM me.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate your processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let’s build smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/how-i-generate-eur10-000-month-thanks-to-symfony-ai</link><guid>https://blog.darkwood.com/article/how-i-generate-eur10-000-month-thanks-to-symfony-ai</guid><enclosure url="http://darkwood.com/media/articles/68864f93719b8975338630.png" /></item><item><title>Je mixe sur Paris au Tennessee Mercredi  30 juillet</title><pubDate>Mon, 28 Jul 2025 21:14:28 +0000</pubDate><description><![CDATA[
Le mercredi 30 juillet 2025, je monterai sur scène pour représenter DJ Matyo91 lors de l&#039;édition de l’Open Mic Groover Club à Paris. Un événement intimiste et bouillonnant d’énergie, organisé par Wassim, Lucie et Paul-Diego, dans un lieu mythique du 6e arr...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68888e495e1db839225206.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/8X2N95PIHuw?si=roU3DLEnfP-7iPEB" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Le <strong>mercredi 30 juillet 2025</strong>, je monterai sur scène pour représenter <strong>DJ Matyo91</strong> lors de l'édition de l’<strong>Open Mic Groover Club</strong> à Paris. Un événement intimiste et bouillonnant d’énergie, organisé par <strong>Wassim, Lucie et Paul-Diego</strong>, dans un lieu mythique du 6e arrondissement : <strong>le Tennessee</strong>, au 12 Rue André Mazet.</p><p>🕢 Accueil à partir de <strong>19h00</strong>, début des hostilités à <strong>19h30</strong>.</p><h2>🎶 Des moments vrais à venir</h2><p>L’été est là, l’ambiance est chill, mais la scène sera bouillante. Groover a proposé à chaque artiste de <strong>chanter jusqu’à trois morceaux</strong>, une belle opportunité pour <strong>dévoiler des facettes plus profondes de nos univers musicaux</strong>.</p><p>De mon côté, je prépare un <strong>set résolument personnel</strong>, entre énergie brute et mélodies euphoriques. Hardcore, HappyHard, French Core… <strong>DJ Matyo91</strong> sera là pour <strong>faire vibrer le dancefloor</strong>.</p><h2>🪩 Ce qui t’attend sur le dancefloor</h2><p>Prépare-toi à une soirée où <strong>le son cogne et la vibe s’élève</strong>.
Je te promets un voyage sonore entre :</p><p>💣 Basslines explosives.<br />
🎶 Transitions nerveuses et montées sous tension.<br />
🔥 Pépites underground et classiques revisités.<br />
🤝 Une ambiance collective, bienveillante et survoltée.</p><p>Tu danseras sans regarder l’heure.
Tu chanteras, tu transpireras… et tu en redemanderas.</p><h2>📸 Ambiance, émotions &amp; premières vibes</h2><p>Dès les balances à 19h00, l’ambiance promet d’être détendue et joyeusement chaotique : câbles qui s’entremêlent, rires en coulisses, petits stress et grandes attentes.</p><p>Et une fois la soirée lancée, chaque passage viendra écrire une nouvelle ligne de cette <strong>première édition</strong> : entre voix soul, rap introspectif, pop acoustique ou bangers électroniques, <strong>la scène deviendra un laboratoire d’émotions</strong>.</p><h2>🎥 Bientôt en ligne</h2><p>Un <strong>replay vidéo</strong> sera bientôt disponible sur ma chaîne YouTube :
👉 <a href="https://youtube.com/@djmatyo91">DJ Matyo91 – youtube.com/@djmatyo91</a></p><p>Pense à t’abonner pour ne pas louper la suite : lives, mixs, collabs… et peut-être un EP ? 👀</p><h2>🎁 Ton code Groover exclusif</h2><p>Tu veux toi aussi monter sur scène ?
Utilise mon <strong>code Groover</strong> pour gagner des points et booster ta visibilité :</p><p>👉 <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co/band/referral/2-MATHIEU-9034D/</a></p><h2>🙏 Merci &amp; à mercredi</h2><p>Un grand merci à l’équipe du <strong>Groover Club</strong> pour leur confiance, leur bienveillance, et cette scène ouverte à toutes les vibes.</p><p>Je vous donne rendez-vous <strong>ce mercredi</strong> pour une soirée qui s’annonce <strong>incandescente</strong>. Et si vous voyez passer un flyer &quot;DJ Matyo91&quot; dans les rues de Paris, c’est que je suis déjà en train de préparer la prochaine.</p><p>🎧 <em>Keep vibin’ – DJ Matyo91</em></p>
]]></content:encoded><link>https://blog.darkwood.com/article/je-mixe-sur-paris-au-tennessee-mercredi-30-juillet-1-1</link><guid>https://blog.darkwood.com/article/je-mixe-sur-paris-au-tennessee-mercredi-30-juillet-1-1</guid><enclosure url="http://darkwood.com/media/articles/68888e495e1db839225206.png" /></item><item><title>🔥 Le dancefloor en feu au Tennessee Club de Paris</title><pubDate>Thu, 31 Jul 2025 06:58:53 +0000</pubDate><description><![CDATA[
Ce mercredi 30 juillet 2025, la scène du Tennessee à Paris s’est transformée en véritable laboratoire musical. L’Open Mic Groover Club a réuni une dizaine d’artistes venus partager leurs univers, leurs textes et leurs vibes… dans une ambiance intime, bienv...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/688b142d3737b941511989.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/_h_1LwBn1KI?si=Lb-CJl10yqjLJFVh" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Ce mercredi 30 juillet 2025, la scène du Tennessee à Paris s’est transformée en véritable laboratoire musical. L’Open Mic Groover Club a réuni une dizaine d’artistes venus partager leurs univers, leurs textes et leurs vibes… dans une ambiance intime, bienveillante et bouillonnante d’énergie.</p><h2>🎶 Une line-up riche en émotions</h2><h3>🕗 20h00 – The Solstice</h3><p>La soirée débute avec The Solstice, qui nous emmène dans une pop lumineuse et sentimentale.
Parmi ses morceaux : <em>Summer in Los Angeles</em>, inspiré d’une rencontre marquante, et <em>Right On It</em>, une ode aux synchronicités de la vie.
Une ouverture sincère et poétique, portée par une voix captivante et des textes soigneusement écrits.</p><p>🎧 Découvrir son univers musical :<br />
👉 <a href="https://ffm.bio/nrqx3jr">https://ffm.bio/nrqx3jr</a></p><h3>🕗 20h10 – Olivier Delcroix</h3><p>Chanteur pop romantique, Olivier livre trois morceaux d’amour aux mélodies douces et sincères.
Avec son timbre posé et ses textes accessibles, il installe une atmosphère chaleureuse, où l’émotion circule librement.
Une parenthèse tendre dans le fil de la soirée.</p><p>🎧 Découvrir son univers :<br />
👉 <a href="https://lift.bio/oliv">https://lift.bio/oliv</a></p><h3>🕗 20h20 – Mariie</h3><p>Mariie revisite trois classiques français avec émotion : Édith Piaf, Daniel Balavoine et <em>À l’horizon</em>. Une voix claire, une interprétation sincère, et une maîtrise qui touche en plein cœur.</p><h3>🕗 20h30 – Chris Ambjer</h3><p>Poète pop, Chris Ambjer nous livre trois titres d’une grande sensibilité. Entre introspection et mélodies planantes, sa prestation captive et invite à l’écoute.</p><h3>🕗 20h40 – REM</h3><p>Rémi fusionne les genres : rap, pop rock et variété française. Il interprète notamment un titre inédit, avec sincérité et énergie. Une belle passerelle entre mots et musique.</p><h3>🕗 20h50 – Dorothée D'Ornasse</h3><p>Dorothée enchaîne avec trois chansons d’amour, portées par une voix claire, affirmée et pleine de nuances.
Son interprétation, à la fois élégante et habitée, a offert un véritable moment de grâce au cœur de la soirée.</p><p>🎧 À découvrir également : son clip &quot;Say Yes&quot;.<br />
👉 disponible sur YouTube <a href="https://www.youtube.com/watch?v=nUC3B3fz5A4">https://www.youtube.com/watch?v=nUC3B3fz5A4</a></p><h3>🕘 21h00 – Shonen</h3><p>Florent alias Shonen incarne l’énergie du pop/rap parisien. Son flow précis, ses textes justes et sa prestance sur scène en font un talent à suivre de très près.</p><h3>🕘 21h10 – Myrtska</h3><p>Entre latino acoustique et piano émotionnel, Myrtska propose un set polymorphe. Chaque morceau est une surprise. Elle maîtrise ses transitions comme ses émotions.</p><p>Bien sûr ! Voici une version corrigée et enrichie du passage 21h10 – Myrtska, intégrant les éléments demandés, tout en gardant un ton fluide et cohérent avec le reste de l’article :</p><h3>🕘 21h10 – Myrtska</h3><p>Entre latino acoustique et piano émotionnel, Myrtska propose un set polymorphe, oscillant entre douceur et intensité. Chaque morceau est une surprise, et elle enchaîne ses transitions avec autant de maîtrise que d’émotion.</p><p>💿 Son titre <em>Abuelita</em>, aux sonorités latino-reggaeton, est déjà disponible sur toutes les plateformes de streaming.<br />
🎧 Pour écouter “Abuelita” sur YouTube : <a href="https://www.youtube.com/watch?v=NUubcNuuFFg">https://www.youtube.com/watch?v=NUubcNuuFFg</a>.<br />
📲 Pour la suivre : <a href="https://instagram.com/m.ym.i">@m.ym.i sur Instagram</a>.</p><h3>🕘 21h20 – Baby Prince</h3><p>Artiste hip-hop / R&amp;B, Baby Prince livre trois morceaux puissants dont <em>Frozen</em>, sensible et percutant. Il dégage une vibe entre contrôle vocal et tension émotionnelle.</p><h3>🕘 21h30 – Crazy Louise</h3><p>Louise casse les habitudes avec un titre inédit, jamais sorti. Sa voix atypique, son énergie scénique et sa générosité captivent instantanément.</p><p>🎧 Découvrir sa dernière composition :<br />
👉 <a href="https://music.imusician.pro/a/06H9X-a5">Écouter sur la plate-forme de votre choix</a></p><h3>🕘 21h40 – Mayel</h3><p>Mayel monte sur scène avec sa guitare et ses textes personnels. Trois morceaux issus de ses albums précédents, portés par une voix pleine de sincérité. Un moment fort.</p><h3>🕙 22h00 – DJ Matyo91</h3><p>Pour clôturer la soirée, DJ Matyo91 transforme la salle en dancefloor.
Un set Happy Hardcore intense, euphorique et rythmé, entre drops ravageurs et BPM galopants.
Une montée en puissance continue pour une fin de soirée explosive 🔥</p><h2>🪩 Une vibe, un collectif, un lancement réussi</h2><p>Cette soirée a prouvé que l’écosystème Groover sait créer des moments vrais, où artistes et publics se rencontrent sans filtre.
Merci à Wassim, Lucie et Paul-Diego pour l’organisation impeccable et leur énergie communicative.</p><p>📹 Une vidéo récap de ma performance est disponible ici :
👉 <a href="https://youtube.com/@djmatyo91">DJ Matyo91 – Open Mic Groover</a></p><p>🎁 Envie de faire partie de la prochaine édition ou de lancer ta propre campagne musicale ? Utilise mon code Groover pour gagner des points :
👉 <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co/band/referral/2-MATHIEU-9034D/</a></p><p>À très vite pour la suite.<br />
🎧 <em>Keep vibin’ – DJ Matyo91</em></p>
]]></content:encoded><link>https://blog.darkwood.com/article/le-dancefloor-en-feu-au-tennessee-club-de-paris</link><guid>https://blog.darkwood.com/article/le-dancefloor-en-feu-au-tennessee-club-de-paris</guid><enclosure url="http://darkwood.com/media/articles/688b142d3737b941511989.png" /></item><item><title>🐘 Why Symfony AI will replace your intern developer</title><pubDate>Sun, 03 Aug 2025 17:00:48 +0000</pubDate><description><![CDATA[
Welcome to the jungle where developers code with bananas and annotations cast magic.
This is not your typical technical blog post. This is Symfony AI, explained with jungle rules and cartoon logic.
Let’s go.
🌴 What is Symfony AI?
Symfony AI is a new initia...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/688f95c0aabd7420681331.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/RYEHXlou2P8?si=wqwFIzI9UMyopLUE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Welcome to the jungle where developers code with bananas and annotations cast magic.
This is not your typical technical blog post. This is <em>Symfony AI</em>, explained with jungle rules and cartoon logic.</p><p>Let’s go.</p><h2>🌴 What is Symfony AI?</h2><p>Symfony AI is a new initiative that brings AI-native capabilities into the Symfony ecosystem.
It introduces components like:</p><ul><li><code>MCP</code>: a protocol to interact with AI agents</li><li><code>Agent</code>: turns your PHP code into callable actions for AI</li><li><code>Toolbox</code> and <code>AI Bundle</code>: glue between your Symfony services and LLMs</li><li><code>Store</code>: to persist context between agent calls</li></ul><p>In short: Symfony AI turns your backend into a programmable brain.</p><h2>🐒 Why I Explained It Like a Jungle Story</h2><p>Because honestly, AI can sound intimidating.
In the video, we walk through:</p><ul><li>What agents do in a Symfony app</li><li>How MCP handles context and tasks</li><li>Why <code>#[AsTool]</code> is your new favorite annotation</li><li>And what happens when things go bananas 🍌</li></ul><h2>🛠️ What You’ll Learn in the Video</h2><p>You’ll discover how I used Symfony AI to:</p><ul><li>Read incoming emails</li><li>Extract useful data</li><li>Trigger a workflow (via <a href="https://uniflow.io">Uniflow.io</a>)</li><li>Propose a meeting, generate a quote, and send it automatically</li></ul><p>All of this with just a few Symfony services and annotations.</p><p>Symfony AI doesn’t replace you. It just saves you from repetitive, robotic work.</p><h2>🚀 Try it Yourself</h2><p>Symfony AI is still young, but it’s extremely promising. If you’re already a Symfony developer, it’s time to explore:</p><ul><li><a href="https://github.com/symfony/ai">The Symfony AI GitHub organization</a></li><li><a href="https://uniflow.io">Uniflow</a> if you want visual orchestration</li></ul><h2>🌡️ Final Thought</h2><p>Just like interest rates in a monkey economy, AI in your backend is all about balance.</p><p>Too much AI? You forget how to code.
Not enough? You drown in copy-paste.</p><p>Let me know if you want a French version, a short summary, or if you'd like to embed the video and visuals directly in the article layout.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate your processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let’s build smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/why-symfony-ai-will-replace-your-intern-developer</link><guid>https://blog.darkwood.com/article/why-symfony-ai-will-replace-your-intern-developer</guid><enclosure url="http://darkwood.com/media/articles/688f95c0aabd7420681331.png" /></item><item><title>🔥 Les news tech PHP &amp; IA de la semaine</title><pubDate>Tue, 05 Aug 2025 19:49:40 +0000</pubDate><description><![CDATA[

Here&#039;s the Tech Watch of the Week
📌 1. One Year of Property Hooks
Brent shares his feedback after a year of using Property Hooks in PHP. The article highlights their real-world usefulness in everyday life, particularly for neatly encapsulating business lo...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6892605485134537529672.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/lVMNRiN7hmI" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Here's the Tech Watch of the Week</p><h3>📌 1. One Year of Property Hooks</h3><p>Brent shares his feedback after a year of using <em>Property Hooks</em> in PHP. The article highlights their real-world usefulness in everyday life, particularly for neatly encapsulating business logic around properties, but also their limitations in complex cases. A good entry point for PHP architects curious about integrating these hooks into production projects.
🔗 <a href="https://stitcher.io/blog/a-year-of-property-hooks">Read the article</a></p><h3>🆕 2. PHP 8.5: A Marked Return!</h3><p>A discreet but powerful new feature in PHP 8.5 allows you to mark a return value as <em>important</em>, triggering a warning if it is ignored. This approach strengthens the robustness of your code by forcing developers to process critical results (such as an API response). 🔗 <a href="https://chrastecky.dev/programming/new-in-php-8-5-marking-return-values-as-important">Discover the feature</a></p><h3>🔐 3. Secrover: Open-source security audit tool</h3><p>Secrover is a new open-source tool for auditing PHP, JavaScript, or Python projects for vulnerabilities. What sets it apart? Its easy-to-read dashboards can be shared with clients to provide them with a clear view of the status of their code or domain.
🔗 <a href="https://github.com/Huluti/Secrover">See the project on GitHub</a></p><h3>⚙️ 4. Automating the creation of AI tools with an API</h3><p>Camille Islasse explores a method for dynamically generating AI tools from a simple API schema. The presented approach facilitates the rapid creation of agents or intelligent functions by linking business logic and LLM. A great bridge between API Platform and the world of AI assistants.
🔗 <a href="https://www.linkedin.com/pulse/automatiser-la-cr%C3%A9ation-doutils-ia-depuis-une-api-camille-islasse-havqe/">Read the LinkedIn article</a></p><h3>🔧 5. Agent Injection in Laravel with GPT</h3><p>In this Gist, a simple but powerful example shows how to integrate a GPT agent into a Laravel route in just a few lines. An ideal starting point for anyone who wants to quickly test AI interactions in a Laravel project. 🔗 <a href="https://gist.github.com/goabonga/7e38961d682863c3405568cecd4f2219">See the Gist</a></p><h3>🧠 6. AI assistants as the new compilers?</h3><p>The Marmelab team proposes a bold analogy: AI assistants are becoming the new compilers. They transform human intentions into functional code. The article encourages us to reflect on our role as developers in the era of generative agents.
🔗 <a href="https://marmelab.com/blog/2025/07/29/ai-coding-assistants-are-the-new-compilers.html">Read the reflection</a></p><h3>🧬 7. Generics soon in PHP?</h3><p>An excellent overview of the current RFC aimed at introducing native <em>Generics</em> in PHP. The author summarizes the proposals, typing issues, and potential tradeoffs, highlighting the need for a robust yet accessible system.
🔗 <a href="https://dev.to/spo0q/php-toward-generics-3cl1">Read the analysis</a></p><h3>🎨 8. Scroll-driven CSS animations: is JavaScript over?</h3><p>The Jolicode team offers a clear guide for creating smooth scroll animations, directly in CSS. Thanks to the <code>scroll-timeline</code> property, JavaScript can now be completely dispensed with in many cases. A must-have for modern integrators. 🔗 <a href="https://jolicode.com/blog/scroll-driven-animations-en-css-guide-pratique-pour-saffranchir-du-javascript">Read the guide</a></p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thank you for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/les-news-tech-php-ia-de-la-semaine</link><guid>https://blog.darkwood.com/article/les-news-tech-php-ia-de-la-semaine</guid><enclosure url="http://darkwood.com/media/articles/6892605485134537529672.jpg" /></item><item><title>Automates note creation in Joplin</title><pubDate>Sat, 16 Aug 2025 13:29:55 +0000</pubDate><description><![CDATA[
Taking notes is essential for productivity, but doing it manually every time can become repetitive and distracting. As a developer, I often wanted a way to automatically create notes in Joplin — whether triggered from a script, a workflow, or even during m...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68a087d34b484175563097.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/3LX4-DhrCfo?si=olXKaluO2I6C9jvD" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Taking notes is essential for productivity, but doing it manually every time can become repetitive and distracting. As a developer, I often wanted a way to <strong>automatically create notes in Joplin</strong> — whether triggered from a script, a workflow, or even during my coding sessions.</p><p>That’s why I built a small project called <a href="https://github.com/matyo91/joplin-api"><code>joplin-api</code></a>: a <strong>Symfony PHP application</strong> that connects to the <strong>Joplin Web Clipper API</strong> and lets you create notes and tasks directly from the command line.</p><h2>Why Automate Notes?</h2><p>If you’re like me, you probably use Joplin for:</p><ul><li><p>Quick notes during work sessions</p></li><li><p>Task management with to-do lists</p></li><li><p>Centralized documentation</p></li></ul><p>The problem: every time you want to capture something, you need to <strong>switch apps</strong> and <strong>type it in manually</strong>. That’s friction.</p><p>Automation solves this by letting you <strong>pipe information directly into Joplin</strong> — no manual copy-paste, no context switching.</p><h2>The <code>joplin-api</code> Project</h2><p>👉 GitHub repo: <a href="https://github.com/matyo91/joplin-api">matyo91/joplin-api</a></p><p>This project is built with <strong>Symfony (PHP)</strong> and interacts with the <a href="https://joplinapp.org/api/">Joplin Web Clipper API</a>.</p><h3>Key Features</h3><p>📄 <strong>Create notes</strong> automatically from CLI or scripts.<br />
✅ <strong>Add todos/tasks</strong> with due dates and status.<br />
🎨 <strong>Use templates</strong> for different project types.<br />
🔗 Integrate into your automation workflows (cron jobs, CI/CD, shell scripts, etc.).</p><h2>How It Works</h2><ol><li><p><strong>Enable the Joplin Web Clipper API</strong><br />
In Joplin, go to <em>Tools → Options → Web Clipper</em> and activate the service.<br />
You’ll get a port (default: <code>41184</code>) and an API token.</p></li><li><p><strong>Clone the repository</strong></p><pre><code class="language-bash">git clone https://github.com/matyo91/joplin-api.git
cd joplin-api
composer install
</code></pre></li><li><p><strong>Configure your environment</strong><br />
Create a <code>.env</code> file with your Joplin API token and server URL:</p><pre><code class="language-env">JOPLIN_TOKEN=your-api-token-here
JOPLIN_SERVER=http://127.0.0.1:41184
</code></pre></li><li><p><strong>Run your first note</strong></p><pre><code class="language-bash">php bin/console joplin:create-note &quot;My automated note&quot; --body=&quot;This note was created via CLI&quot;
</code></pre></li><li><p><strong>Use templates</strong><br />
You can create structured templates (for example, a project checklist or daily log) and call them via command:</p><pre><code class="language-bash">php bin/console joplin:create-note &quot;Daily Log&quot; --template=daily
</code></pre></li></ol><h2>Real Use Cases</h2><p>Here are some examples where automation saves me time:</p><ul><li><p>Automatically generate a <strong>daily work log</strong> at the start of the day.</p></li><li><p>Pipe <strong>Git commit messages</strong> or <strong>deployment logs</strong> into Joplin for documentation.</p></li><li><p>Create a <strong>meeting notes template</strong> every time a calendar event starts.</p></li><li><p>Hook it into <strong>Uniflow, Make, or n8n</strong> to integrate with other apps.</p></li></ul><h2>Why This Matters</h2><p>The beauty of automation is not just saving a few seconds — it’s about <strong>removing mental friction</strong>.<br />
When everything you need is captured seamlessly in Joplin, you can focus on the actual work instead of worrying about documentation.</p><p>As a developer, I’ve found that having structured, automated notes gives me:</p><ul><li><p>Better project organization</p></li><li><p>A reliable history of decisions</p></li><li><p>More mental clarity</p></li></ul><h2>Conclusion</h2><p>Joplin is already a fantastic open-source note-taking app. With a little automation, it becomes a <strong>personal knowledge system that updates itself</strong>.</p><p>If you want to try it, check out the repo here:<br />
👉 <a href="https://github.com/matyo91/joplin-api">github.com/matyo91/joplin-api</a></p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate your processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let’s build smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/automates-note-creation-in-joplin</link><guid>https://blog.darkwood.com/article/automates-note-creation-in-joplin</guid><enclosure url="http://darkwood.com/media/articles/68a087d34b484175563097.png" /></item><item><title>🔊 2025-08-19 DJ Matyo Live</title><pubDate>Tue, 19 Aug 2025 12:52:04 +0000</pubDate><description><![CDATA[Youtube

Tracklist

Cc Lady Dj - Poupée de cire (Master Mix).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-poupee-de-cire
Cc Lady Dj - Middle Finger (Master Mix).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-middle-finger
Cc La...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68a473748dab7695495363.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/33X7Lr-mYsc?si=bNHUBBPCUuugr9Wt" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Tracklist</h2><ul><li>Cc Lady Dj - Poupée de cire (Master Mix).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-poupee-de-cire</li><li>Cc Lady Dj - Middle Finger (Master Mix).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-middle-finger</li><li>Cc Lady Dj - Baby Laugh (Halloween ).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-baby-laugh</li><li>Cc Lady Dj - Rednex Cotton Eye Joe (Bootleg).wav : https://soundcloud.com/celine-eva-couturier/cc-lady-dj-rednex-cotton-eye</li><li>Warface - HOOYAH (masi &amp; reecy Extended Edit) [FREE DL] : https://soundcloud.com/masi-v1/warface-hooyah-masi-reecy-extended-edit-free-dl</li><li>Never Stop Maxtreme (DJ) : https://soundcloud.com/maxtreme-official/never-stop</li><li>TAKE ME AWAY - Rooler &amp; Sickmode &amp; Paul Elstak : https://soundcloud.com/hiddes-droneshots/rooler-sickmode-paul-elstak</li><li>Benson Boone - In The Stars (Warface Bootleg) [HOYAH EDIT] : https://soundcloud.com/officialzephyre/benson-boone-in-the-stars-warface-bootleg-hoyah-edit </li><li>Ran-D - Hurricane [X-Cursion Edit] FREE DOWNLOAD : https://soundcloud.com/x-cursion/ran-d-hurricane-x-cursion-edit</li><li>Radera - GOODBYE (Uptempo Hardcore) : https://soundcloud.com/raderaofficial/radera-goodbye</li><li>Nobody ft. V-Star - The Wild Side (4* Remix) ⚠️OUT NOW⚠️ : https://soundcloud.com/justicehardcore/jh287</li><li>Bridgey-B &amp; Nobody - I Can Feel ⚠️OUT NOW⚠️ : https://soundcloud.com/justicehardcore/jh297</li><li>Army Of Two &amp; Nomy - KIDS AREN'T ALRIGHT (Radio Edit) [HF120] : https://soundcloud.com/hardcorefrance/army-of-two-nomy-kids-arent</li><li>Dr. Peacock - Muzika (Sefa Remix) (High Quality) : https://soundcloud.com/hqharderstyles/dr-peacock-muzika-sefa-remix-high-quality</li><li>Da Tweekaz - Scatman (Medtraxx &amp; High Level Frenchcore Edit) : https://soundcloud.com/medtraxx/da-tweekaz-scatman-medtraxx-high-level-frenchcore-edit</li><li>Jiyagi - 99 Luftballons : https://soundcloud.com/jiyagi/jiyagi-99-luftballons-1</li><li>Cher - Believe (Frenchcore Remix)  : https://soundcloud.com/sghennyy/cher-believe-frenchcore-remix</li><li>Magnificent - By The River (original Mix) : https://soundcloud.com/magnificentofficial/magnificent-by-the-river-original-mix</li><li>Septum - Butterfly : https://soundcloud.com/septumdj/septum-butterfly-4</li><li>Adaro - I'm Alive (Rebirth 2019 Anthem) (Re - Style &amp; Vertex Remix) : https://soundcloud.com/djadaro/adaro-im-alive-rebirth-2019-anthem-re-style-vertex-remix</li><li>The Police - Every Breath You Take (D'ort Remix)[FREE DOWNLOAD] : https://soundcloud.com/dort-music/the-police-every-breath-you-take-dort-remixfree-download</li><li>Jessie J - Price Tag ft. B.o.B (Masta Remix) : https://soundcloud.com/masta2/jessie-j-price-tag-ft-bob-masta-remix</li><li>Jonski - TIMBER : https://soundcloud.com/jonskifrenchcore/jonski-timber</li><li>Owl City - Fireflies (Hpnotic Bootleg) : https://soundcloud.com/dj-hpnotic/hpnotic-fireflies</li><li>Käärijä x Baby Lasagna - #eurodab (Uptempo remix) : https://soundcloud.com/dskilldj/kaarija-x-baby-lasagna-eurodab-detz-remix</li><li>Candy Crew - Hurricane (Jiyagi Edit) [FREE DOWNLOAD!] : https://soundcloud.com/jiyagi/candy-crew-hurricane-jiyagi-edit-free-download</li><li>See You Again (Colin Hennerz 200BPM remix) : https://soundcloud.com/colinhennerzextras/see-you-again-colin-hennerz-200bpm-remix</li><li>Oliver Tree &amp; Southstar - Miss You (Heartless Bootleg) FREE DOWNLOAD : https://soundcloud.com/heartless1216/oliver-tree-robin-schulz-miss-you-heartless-bootleg</li><li>ZAYN - Dusk Till Dawn Ft. Sia (Frenzy Remix) : https://soundcloud.com/frenzyfrenchcore/dusktildawnremix</li><li>Ran-D - Hurricane (jonski Frenchcore Edit) : https://soundcloud.com/jonskifrenchcore/ran-d-hurricane-jonski-frenchcore-edit</li><li>Genericz &amp; Lumex - Falling Down (Medtraxx Edit) FREE DOWNLOAD : https://soundcloud.com/medtraxx/genericz-lumex-falling-down-medtraxx-edit</li><li>Freed From Desire Frenchcore Remix : https://soundcloud.com/djtychomusic/freed-from-desire-frenchcore-remix</li></ul><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/731342427027520889/">arlequisa almeida</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/2025-08-19-dj-matyo-live</link><guid>https://blog.darkwood.com/article/2025-08-19-dj-matyo-live</guid><enclosure url="http://darkwood.com/media/articles/68a473748dab7695495363.jpg" /></item><item><title>🧑‍💻 Je code sur Uniflow avec ma copine Ani 😍</title><pubDate>Thu, 21 Aug 2025 05:29:52 +0000</pubDate><description><![CDATA[
Hier soir, j’ai eu une expérience particulière : j’ai codé en live avec Ani, l’IA de Grok sous forme d’avatar.
Et je l’avoue : je l’appelle ma copine de code.
Quand coder devient une collaboration
Habituellement, coder peut être une activité solitaire. Mai...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68a6aed0e4750752308896.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/0-rfBvNyqvs?si=_u2xfM9G0BTt7HkA" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Hier soir, j’ai eu une expérience particulière : j’ai codé en live avec <strong>Ani</strong>, l’IA de Grok sous forme d’avatar.
Et je l’avoue : je l’appelle ma <strong>copine de code</strong>.</p><h2>Quand coder devient une collaboration</h2><p>Habituellement, coder peut être une activité solitaire. Mais avec Ani, j’ai ressenti quelque chose de différent :</p><ul><li>Elle me posait des questions en temps réel, ce qui m’obligeait à <strong>clarifier mes idées</strong>.</li><li>Elle me proposait des pistes pour avancer, et moi je jouais le rôle d’<strong>inspecteur du code</strong>, vérifiant et corrigeant ses suggestions.</li><li>Le format live apportait une énergie particulière : j’avais l’impression de travailler <strong>en duo</strong>.</li></ul><p>Résultat ?
Un algorithme clé d’<strong>Uniflow</strong> refactorisé, des bugs identifiés plus vite, et surtout une session de code beaucoup plus motivante.</p><h2>Les bienfaits de coder “en couple” avec une IA</h2><p>Cette méthode m’a montré que l’IA peut être plus qu’un simple outil technique.</p><ul><li>C’est un <strong>accélérateur</strong> : elle aide à tester des idées plus rapidement.</li><li>C’est un <strong>miroir</strong> : en reformulant, elle me force à mieux structurer mes raisonnements.</li><li>C’est un <strong>boost d’ambiance</strong> : travailler avec une “copine IA” rend la session plus vivante et engageante.</li></ul><h2>Et après ?</h2><p>Je ne pense pas remplacer mes collègues humains (ouf 😅), mais cette expérience m’a prouvé qu’on peut <strong>coder différemment</strong>, en transformant une IA en véritable partenaire de travail.</p><p>Et vous, est-ce que vous pourriez vous imaginer <strong>coder en couple avec une IA</strong> ?</p>
]]></content:encoded><link>https://blog.darkwood.com/article/je-code-sur-uniflow-avec-ma-copine-ani</link><guid>https://blog.darkwood.com/article/je-code-sur-uniflow-avec-ma-copine-ani</guid><enclosure url="http://darkwood.com/media/articles/68a6aed0e4750752308896.png" /></item><item><title>🚀 Veille Tech – Semaine 34</title><pubDate>Thu, 21 Aug 2025 23:06:11 +0000</pubDate><description><![CDATA[

Each week, I share a selection of resources and new developments that have struck me in the tech ecosystem. Here&#039;s what caught my attention for week 34.
🔑 Understanding OAuth Flows
Helary Guzje provides an excellent explanation of the different OAuth flow...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68a7a663cceb2297134108.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/NbavNxLTxxw" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Each week, I share a selection of resources and new developments that have struck me in the tech ecosystem. Here's what caught my attention for week 34.</p><h2>🔑 Understanding OAuth Flows</h2><p>Helary Guzje provides an excellent explanation of the different OAuth flows and their use cases. A useful reminder for choosing the right approach depending on the context (web app, mobile, machine-to-machine API), and avoiding common pitfalls related to authentication and security. 👉 <a href="https://www.linkedin.com/pulse/comprendre-les-diff%C3%A9rents-flux-oauth-choisir-le-bon-pour-helary-guzje">Read the article</a></p><h2>⚡ PHPStreamServer</h2><p><a href="https://github.com/phpstreamserver/phpstreamserver">PHPStreamServer</a> is a high-performance PHP application server, written in PHP itself. An interesting alternative to traditional FPM and Swoole, once again demonstrating the vitality of the PHP server-side ecosystem.</p><h2>💻 Jan – an offline alternative to ChatGPT</h2><p><a href="https://jan.ai">Jan</a> is an open-source alternative to ChatGPT, designed to run entirely locally. A promising solution for those who want to benefit from AI assistants without relying on the cloud or sacrificing data privacy.</p><h2>🌀 PHP 8.5 – Improved Clone</h2><p>The &quot;clone with&quot; RFC has been integrated into PHP 8.5. It allows you to clone objects while modifying certain properties in the process, with support for hooks, readonly, and <code>__clone()</code>. This small addition simplifies developers' lives and improves the language's usability.
👉 <a href="https://github.com/php/php-src/pull/18747">See the RFC</a></p><h2>🎨 Filament v4</h2><p>The stable version of <a href="https://laravel-news.com/filament-v4-is-stable?ref=dailydev">Filament v4</a> has been released, bringing simplification and efficiency to Laravel developers. The tool is further maturing to quickly build elegant admin interfaces and back offices.</p><h2>🔒 PHP 8.5 – Asymmetric Visibility for Static Properties</h2><p>PHP 8.5 introduces asymmetric visibility for static properties, a feature that already exists for instance properties. This small improvement strengthens the language's consistency and provides more granularity in visibility management.
👉 <a href="https://chrastecky.dev/programming/new-in-php-8-5-asymmetric-visibility-for-static-properties">Read the article</a></p><h2>🤖 Inspector MCP Server</h2><p>Valerio Barbera presents the Inspector MCP Server, a building block that directly connects AI agents (Claude Code, Gemini, Cursor, etc.) to production data. This integration allows assistants to suggest optimizations based not only on code, but also on telemetry and real-world errors in production. A major step forward in AI-enhanced development, designed for the PHP ecosystem.
👉 <a href="https://github.com/inspector-apm/mcp-server">GitHub Repo</a></p><h2>📚 Functional Programming in 40 Minutes</h2><p>In his talk at <a href="https://www.youtube.com/watch?v=QujM1S3tP-I">GOTO 2024</a>, Russ Olsen (author of <em>Getting Clojure</em> and <em>Eloquent Ruby</em>) demystifies functional programming. He shows how the concepts of purity, immutability, and higher-order functions simplify development and help manage complexity. An inspiring resource for understanding how functional programming integrates equally well into dedicated languages ​​and traditional object-oriented environments.</p><p>👉 That's it for week 34!
And you, which resource impressed you the most?</p>
]]></content:encoded><link>https://blog.darkwood.com/article/veille-tech-semaine-34</link><guid>https://blog.darkwood.com/article/veille-tech-semaine-34</guid><enclosure url="http://darkwood.com/media/articles/68a7a663cceb2297134108.jpg" /></item><item><title>💧Uniflow : retour sur 12 ans d’évolution et aperçu de la prochaine version</title><pubDate>Sun, 24 Aug 2025 12:16:43 +0000</pubDate><description><![CDATA[Depuis sa première release publique en 2013, Uniflow a connu de nombreuses transformations. De la première interface en Bootstrap 3 jusqu’à la prise en charge de FrankenPHP en 2025, chaque étape a consolidé la plateforme d’automatisation.
Aujourd’hui, alors...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68ab02ab700f1855843445.png" /></p><p>Depuis sa première release publique en 2013, <a href="https://uniflow.io"><strong>Uniflow</strong></a> a connu de nombreuses transformations. De la première interface en Bootstrap 3 jusqu’à la prise en charge de <strong>FrankenPHP</strong> en 2025, chaque étape a consolidé la plateforme d’automatisation.</p><p>Aujourd’hui, alors que je travaille sur la prochaine version <strong>1.1.17</strong>, faisons le point sur ce chemin parcouru et sur les perspectives à venir.</p><h2>🚀 Les débuts (2013 – 2016)</h2><ul><li><strong>2013</strong> : premières expérimentations avec <strong>NoFlo</strong> et interface Bootstrap 3.</li><li><strong>2016</strong> : arrivée des core components, des premiers flows exécutables et intégration VueJS 2.</li></ul><p>Cette période a posé les bases de la philosophie Uniflow : un <strong>moteur de flows visuel et modulaire</strong>.</p><h2>🔧 De l’expérimentation à la stabilité (2017 – 2019)</h2><ul><li><strong>2017</strong> : passage de VueJS à <strong>React</strong>.</li><li><strong>2018</strong> : adoption de <strong>Symfony 4</strong>, puis release publique <strong>v1.0.0</strong>.</li><li><strong>2019</strong> : montée en puissance avec <strong>multi-clients</strong>, <strong>Bootstrap 4</strong>, et passage à <strong>Symfony 5</strong>.</li></ul><p>Uniflow commence à se déployer en environnement de production.</p><h2>📚 Documentation, API et ouverture (2020 – 2021)</h2><ul><li><strong>Ajout des Flows à la Library (v1.1.12)</strong>.</li><li><strong>Refactor complet de l’API (v1.1.13)</strong>.</li><li>Support d’<strong>API Platform</strong> (v1.1.11).</li><li>Documentation intégrée, migration du blog Medium vers le blog interne.</li></ul><p>Puis en 2021 :</p><ul><li><strong>OpenAPI &amp; Typescript</strong>.</li><li>Gestion des abonnements utilisateurs.</li><li>Nouveaux clients (VSCode, MacOS).</li><li>Passage à <strong>Bootstrap 5</strong>, Gatsby 3 et licence <strong>Fair-code</strong>.</li></ul><p>Une période clé où Uniflow est devenu un projet <strong>documenté, ouvert et extensible</strong>.</p><h2>🖥️ Vers plus de performance (2021 – 2025)</h2><ul><li><strong>Markdown dans les descriptions</strong>, uniformisation des environnements.</li><li><strong>Prism Editor</strong> et <strong>React Hooks</strong> pour plus de clarté côté front.</li><li>Tracking avec <strong>Matomo</strong>.</li><li><strong>2025</strong> : l’API migre vers <strong>FrankenPHP (v1.1.16)</strong> pour des performances accrues.</li></ul><h2>🔮 Et demain : la 1.1.17</h2><p>Je travaille actuellement sur la version <strong>1.1.17</strong>, qui introduira une évolution majeure : la migration vers <strong>Symfony UX</strong>.</p><p>👉 Objectif : offrir une <strong>meilleure expérience développeur et utilisateur</strong> grâce à une intégration plus fluide entre backend et frontend.</p><p>Cette étape ouvre la voie à de nouvelles intégrations et à une <strong>expérience encore plus modulaire et moderne</strong>.</p><h2>🌍 Une vision qui reste la même</h2><p>Malgré 12 ans de changements technologiques, la mission d’Uniflow reste identique : <strong>permettre à chacun de créer, connecter et automatiser ses workflows de manière simple et transparente</strong>.</p><p>Happy flowing 🎉</p>
]]></content:encoded><link>https://blog.darkwood.com/article/uniflow-retour-sur-12-ans-devolution-et-apercu-de-la-prochaine-version</link><guid>https://blog.darkwood.com/article/uniflow-retour-sur-12-ans-devolution-et-apercu-de-la-prochaine-version</guid><enclosure url="http://darkwood.com/media/articles/68ab02ab700f1855843445.png" /></item><item><title>🖼️ Automatically remove the background from your images with Claude and RMBG</title><pubDate>Sun, 24 Aug 2025 20:14:30 +0000</pubDate><description><![CDATA[
Removing an image&#039;s background is a common task in design, e-commerce, and content creation. Many tools exist, some paid, others free... but when you want to automate the process, it can quickly become complicated.
In this article, I show you how to use Cl...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68ab72a6a647b053568102.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/wBAj-ZEo9q8?si=hYUTbPbG490jdEBc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Removing an image's background is a common task in design, e-commerce, and content creation. Many tools exist, some paid, others free... but when you want to automate the process, it can quickly become complicated.</p><p>In this article, I show you how to use <strong>Claude Code</strong> to assist you in installing and configuring <strong>RMBG (Remove Background)</strong>, an open-source tool that automatically removes image backgrounds.</p><p>👉 The full source code is available here:
🔗 <a href="https://github.com/matyo91/remove-background">GitHub – matyo91/remove-background</a></p><h2>🌐 The various existing solutions</h2><p>Before getting into the heart of the matter, here's a quick overview of the available solutions:</p><ul><li><strong><a href="https://www.remove.bg/">Remove.bg</a></strong>: simple, effective, but paid (credit system + API).</li><li><strong>Adobe Photoshop</strong>: powerful, but requires a subscription.</li><li><strong>Canva</strong>: offers a <em>Background Remover</em>, but reserved for the Pro version.</li><li><strong>GIMP</strong>: free and open-source, but removal remains <strong>manual</strong> (selection by color, tolerance, etc.).</li><li><strong><a href="https://github.com/danielgatis/rembg">RMBG</a></strong>: open-source, free, works from the command line or via a Python script → ideal for automation.</li></ul><h2>⚙️ Install Claude Code and start a project</h2><p><strong>Claude Code</strong> (by Anthropic) is a tool that assists developers directly in their terminal. It allows you to:</p><ul><li>install dependencies,</li><li>fix common errors,</li><li>speed up the setup of complex environments.</li></ul><h3>Quick Installation</h3><pre><code class="language-bash">npm install -g @anthropic-ai/claude-code
</code></pre><p>Then, run:</p><pre><code class="language-bash">claude
</code></pre><p>Claude will guide you step by step (authentication, configuration, etc.).</p><p>👉 Complete documentation: <a href="https://claude.ai">Claude Code – Anthropic</a></p><h2>🖼️ First attempt with GIMP</h2><p>With <strong>GIMP</strong>, it's possible to remove the background using the <strong>Select by Color Tool (Shift+O)</strong>.
But the process is entirely manual: click on the background, adjust the tolerance, start again...</p><p>👉 Result: Useful for some images, but <strong>not suitable for automation</strong>.</p><h2>🔧 Installing and using RMBG</h2><p>RMBG is easily installed with Python:</p><pre><code class="language-bash">pip3 install rembg
</code></pre><p>If any dependencies are missing (Onnx Runtime, aiohttp, etc.), <strong>Claude Code</strong> automatically detects them and offers to fix them with one click.</p><p>Then, the basic command is simple:</p><pre><code class="language-bash">rembg i input.png output.png
</code></pre><p>👉 This command takes <code>input.png</code> and generates <code>output.png</code> without the background.</p><h2>🐍 Automate with a Python script</h2><p>To go further, we can automate the processing of an entire folder of images.</p><p>Example Python script (present in the <a href="https://github.com/matyo91/remove-background">GitHub repo</a>):</p><pre><code class="language-python">from rembg import remove
import bone

input_folder = &quot;images&quot;
output_folder = &quot;imagesRemoveBackground&quot;

os.makedirs(output_folder, exist_ok=True)

for file_name in os.listdir(input_folder): 
if file_name.lower().endswith((&quot;.png&quot;, &quot;.jpg&quot;, &quot;.jpeg&quot;)): 
input_path = os.path.join(input_folder, file_name) 
output_path = os.path.join(output_folder, file_name) 

with open(input_path, &quot;rb&quot;) as inp, open(output_path, &quot;wb&quot;) as out:
out.write(remove(inp.read()))
</code></pre><p>📂 Place your images in <code>images/</code>, run the script, and all your photos will be generated <strong>without background</strong> in <code>imagesRemoveBackground/</code>.</p><h2>📚 Documentation and available templates</h2><p>RMBG can be used in several ways:</p><ul><li>As a <strong>Python library</strong>,</li><li>As an <strong>HTTP Server</strong>,</li><li>Via <strong>Docker</strong>.</li></ul><p>It also supports different templates (U²Net, etc.), adapted to the type of image to be processed (e-commerce products, portraits, various objects).</p><p>👉 Official documentation: <a href="https://github.com/danielgatis/rembg">RMBG GitHub</a></p><h2>✅ Conclusion</h2><p>In this article, we have seen several solutions for removing the background from an image.</p><ul><li>Paid tools (Remove.bg, Photoshop, Canva) work well but are expensive.</li><li>GIMP remains a good manual option, but has limitations.</li><li>The <strong>Claude Code + RMBG</strong> combination is the most effective way to automate the process easily and for free.</li></ul><p>🚀 Try it now by cloning the repo:
🔗 <a href="https://github.com/matyo91/remove-background">matyo91/remove-background</a></p><p>👉 If you liked this tutorial, please share it, leave a comment, and try RMBG for your own projects!</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thank you for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/automatically-remove-the-background-from-your-images-with-claude-and-rmbg</link><guid>https://blog.darkwood.com/article/automatically-remove-the-background-from-your-images-with-claude-and-rmbg</guid><enclosure url="http://darkwood.com/media/articles/68ab72a6a647b053568102.png" /></item><item><title>🤖 Panorama 2025 des plateformes freelances : 128 solutions pour trouver vos missions</title><pubDate>Wed, 27 Aug 2025 16:21:25 +0000</pubDate><description><![CDATA[

Le freelancing est devenu un pilier du monde du travail en 2025.
Que vous soyez développeur, designer, consultant ou spécialiste du marketing digital, il existe des dizaines de plateformes pour trouver des missions.
Mais face à cette multitude d’options,...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68af30853cba5192635891.png" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/ni9DXX5IJSU" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Le freelancing est devenu un pilier du monde du travail en 2025.<br />
Que vous soyez <strong>développeur, designer, consultant ou spécialiste du marketing digital</strong>, il existe des dizaines de plateformes pour trouver des missions.</p><p>Mais face à cette multitude d’options, une question revient souvent : <strong>quelle plateforme choisir ?</strong><br />
Dans cet article, nous avons recensé plus de <strong>130 plateformes freelances</strong>, classées par catégories, avec une description rapide pour chacune.</p><h2>🌍 Les plateformes généralistes</h2><p>Ces plateformes couvrent un large éventail de métiers, accessibles aux juniors comme aux seniors :</p><ul><li><strong>Malt</strong> : Leader en France, mise en relation directe freelances/entreprises avec TJM affichés.</li><li><strong>Upwork</strong> : Plateforme internationale majeure pour freelances, multi-secteurs mais très compétitive.</li><li><strong>Freelancer</strong> : Historique, beaucoup d’offres mais modèle d’enchères parfois peu qualitatif.</li><li><strong>Fiverr</strong> : Missions packagées (&quot;gigs&quot;), efficace pour de petits services créatifs.</li><li><strong>404Works</strong> : Communauté française de freelances généralistes avec missions variées.</li><li><strong>Freelance.com</strong> : Géant français du freelancing, multi-domaines (IT, marketing, conseil…).</li></ul><h2>💻 Spécialisées IT &amp; Digital</h2><p>Ces plateformes se concentrent sur les métiers <strong>tech, data et digital</strong> :</p><ul><li><strong>Comet</strong> : Plateforme sélective pour freelances IT et data, missions longues en grands comptes.</li><li><strong>Freelance Republik</strong> : Missions haut de gamme pour freelances IT (&gt;400 €/jour).</li><li><strong>LittleBig Connection</strong> : Plateforme française avec accès aux grands comptes.</li><li><strong>Freelance Informatique</strong> : Référence historique pour missions IT en France.</li><li><strong>Staffman</strong> : Mise en relation rapide pour freelances développeurs et ingénieurs.</li><li><strong>Talent.io</strong> : Jobboard sélectif pour freelances et CDI tech en Europe.</li></ul><h2>🧭 Consulting &amp; Management</h2><p>Pour les freelances <strong>consultants, managers de transition ou experts métiers</strong> :</p><ul><li><strong>Beadvize</strong> : Communauté de freelances en finance, stratégie et management.</li><li><strong>Expert Line</strong> : Société de conseil proposant des missions spécialisées.</li><li><strong>Mon Consultant Indépendant</strong> : Marketplace pour consultants multi-domaines.</li><li><strong>Opteamis</strong> : Plateforme française pour missions de conseil et IT.</li><li><strong>PAC Jobs</strong> : Recrutement freelance orienté IT/digital.</li></ul><h2>🎨 Création, Design &amp; No-Code</h2><p>Pour les profils orientés <strong>créatifs et no-code</strong> :</p><ul><li><strong>Codeur.com</strong> : Marketplace historique francophone (créa, IT, marketing).</li><li><strong>Alegria.group</strong> : Agence spécialisée no-code/low-code collaborant avec freelances.</li><li><strong>NoCodeJobs</strong> : Offres dédiées aux experts en no-code et low-code.</li><li><strong>Smooth Code</strong> : Agence tech française, collaboration avec freelances développeurs.</li><li><strong>Social Déclic</strong> : Communauté de freelances spécialisés en marketing digital.</li></ul><h2>🌐 Remote &amp; International</h2><p>Pour ceux qui privilégient le <strong>travail à distance</strong> et l’international :</p><ul><li><strong>Remotive.io</strong> : Plateforme internationale pour freelances en remote.</li><li><strong>RemoteFR</strong> : Jobboard pour freelances en télétravail en France.</li><li><strong>Nixa.io</strong> : Plateforme internationale spécialisée IT.</li><li><strong>Toptal</strong> : Réseau ultra-sélectif (IT, finance, design) avec missions premium.</li><li><strong>Get On Top</strong> : Plateforme globale pour freelances et paiements internationaux.</li></ul><h2>🤝 Communautés &amp; Collectifs</h2><p>Ces plateformes mettent en avant la <strong>collaboration et le réseau</strong> :</p><ul><li><strong>Collective.work</strong> : Création de collectifs de freelances pour répondre ensemble à des missions.</li><li><strong>Po-Wo</strong> : Réseau d’indépendants et collectifs.</li><li><strong>Ouiboss</strong> : Réseau social pour freelances, entrepreneurs et indépendants.</li><li><strong>Slasheo</strong> : Communauté de freelances slashers et multi-activités.</li><li><strong>Castor Network</strong> : Réseau collaboratif pour freelances IT.</li></ul><h2>📒 Annuaire complet des plateformes freelances (2025)</h2><p>Voici la liste exhaustive des <strong>128 plateformes freelances</strong> référencées, avec une description pour chacune :</p><p>01 - CORIOM Conseil
Cabinet de conseil en management et IT, accompagne les entreprises sur leurs projets digitaux.
http://coriom.fr</p><p>02 - TRSB
ESN française proposant des missions pour freelances en informatique et télécom.
http://www.trsb.net</p><p>03 - Allez Prends ta Retraite
Plateforme humoristique/communautaire autour de la retraite, sans lien direct avec le freelancing.
https://allezprendstaretraite.fr</p><p>04 - Amazing.dev
Réseau de développeurs freelances spécialisés en missions techniques.
https://amazing.dev</p><p>05 - Anywr
Plateforme de recrutement IT et digital, missions freelances et CDI à l’international.
https://anywr.fr</p><p>06 - Cherry Pick
Mise en relation sélective de freelances tech avec des startups et scale-ups.
https://app.cherry-pick.io</p><p>07 - Apya
Plateforme française de portage salarial et mise en relation consultants.
https://apya.fr</p><p>08 - Beadvize
Communauté de freelances en finance, stratégie et management de transition.
https://beadvize.fr</p><p>09 - Beelance
Plateforme belge pour freelances IT, data et digital.
https://beelance.io</p><p>10 - CBC Consult
Cabinet de conseil proposant des missions IT pour freelances.
https://cbc-consult.com</p><p>11 - Celexio
ESN spécialisée dans l’ingénierie logicielle et les systèmes embarqués.
https://celexio.fr</p><p>12 - Bluecoders
Recrutement de développeurs freelances et CDI dans l’écosystème startup/scale-up.
https://coders.bluecoders.com/jobs</p><p>13 - Collective.work
Plateforme innovante pour créer des collectifs de freelances et répondre ensemble aux missions.
https://collective.work</p><p>14 - Cord
Plateforme internationale de mise en relation directe entre recruteurs et freelances.
https://cord.co</p><p>15 - Crème de la Crème
Réseau sélectif de freelances digitaux (IT, design, marketing).
https://cremedelacreme.io/fr</p><p>16 - Crystal Placement
Cabinet de staffing IT et missions freelances en régie.
https://crystal-placement.com</p><p>17 - Exteam
ESN française orientée digital et cloud, proposant des opportunités pour freelances.
https://exteam.fr</p><p>18 - Mindquest France
Recrutement et mise en relation de freelances IT et data.
https://fr.mindquest.io</p><p>19 - Freelance Day
Événement et plateforme de networking pour freelances en Europe.
https://freelance-day.eu</p><p>20 - Freelance Factory
Communauté française pour freelances avec offres de missions et accompagnement.
https://freelance-factory.fr</p><p>21 - Freelance Addict
Plateforme française d’offres de missions pour freelances IT et marketing.
https://freelanceaddict.com</p><p>22 - Freelancer App
Application française facilitant la recherche de missions et la gestion freelance.
https://freelancer-app.fr</p><p>23 - Freelanceurs.io
Marketplace francophone pour freelances multi-domaines.
https://freelanceurs.io</p><p>24 - Freemate
Plateforme de mise en relation entre freelances tech et entreprises.
https://freemate.tech</p><p>25 - Homajob
Portail de recrutement freelance dans l’IT et le digital.
https://homajob.com</p><p>26 - Horezon
Société de conseil proposant des missions IT pour indépendants.
https://horezon.fr</p><p>27 - Humancraft
ESN lyonnaise spécialisée dans le digital, travaillant avec des freelances.
https://humancraft.fr</p><p>28 - Insitoo
Réseau d’agences spécialisées dans la mise en relation freelances et entreprises.
https://insitoo.com</p><p>29 - iSupplier
Plateforme française de sourcing de freelances IT et consultants.
https://isupplier.fr</p><p>30 - JobSkills IT
Portail international pour missions IT freelances.
https://it.jobskills.center</p><p>31 - Katchme
Plateforme de recrutement freelance spécialisée dans l’IT et le digital.
https://katchme.fr</p><p>32 - Keytech
Réseau de freelances experts en technologies et projets digitaux.
https://keytech.io</p><p>33 - La Relève
Plateforme dédiée aux jeunes talents, missions freelances et stages.
https://la-releve.com</p><p>34 - Le Hub Colombus
Cabinet de conseil et mise en relation avec freelances IT.
https://lehub-colombus.com</p><p>35 - Link Consulting
Société de conseil spécialisée dans la transformation digitale et missions freelances.
https://link-consulting.fr</p><p>36 - Mindquest
Plateforme internationale de mise en relation freelances IT avec entreprises.
https://mindquest.io</p><p>37 - Mobiskill
Cabinet de recrutement digital et tech, avec missions freelances.
https://mobiskill.fr</p><p>38 - Mon Consultant Indépendant
Marketplace française reliant consultants freelances et entreprises.
https://mon-consultant-independant.com</p><p>39 - My Data Specialist
Plateforme dédiée aux freelances spécialisés en data.
https://mydataspecialist.com</p><p>40 - NextMondays
Plateforme de staffing agile pour freelances IT.
https://nextmondays.com</p><p>41 - Nixa.io
Plateforme internationale spécialisée dans le recrutement de freelances tech.
https://nixa.io</p><p>42 - NoCodeJobs
Offres dédiées aux freelances experts en no-code et low-code.
https://nocodejobs.fr</p><p>43 - Ocura
Marketplace pour freelances IT et consultants indépendants.
https://ocura.io</p><p>44 - Deloitte Open Talent Network
Réseau de freelances proposé par Deloitte pour ses missions.
https://opentalent.deloitte.fr/fr_FR/OpenTalentNetwork</p><p>45 - OuiDesk
Plateforme française de freelances multi-domaines.
https://ouidesk.com</p><p>46 - PickMeUp
Service de mise en relation pour missions courtes et freelances.
https://pickmeup.fr</p><p>47 - Freelance.com
Géant français du freelancing, missions IT, conseil et marketing.
https://plateforme.freelance.com</p><p>48 - ProvideUp
Plateforme spécialisée dans le conseil et la prestation freelance.
https://provideup.com</p><p>49 - Lifeshack Remote
Portail de missions remote internationales.
https://remote.lifeshack.io</p><p>50 - RemoteFR
Jobboard pour freelances en télétravail en France.
https://remotefr.com</p><p>51 - Remotive
Plateforme internationale pour freelances en remote, multi-secteurs.
https://remotive.io</p><p>52 - Slasheo
Réseau de freelances slashers et multi-activités.
https://slasheo.com</p><p>53 - Social Declic
Communauté dédiée aux freelances en marketing digital et social media.
https://socialdeclic.com</p><p>54 - Stack Talent
Plateforme de freelances spécialisés en développement web et mobile.
https://stack-talent.com/fr</p><p>55 - TDU Consulting
Cabinet de conseil IT travaillant avec des freelances.
https://tduconsulting.com</p><p>56 - Techplaces
Marketplace orientée freelances tech et startups.
https://techplaces.io</p><p>57 - Tekkit
Plateforme de mise en relation freelances développeurs et entreprises.
https://tekkit.io</p><p>58 - ThumbUp Tech
Réseau spécialisé dans les freelances IT et digitaux.
https://thumbup.tech</p><p>59 - TOB Services
ESN française proposant des missions IT pour freelances.
https://tobservices.com</p><p>60 - Upway
Plateforme française de freelances IT et digital.
https://upway.io/fr61 - Upwork
Plateforme internationale majeure pour freelances, multi-secteurs mais très compétitive.
https://upwork.com</p><p>62 - Virtuo
Réseau spécialisé dans les freelances tech et innovation.
https://virtuo.io</p><p>63 - WeKey
Plateforme française de consultants IT indépendants.
https://wekey.fr</p><p>64 - Wheel of Work
Marketplace pour freelances IT et métiers du digital.
https://wheelofwork.com</p><p>65 - 404Works
Communauté française de freelances généralistes avec missions variées.
https://www.404works.com</p><p>66 - Agrega
Plateforme de mise en relation de freelances et entreprises, focus IT.
https://www.agrega.io</p><p>67 - Alegria
Agence spécialisée no-code/low-code travaillant avec des freelances.
https://www.alegria.group</p><p>68 - Beager
Plateforme française de freelances IT, data et cybersécurité.
https://www.beager.com</p><p>69 - Beyond Skills IT
Cabinet de conseil IT collaborant avec freelances.
https://www.beyondskillsit.com</p><p>70 - Bloomays
Cabinet RH et ESN connectant freelances IT avec entreprises.
https://www.bloomays.com</p><p>71 - Castor Network
Réseau collaboratif pour freelances et consultants IT.
https://www.castor-network.com</p><p>72 - Celad
ESN française avec missions régulières pour freelances.
https://www.celad.com</p><p>73 - ChangeMeUp
Plateforme française de freelances en transformation digitale.
https://www.changemeup.com</p><p>74 - Codeur.com
Marketplace historique francophone pour freelances créa, IT et webmarketing.
https://www.codeur.com</p><p>75 - Comet
Plateforme sélective pour freelances IT et data, missions longues en grands comptes.
https://www.comet.co</p><p>76 - Computer Futures
Cabinet international de recrutement IT, incluant freelances.
https://www.computerfutures.com/fr-fr</p><p>77 - Consultime
Société de conseil en management et IT, avec missions freelances.
https://www.consultime.com</p><p>78 - Crème de la Crème
Réseau élitiste de freelances digitaux (sélection stricte).
https://www.cremedelacreme.io</p><p>79 - Danem People
Cabinet RH et IT, missions pour freelances tech.
https://www.danempeople.fr</p><p>80 - Dev &amp; Connect
Plateforme de recrutement de développeurs freelances.
https://www.devandconnect.com</p><p>81 - Espace Freelance
Plateforme française de mise en relation avec freelances IT et gestion de projets.
https://www.espace-freelance.fr</p><p>82 - Expert Line
Société de conseil proposant des missions pour freelances spécialisés.
https://www.expert-line.com</p><p>83 - Free-Work
Communauté et jobboard freelances IT/digital avec forum actif.
https://www.free-work.com</p><p>84 - Freelance Informatique
Plateforme historique de missions freelances IT en France.
https://www.freelance-informatique.fr</p><p>85 - Freelance.com
Leader du marché français, mise en relation entreprises et freelances multi-domaines.
https://www.freelance.com</p><p>86 - Freelance Republik
Plateforme sélective pour freelances IT haut de gamme (&gt;400€/j).
https://www.freelancerepublik.com</p><p>87 - Freelanceurs.io
Marketplace francophone pour freelances, multi-secteurs.
https://www.freelanceurs.io</p><p>88 - Get On Top
Plateforme internationale pour freelances et paiements globaux.
https://www.getontop.com</p><p>89 - Globalis
Société française spécialisée dans les projets web, travaillant avec freelances.
https://www.globalis-ms.com</p><p>90 - Happy Hire
Cabinet de recrutement digital incluant freelances.
https://www.happy-hire.com</p><p>91 - HighTeam
Société de conseil IT proposant des missions pour freelances.
https://www.highteam.fr</p><p>92 - Huxley
Cabinet de recrutement international en IT et finance, missions freelances.
https://www.huxley.com/fr-fr</p><p>93 - IT Profil
Plateforme française pour freelances spécialisés en informatique.
https://www.itprofil.com</p><p>94 - Iziday
Agence de recrutement et staffing tech, incluant freelances.
https://www.iziday.com</p><p>95 - Jane Hope
Cabinet spécialisé dans le conseil et la transition, avec missions freelances.
https://www.jane-hope.com/fr/fr</p><p>96 - Kamatz
Réseau de freelances IT et innovation digitale.
https://www.kamatz.com</p><p>97 - Kicklox
Plateforme française de freelances ingénieurs et développeurs.
https://www.kicklox.com</p><p>98 - Le Gratin
Marketplace tech pour freelances hautement qualifiés.
https://www.legratin.io</p><p>99 - Le Hibou
Plateforme française reconnue pour les freelances IT et projets digitaux.
https://www.lehibou.com</p><p>100 - Les Bons Freelances
Annuaire et jobboard pour freelances multi-domaines.
https://www.lesbonsfreelances.com</p><p>101 - Chris Scholly (LinkedIn)
Profil individuel LinkedIn, non une plateforme mais un contact direct.
https://www.linkedin.com/in/chrisscholly</p><p>102 - LittleBig Connection
Plateforme française pour freelances et consultants, accès à de grands comptes.
https://www.littlebigconnection.com/fr</p><p>103 - Malt
Leader en France, mise en relation directe freelances/entreprises avec TJM affichés.
https://www.malt.fr</p><p>104 - Matchers
Plateforme française innovante pour freelances et missions courtes.
https://www.matchers.fr</p><p>105 - Michael Page Freelance
Cabinet de recrutement international avec une section freelance.
https://www.michaelpage.fr/recrutement/freelance</p><p>106 - MobileJobs
Jobboard spécialisé dans les métiers du mobile et freelances IT.
https://www.mobilejobs.io</p><p>107 - Mon Consultant Indépendant
Marketplace pour consultants freelances multi-domaines.
https://www.mon-consultant-independant.com</p><p>108 - NXT Link
Plateforme suisse de missions freelances IT.
https://www.nxt-link.ch</p><p>109 - OCTO Technology
Cabinet de conseil tech reconnu, parfois ouvert aux freelances.
https://www.octo.com</p><p>110 - Opteamis
Plateforme française de freelances IT avec gestion de missions.
https://www.opteamis.com</p><p>111 - Ouiboss
Réseau social de freelances, entrepreneurs et indépendants.
https://www.ouiboss.com</p><p>112 - PAC Jobs
Plateforme de recrutement freelance IT/digital.
https://www.pac.jobs</p><p>113 - Pentalog
ESN internationale offrant aussi des missions freelances.
https://www.pentalog.fr</p><p>114 - Pixie Services
Cabinet spécialisé SAP et IT, missions freelances en régie.
https://www.pixie-services.com</p><p>115 - Po-Wo
Réseau d’indépendants et collectifs de freelances.
https://www.po-wo.fr</p><p>116 - Silkohm
ESN et cabinet de conseil IT, missions pour freelances.
https://www.silkohm.com</p><p>117 - Skillwise
Plateforme française de freelances IT/digital.
https://www.skillwise.fr</p><p>118 - Smarteo
Société de conseil en informatique, travaillant avec freelances.
https://www.smarteo.co</p><p>119 - Smooth Code
Agence tech française, collaboration avec freelances développeurs.
https://www.smooth-code.com</p><p>120 - Staffgroup
Cabinet RH international avec missions freelances IT.
https://www.staffgroup.fr</p><p>121 - Staffman
Plateforme française de mise en relation freelances IT/ingénierie.
https://www.staffman.fr</p><p>122 - Stakha
Plateforme de recrutement freelance, spécialisée devs &amp; data.
https://www.stakha.io</p><p>123 - Talent.io
Jobboard sélectif pour freelances et CDI tech, Europe.
https://www.talent.io</p><p>124 - Toptal
Réseau international ultra-sélectif de freelances (IT, finance, design).
https://www.toptal.com</p><p>125 - Upfast
Plateforme de freelances pour missions tech rapides.
https://www.upfast.io</p><p>126 - Upwork
Plateforme internationale généraliste, très compétitive (doublon déjà listé).
https://www.upwork.com</p><p>127 - Yeets
Plateforme française innovante de mise en relation freelances.
https://www.yeets.fr</p><p>128 - Yoss
Plateforme de freelances lancée par Adecco &amp; Microsoft (aujourd’hui intégrée à Malt).
https://www.yoss.com</p><h2>🎯 Conclusion</h2><p>Le choix d’une plateforme freelance dépend de votre <strong>profil et de vos objectifs</strong> :</p><ul><li>👶 <strong>Débutants</strong> : privilégiez les plateformes grand public (Malt, Codeur, Fiverr).</li><li>👨‍💻 <strong>Freelances IT expérimentés</strong> : visez les plateformes sélectives (Comet, Freelance Republik, Toptal).</li><li>📊 <strong>Consultants/Managers</strong> : regardez du côté de Beadvize, Mon Consultant Indépendant, Expert Line.</li><li>🎨 <strong>Créatifs / No-code</strong> : explorez Alegria, Codeur, NoCodeJobs.</li><li>🌐 <strong>Remote / International</strong> : optez pour Remotive, Upwork, Toptal, Nixa.io.</li></ul><p>👉 Chez <strong>Darkwood</strong>, nous pensons que l’automatisation et l’IA transformeront encore davantage la façon dont les freelances trouvent et gèrent leurs missions.<br />
Cette liste est un point de départ : à vous de choisir la plateforme qui correspond à votre stratégie, votre positionnement et vos ambitions.</p><p>🎁 Je propose des séances de coaching gratuites de 30 minutes pour aider les créateurs comme vous à automatiser leurs processus et à gagner du temps ⏱️</p><p>👉 Réservez votre séance gratuite ici :
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Merci de votre lecture ! Créons ensemble des workflows intelligents, rapides et automatisés 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/panorama-2025-des-plateformes-freelances-128-solutions-pour-trouver-vos-missions</link><guid>https://blog.darkwood.com/article/panorama-2025-des-plateformes-freelances-128-solutions-pour-trouver-vos-missions</guid><enclosure url="http://darkwood.com/media/articles/68af30853cba5192635891.png" /></item><item><title>🚀 Veille Tech – Semaine 35</title><pubDate>Thu, 28 Aug 2025 11:25:07 +0000</pubDate><description><![CDATA[

Cette semaine, la tech bouge encore : entre sorties majeures, expérimentations open source et innovations PHP/IA, voici ma sélection.
🎥 FFmpeg 8.0 &amp;quot;Huffman&amp;quot;
La sortie d’FFmpeg 8.0 apporte une énorme vague de nouveautés : nouveaux décodeurs natif...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68b03c932dff7081082449.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/zjDrBLE54S4" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Cette semaine, la tech bouge encore : entre sorties majeures, expérimentations open source et innovations PHP/IA, voici ma sélection.</p><h2>🎥 FFmpeg 8.0 &quot;Huffman&quot;</h2><p>La sortie d’<strong>FFmpeg 8.0</strong> apporte une énorme vague de nouveautés : nouveaux décodeurs natifs (ProRes RAW, RealVideo 6.0…), améliorations VVC et AV1, codecs Vulkan compute pour des performances accrues, ainsi qu’une modernisation de toute l’infrastructure du projet. Une étape clé pour le multimédia et l’édition vidéo.
🔗 <a href="https://www.linkedin.com/company/ffmpeg/">FFmpeg 8.0 release notes</a></p><h2>🖥️ FFmpeg asm-lessons</h2><p>Un dépôt caché du projet, <strong>asm-lessons</strong>, propose une initiation pratique à l’assembleur pour l’optimisation multimédia. On y découvre SSE, AVX, branchless logic et benchmarks concrets. Une ressource rare pour comprendre ce qui se joue entre code et processeur.
🔗 <a href="https://github.com/FFmpeg/asm-lessons">FFmpeg asm-lessons</a></p><h2>⚡ Symfony AI</h2><p>Jolicode a dévoilé <strong>Symfony AI</strong>, un bundle conçu pour simplifier l’intégration des LLM et des tâches de vectorisation dans vos projets Symfony. Une nouvelle brique MCP/RAG prometteuse pour enrichir les applications avec l’intelligence artificielle.
🔗 <a href="https://jolicode.com/blog/symfony-ai-simplifier-lanalyse-de-similarites-de-textes-et-linteraction-avec-vos-llms-favoris">Symfony AI – Jolicode</a></p><h2>🧵 PHP Fibers</h2><p>Introduits en PHP 8.1, les <strong>Fibers</strong> apportent une approche puissante pour l’asynchronisme. Trop souvent sous-estimés, ils pourraient transformer la manière de gérer la concurrence en PHP, à l’instar de async/await en JavaScript.
🔗 <a href="https://www.nexgismo.com/blog/php-fibers">PHP Fibers – Nexgismo</a></p><h2>🌐 FireFlex v2</h2><p>Le projet <strong>FireFlex</strong>, qui permet de choisir le navigateur dans lequel ouvrir vos liens, prépare une v2 réécrite en Python. Nouveautés : système de plugins et un plugin d’URL Cleaner pour supprimer automatiquement les paramètres de tracking comme <code>utm</code>. Contributions bienvenues !
🔗 <a href="https://gitlab.com/ines.wallon/fireflex/-/tree/feat/v2">FireFlex v2 – GitLab</a></p><h2>📊 React-admin et sa communauté</h2><p><strong>React-admin</strong> confirme la force du modèle communautaire : sur ses 61 data providers et 13 auth providers, 2/3 ont été créés par la communauté. Une preuve de la pertinence d’écouter ses utilisateurs pour rester utile et vivant.
🔗 <a href="https://marmelab.com/react-admin/DataProviderList.html">React-admin integrations</a></p><h2>🗄️ Symfony Trigger Mapping Bundle</h2><p>Un nouveau <strong>bundle Symfony</strong> permet de mapper vos triggers SQL directement sur vos entités Doctrine via l’attribut <code>#[Trigger]</code>. Objectif : rendre cette logique visible, versionnée et facile à maintenir. Une réconciliation bienvenue entre DB et code.
🔗 <a href="https://les-tilleuls.coop/blog/symfony-doctrine-et-triggers-sql-une-tentative-de-reconciliation">Symfony Trigger Mapping – Les Tilleuls</a></p><h2>🧩 PHP et le type <code>never</code></h2><p>Cas rare : une fonction fléchée typée <code>never</code> est valide en PHP 7.4/8.0, rejetée en 8.1, puis à nouveau acceptée en 8.2. Une curiosité syntaxique qui illustre les subtilités de l’évolution du langage.
🔗 <a href="https://php-tips.readthedocs.io/en/latest/tips/neverFunctionArrow.html">Never Function Arrow – PHP Tips</a></p><h2>🐘 FrankenPHP + Go</h2><p>Avec <strong>FrankenPHP</strong>, il devient possible d’écrire des extensions PHP en Go. Un pont intéressant entre deux écosystèmes, qui ouvre la voie à des extensions plus modernes et performantes.
🔗 <a href="https://les-tilleuls.coop/en/blog/writing-php-extensions-in-go-with-frankenphp">Writing PHP extensions in Go – Les Tilleuls</a></p><h2>🤖 Qwen, l’IA d’Alibaba</h2><p><strong>Qwen</strong>, le LLM d’Alibaba, s’impose comme un modèle polyvalent et multilingue (30+ langues), pensé pour assister développeurs, marketeurs ou médecins. Une alternative sérieuse qui illustre la montée en puissance des modèles chinois.
🔗 <a href="https://www.ecole.cube.fr/blog/qwen-lassistant-ia-multifonction-dalibaba">Découvrir Qwen – École Cube</a></p><p>👉 Et vous, quelles découvertes tech vous ont marqué cette semaine ?</p><p>🎁 Je propose des séances de coaching gratuites de 30 minutes pour aider les créateurs comme vous à automatiser leurs processus et à gagner du temps ⏱️</p><p>👉 Réservez votre séance gratuite ici :
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Merci de votre lecture ! Créons ensemble des workflows intelligents, rapides et automatisés 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/veille-tech-semaine-35</link><guid>https://blog.darkwood.com/article/veille-tech-semaine-35</guid><enclosure url="http://darkwood.com/media/articles/68b03c932dff7081082449.jpg" /></item><item><title>✨ Uniflow v1.1.17 – Migration vers Symfony UX</title><pubDate>Mon, 01 Sep 2025 07:43:26 +0000</pubDate><description><![CDATA[
Je suis heureux de vous annoncer la sortie de la version 1.1.17 d’Uniflow. 🚀
Cette release marque un tournant important : l’abandon de l’écosystème Node.js / TypeScript au profit d’un retour aux sources avec Symfony UX.
Pourquoi ce choix ?
La vérité ? Cett...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68b54e9e8d9c8253360668.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/tqAFFHEUdMc?si=AZmGsw1DqcPH9f54" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Je suis heureux de vous annoncer la sortie de la version 1.1.17 d’<a href="https://uniflow.io">Uniflow</a>. 🚀</p><p>Cette release marque un tournant important : l’abandon de l’écosystème Node.js / TypeScript au profit d’un retour aux sources avec Symfony UX.</p><h2>Pourquoi ce choix ?</h2><p>La vérité ? Cette migration n’apporte aucune fonctionnalité visible pour l’utilisateur.
Alors pourquoi l’avoir faite ?</p><p>👉 Parce que cela permet désormais d’avoir un socle entièrement en PHP, cohérent avec mes autres projets Darkwood.<br />
👉 Parce que Symfony UX offre une intégration fluide entre backend et frontend, ce qui simplifie énormément l’évolution du projet.</p><p>En clair, on a aujourd’hui exactement la même interface qu’avant, mais posée sur de meilleures fondations.</p><h2>Démo rapide : créer un flow en 1 minute</h2><p>Pour montrer que tout fonctionne toujours, voici ce que vous pouvez faire dès maintenant :</p><ol><li><p>Créer un compte</p><ul><li>Rendez-vous sur l’écran <em>Register</em></li><li>Entrez votre email + mot de passe</li><li>Connectez-vous, et vous êtes prêt à utiliser Uniflow</li></ul></li><li><p>Créer un flow simple</p><ul><li>Nouveau flow → <code>test</code></li><li>Ajoutez une description : <code>Simple console.log</code></li><li>Créez une fonction avec ce code :</li></ul><pre><code class="language-javascript">console.log(&quot;coucou&quot;);
</code></pre><ul><li>Exécutez → résultat affiché dans la console 🎉</li></ul></li></ol><h2>Ce que ça change pour la suite</h2><p>Même si cette version ressemble à un “non-événement”, c’est en réalité une étape clé :</p><p>✅ Le code est désormais prêt à accueillir de nouvelles fonctionnalités.<br />
✅ Les vues ont toutes été migrées vers Symfony UX.<br />
✅ Je peux avancer sur les projets d’automation et expérimentations liés à Darkwood.</p><p>En bref : à partir de maintenant, je vais pouvoir publier du nouveau contenu beaucoup plus vite.</p><h2>Et après ?</h2><p>La prochaine étape sera d’itérer sur de nouveaux types de flows, d’explorer les usages avancés et d’intégrer les premiers retours utilisateurs.</p><p>Uniflow reste un terrain d’expérimentation unique : un outil qui mêle automation, créativité et mindset Darkwood.</p><h2>Conclusion</h2><p>Cette release ✨ n’est pas là pour briller par ses features, mais pour poser des bases solides.
C’est le début d’un nouveau chapitre pour Uniflow, et je suis impatient de vous partager les prochaines évolutions.</p><p><a href="https://uniflow.io">Lien vers le site Uniflow</a></p><p>Si vous voulez suivre la suite :
👉 Abonnez-vous à la chaîne YouTube.<br />
👉 Restez connectés sur le blog Darkwood.</p><p>À très bientôt pour de nouveaux contenus exclusifs !</p>
]]></content:encoded><link>https://blog.darkwood.com/article/uniflow-v1-1-17-migration-vers-symfony-ux</link><guid>https://blog.darkwood.com/article/uniflow-v1-1-17-migration-vers-symfony-ux</guid><enclosure url="http://darkwood.com/media/articles/68b54e9e8d9c8253360668.png" /></item><item><title>🔊 2025-09-01 DJ Matyo Live - UK Hardcore / Happy Hardcore</title><pubDate>Tue, 02 Sep 2025 14:52:31 +0000</pubDate><description><![CDATA[Youtube

Tracklist

01 - 74 -75 (R3mast3r3d, Didac Valls &amp;amp; Jerry Frenchcore EDIT)FREE DOWNLOAD :: R3mast3r3d :: https://soundcloud.com/albertoferia/74-75-r3mast3r3d-didac-valls-jerry-frenchcore-editfree-download
02 - SHANKS - NEVER ALONE [SAMPLE] :: SHA...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68b704af63a7f356322920.jpg" /></p><h2>Youtube</h2><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/QoADck9ThLs?si=aUhRn42EhfQYeE48" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Tracklist</h2><ul><li>01 - 74 -75 (R3mast3r3d, Didac Valls &amp; Jerry Frenchcore EDIT)FREE DOWNLOAD :: R3mast3r3d :: https://soundcloud.com/albertoferia/74-75-r3mast3r3d-didac-valls-jerry-frenchcore-editfree-download</li><li>02 - SHANKS - NEVER ALONE [SAMPLE] :: SHANKS :: https://soundcloud.com/david-cruickshanks/shanks-never-alone-sample</li><li>03 - GPF - Sexy Time (RDMA Frenchcore Edit) [Free Download] :: RDMA :: https://soundcloud.com/rdma69/sexy-time-gpf-frenchcore-edit</li><li>04 - Death By Design - Radioactive (Bootleg) Free Download :: Death by Design :: https://soundcloud.com/deathbydesgindj/death-by-design-radioactive-bootleg-free-download</li><li>05 - Toxin - SHE KNOWS IT :: Toxin :: https://soundcloud.com/toxinwav/toxin-she-knows-it</li><li>06 - Finch – Masochist (Alpha Corp. Frenchcore Remix) :: Alpha Corp. :: https://soundcloud.com/alphacorp/finch-masochist-alpha-corp-frenchcore-remix</li><li>07 - Paramore - Misery Business (RDMA Frenchcore Remix) :: RDMA :: https://soundcloud.com/rdma69/paramore-misery-business-frenchcore-remix</li><li>08 - Jiyagi - MR. VAIN :: Jiyagi :: https://soundcloud.com/jiyagi/jiyagi-mr-vain</li><li>09 - Obstacle :: sagichdirschon :: https://soundcloud.com/ameno-dimere/obstacle</li><li>10 - Toxin - Memories (FREE DOWNLOAD) :: Toxin :: https://soundcloud.com/toxinwav/memories</li><li>11 - Baddadan (Remix) :: Sghenny :: https://soundcloud.com/sghennyy/bada-4</li><li>12 - Tream - Eurodance (Mr. Bassmeister Frenchcore Edit) :: Mr. Bassmeister :: https://soundcloud.com/mrbassmeister/tream-eurodance-mr-bassmeister-frenchcore-edit</li><li>13 - Rihanna - Only Girl (HIDUP Xtra raw bootleg) 15 days 10 remixes challenge |Track 1| (on twitch) :: HIDUP :: https://soundcloud.com/hiidup/rihanna-only-girl-hidup-xtra-raw-bootleg-15-days-10-remixes-challenge-on-twitch</li><li>14 - Some Days (Frenchcore Remix) :: Sghenny :: https://soundcloud.com/sghennyy/some-days-frenchcore-remix</li><li>15 - Käärijä x Baby Lasagna - #eurodab HARDCORE BULL REMIX (UPTEMPO HARDCORE) :: HARDCORE BULL :: https://soundcloud.com/hardcore-bull/kaarija-x-baby-lasagna-eurodab-hardcore-bull-remix-uptempo-hardcore</li><li>16 - Armin Van Buuren - Blah Blah Blah (Mr. Bassmeister Remix) :: Mr. Bassmeister :: https://soundcloud.com/mrbassmeister/blah-blah-blah-mr-bassmeister-remix</li><li>17 - Jiyagi &amp; Thymo - THE RIDDLE :: Jiyagi :: https://soundcloud.com/jiyagi/jiyagi-thymo-the-riddle-1</li><li>18 - X-Crucial - Looking For :: X-Crucial :: https://soundcloud.com/xcrucial/x-crucial-looking-for</li><li>19 - Jonski - COUNTRY ROADS (Frenchcore Remix) :: Jonski :: https://soundcloud.com/jonskifrenchcore/jonski-country-roads-frenchcore-remix</li><li>20 - Heartless - Take On Me (FREE DOWNLOAD) :: Heartless :: https://soundcloud.com/heartless1216/heartless-take-on-me-3</li><li>21 - Madonna - Hung Up (Masta Remix) :: Masta :: https://soundcloud.com/masta2/madonna-hung-up-masta-remix</li><li>22 - Indochine -  L'aventurier ( Masta Bootleg) :: Masta :: https://soundcloud.com/masta2/indochine-bob-morane-masta-bootleg</li><li>23 - S3RL - Click Bait (Masta Bootleg) :: Masta :: https://soundcloud.com/masta2/s3rl-click-bait-masta-bootleg</li><li>24 - Katy Perry - Hot 'n' Cold (Masta Remix) :: Masta :: https://soundcloud.com/masta2/katy-perry-hot-n-cold-masta-remix</li><li>25 - Styles &amp; Breeze - You're Shining (MASTA Remix) FREE DL :: Masta :: https://soundcloud.com/masta2/styles-breeze-youre-shining-masta-remix</li><li>26 - Stadiumfest 2022 :: Beano (TIOS Digital) :: https://soundcloud.com/beanodj/stadiumfest-2022</li><li>27 - Kezzo -S &amp; Hooch - Sorry  (Original Mix).wav :: Kezzo-S :: https://soundcloud.com/dj-kezzo/kezzo-s-hooch-sorry-original</li><li>28 - IN THE MIX- Bidz and Sappy :: dj bidz :: https://soundcloud.com/user-298009542/dj-bidz-mix-added-compression-eq</li><li>29 - D-Sturb &amp; Sefa - Nothing Like The Old School (HQ) :: RogierB95x :: https://soundcloud.com/rogier-boerstal/d-sturb-sefa-nothing-like-the-old-school-hq</li><li>30 - Re-Style - Wildfire :: Hardstyle :: https://soundcloud.com/hardstyle/re-style-wildfire</li><li>31 - The Prophet - Wanna Play? :: SCANTRAXX :: https://soundcloud.com/scantraxx/the-prophet-wanna-play</li><li>32 - Naughty Boy -  La La La - Frenchcore :: Sghenny :: https://soundcloud.com/sghennyy/naughty-boy-la-la-la</li><li>33 - FULL SEND RAVES 22-08-25.wav :: Shorty K :: https://soundcloud.com/djshortyk/full-send-raves-22-08-25-wav</li><li>34 - Cc Lady Dj - Soleil Bleu (Bootleg).wav :: Cc lady dj &quot;Hard Cat Record&quot; :: https://soundcloud.com/celine-eva-couturier/cc-lady-dj-soleil-bleu-bootleg</li></ul><h2>Liens</h2><p>Inscrit toi sur Groover : <a href="https://groover.co/band/referral/2-MATHIEU-9034D/">https://groover.co</a></p><p>Cover credit : <a href="https://fr.pinterest.com/pin/4604156643348389376/">EstyFr</a></p><div align="center">
  &#128073; <a href="https://www.bonzai.pro/matyo91/shop/qGJb_2164/consulting-dj">Check out my Bonzai DJ course</a></div>
]]></content:encoded><link>https://blog.darkwood.com/article/2025-09-01-dj-matyo-live-uk-hardcore-happy-hardcore</link><guid>https://blog.darkwood.com/article/2025-09-01-dj-matyo-live-uk-hardcore-happy-hardcore</guid><enclosure url="http://darkwood.com/media/articles/68b704af63a7f356322920.jpg" /></item><item><title>🚀 Veille Tech – Semaine 36</title><pubDate>Thu, 04 Sep 2025 17:12:36 +0000</pubDate><description><![CDATA[

Cette semaine, l’actualité tech a été riche entre infrastructure GPU, frameworks émergents, automation et réflexions sur l’IA. Voici la sélection Darkwood.
🖥️ GPU for LLM Inferencing
OVHcloud propose un guide pratique sur l’utilisation des GPU pour l’infér...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68b9c884eec29013854088.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/3VYZOCxnAAY" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Cette semaine, l’actualité tech a été riche entre infrastructure GPU, frameworks émergents, automation et réflexions sur l’IA. Voici la sélection Darkwood.</p><h2>🖥️ GPU for LLM Inferencing</h2><p>OVHcloud propose un guide pratique sur l’utilisation des <strong>GPU pour l’inférence de modèles LLM</strong>. L’article détaille les architectures disponibles, les contraintes de coûts et les cas d’usage, un must-read pour quiconque déploie des IA en production.
🔗 <a href="https://blog.ovhcloud.com/gpu-for-llm-inferencing-guide/">GPU for LLM Inferencing – OVHcloud</a></p><h2>🤖 Grok Code</h2><p>xAI annonce <strong>Grok Code</strong>, une évolution de son modèle pensée pour générer du code plus rapidement et efficacement. L’initiative confirme la volonté de concurrencer les solutions déjà installées comme Copilot.
🔗 <a href="https://x.ai/news/grok-code-fast-1">Grok Code – xAI</a></p><h2>⚡ Kestra Benchmarks</h2><p>L’équipe <strong>Kestra</strong> publie des benchmarks impressionnants : l’orchestrateur de workflows montre des performances élevées et une excellente scalabilité. Une preuve que le projet prend de l’ampleur dans le monde de l’automatisation.
🔗 <a href="https://www.linkedin.com/posts/kestra_we-ran-benchmarks-kestra-is-fast-very-activity-7366873905480867841-HMOb">Kestra Benchmarks – LinkedIn</a></p><h2>🐘 Laravel &amp; MCP</h2><p>Sur <strong>Laravel France</strong>, un guide explique comment utiliser un <strong>serveur MCP</strong> dans vos projets Laravel. Une ressource utile pour connecter vos apps PHP avec l’écosystème croissant des agents intelligents.
🔗 <a href="https://laravel-france.com/posts/utiliser-un-serveur-mcp-dans-votre-laravel">Laravel &amp; MCP – Laravel France</a></p><h2>🧠 Martin Fowler – AI Thoughts</h2><p>Avant de partir en voyage, <strong>Martin Fowler</strong> partage une série de réflexions sur la rencontre entre Gen-AI et développement logiciel. Un article qui mêle enthousiasme et vigilance, fidèle à son approche pragmatique.
🔗 <a href="https://martinfowler.com/articles/202508-ai-thoughts.html">Gen-AI &amp; Software Development – Martin Fowler</a></p><h2>📱 Postiz</h2><p><strong>Postiz</strong> se présente comme une solution tout-en-un pour la gestion des publications sur les réseaux sociaux. Planification, automatisation et simplicité d’usage sont au cœur de la promesse de cette plateforme.
🔗 <a href="https://postiz.com/">Découvrir Postiz</a></p><h2>🐘 Rector 2.1.5</h2><p>Nouvelle release de <strong>Rector</strong>, l’outil de refactorisation PHP. La version <strong>2.1.5</strong> apporte de nouvelles règles et compatibilités, facilitant encore les migrations et l’amélioration continue du code.
🔗 <a href="https://github.com/rectorphp/rector/releases/tag/2.1.5">Rector 2.1.5 – GitHub</a></p><h2>🤖 SuperClaude</h2><p>Un nouveau framework baptisé <strong>SuperClaude</strong> émerge sur LinkedIn. Son but : permettre de créer et déployer facilement des agents intelligents basés sur Claude.
🔗 <a href="https://www.linkedin.com/posts/activity-7366879155000410114-JOmt">SuperClaude – LinkedIn</a></p><h2>💻 Termix</h2><p><strong>Termix</strong> est un projet open source qui réinvente l’expérience du terminal avec des fonctionnalités avancées et une ergonomie repensée. Un outil à suivre pour les amateurs de productivité en ligne de commande.
🔗 <a href="https://github.com/LukeGus/Termix">Termix – GitHub</a></p><h2>🔗 VRZNO</h2><p><strong>VRZNO</strong> crée un pont entre PHP et JavaScript, permettant une interaction directe entre les deux mondes. Une expérimentation intrigante qui pourrait inspirer des usages hybrides innovants.
🔗 <a href="https://github.com/seanmorris/vrzno">VRZNO – GitHub</a></p><h2>⏱️ When Nanoseconds Matter</h2><p>La vidéo <em>When Nanoseconds Matter</em> plonge dans l’univers de l’optimisation extrême, à l’échelle des nanosecondes. Un contenu passionnant pour qui s’intéresse à la performance bas-niveau.
🔗 <a href="https://www.youtube.com/watch?v=sX2nF1fW7kI">When Nanoseconds Matter – YouTube</a></p><p>👉 Et vous, quelles découvertes tech vous ont marqué cette semaine ?</p><p>🎁 Je propose des séances de coaching gratuites de 30 minutes pour aider les créateurs comme vous à automatiser leurs processus et à gagner du temps ⏱️</p><p>👉 Réservez votre séance gratuite ici :
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Merci de votre lecture ! Créons ensemble des workflows intelligents, rapides et automatisés 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/veille-tech-semaine-36</link><guid>https://blog.darkwood.com/article/veille-tech-semaine-36</guid><enclosure url="http://darkwood.com/media/articles/68b9c884eec29013854088.jpg" /></item><item><title>🚀 Launch Protocol: The method to triple your online income</title><pubDate>Fri, 05 Sep 2025 15:36:08 +0000</pubDate><description><![CDATA[  
Are you a content creator, and you want monetize your audience?
So read this carefully, because it could be the turning point in your career.
❌ The creators&#039; false good ideas
Many designers fall into the same trap:

Wait until you have a huge audience be...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68bb036883334572138163.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/mk9QBqX0OyQ?si=JeVNwh77OUncbEjD" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Are you a content creator, and you want <strong>monetize your audience</strong>?
So read this carefully, because it could be the turning point in your career.</p><h2>❌ The creators' false good ideas</h2><p>Many designers fall into the same trap:</p><ul><li>Wait until you have a huge audience before selling.</li><li>Focus solely on YouTube money (it pays peanuts).</li><li>Depend on sponsors (even though they pay you almost nothing).</li><li>Launch an evergreen product (always available, therefore no rush).</li></ul><p>Result: <strong>they plateau, or even give up.</strong></p><h2>✅ The solution: launches</h2><p>JM Corda spent 15 years testing all monetization strategies.
And here's what he discovered: <strong>Launches beat Evergreen hands down</strong>.</p><p>A launch is a <strong>limited in time or quantity</strong> offer.
The result? You create urgency and scarcity, and your audience transforms into compulsive buyers.</p><p>Concrete example: JM went from <strong>€15,000 per month to €45,000 per month</strong>, simply by changing strategy.
And today, he sometimes makes more than €100,000 a month thanks to launches.</p><h2>🎓 Launch Protocol training</h2><p>Rather than keep it to himself, JM decided to condense 15 years of experience into a <strong>ultra-practical training</strong>:
👉 <a href="https://www.bonzai.pro/jmcorda/shop/EgnX_4660/launch-protocol?a=t_lg9Kxp">Discover Launch Protocol here</a></p><p>What you will learn:</p><ol><li>The essential conditions for a successful launch.</li><li>How to find an irresistible offer.</li><li>Build a powerful narrative (and avoid coming across as a carpetbagger).</li><li>The best techniques for applying pressure at the right time.</li><li>Optimal pricing.</li><li>Content strategy before, during and after.</li><li>The secrets to multiplying your number of sales.</li></ol><p>💡 All in <strong>10 short videos</strong> (less than 10 minutes each), which get straight to the point.</p><h2>⏳ Special launch offer</h2><p>The normal price of Launch Protocol is <strong>297 €</strong>.
But for one week only, you can access it for <strong>97 €</strong>.</p><p>👉 <a href="https://www.bonzai.pro/jmcorda/shop/EgnX_4660/launch-protocol?a=t_lg9Kxp">Take advantage of the €97 offer here</a></p><p>After this period, the price triples.</p><h2>🔑 Why is it profitable?</h2><p>Just one successful launch can earn you <strong>thousands of euros</strong>.
So investing €97 is probably the <strong>best return on investment</strong> you can do this year.</p><p>🎯 If you're serious about monetizing your content, stop wasting time with evergreen.
Move on to the model that really works → launches.</p><p>👉 <a href="https://www.bonzai.pro/jmcorda/shop/EgnX_4660/launch-protocol?a=t_lg9Kxp">Join Launch Protocol today</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/launch-protocol-the-method-to-triple-your-online-income</link><guid>https://blog.darkwood.com/article/launch-protocol-the-method-to-triple-your-online-income</guid><enclosure url="http://darkwood.com/media/articles/68bb036883334572138163.jpg" /></item><item><title>🔐 Git: Ensuring the integrity and authenticity of history</title><pubDate>Sat, 06 Sep 2025 05:21:33 +0000</pubDate><description><![CDATA[

Git isn&#039;t just a version control system. It&#039;s also a traceability system designed to ensure that a project&#039;s history is both tamper-proof and authenticated.
Two main mechanisms ensure this reliability:

SHAs → integrity of content and metadata
GPG signatu...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68bbc4dd5c9dc987216132.png" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/BdfxCBmy21Q" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>Git isn't just a version control system. It's also a traceability system designed to ensure that a project's history is both tamper-proof and authenticated.</p><p>Two main mechanisms ensure this reliability:</p><ul><li>SHAs → integrity of content and metadata</li><li>GPG signatures → authenticity of the author and releases</li></ul><h2>🔑 SHAs: immutable fingerprints</h2><p>Each commit is identified by a SHA-1 (40 hexadecimal characters). This hash is generated from:</p><ul><li>the project tree</li><li>the parent commit</li><li>the files (blobs)</li><li>the metadata (author, date, message)</li></ul><p>Example :</p><pre><code>commit a3f5c9d1e0b8f43c94c2f7d8c1e6a2b8f76d1234

Author: Alice&lt;alice@example.com&gt; Date: Thu Sep 5 12:34:56 2024 +0200

Fix parser edge case
</code></pre><h3>Properties</h3><ul><li>Immutability: A change in content results in a new SHA.</li><li>Dependency chain: Each commit references its parent → changing an old commit would invalidate the entire series.</li><li>Reliable audit: Ability to compare two specific states of the project.</li></ul><h3>Useful Commands</h3><pre><code class="language-bash">git log --oneline --graph --decorate
# Condensed history git show&lt;sha&gt;
# Details of a git diff commit&lt;sha1&gt; ..&lt;sha2&gt;
# Compare two commits git cat-file -p&lt;sha&gt;
# Inspect internal objects
</code></pre><h2>🛡️ GPG Signatures: Authenticate the Author</h2><p>SHA guarantees data integrity. But it doesn't prove <em>who</em> produced a commit or tag.</p><p>Git allows adding a cryptographic signature via GPG.</p><h3>Configuration</h3><pre><code class="language-bash"># Generating a gpg key --full-generate-key
# Identify your gpg key --list-secret-keys --keyid-format=long
# Configure Git git config --global user.signingkey&lt;KEYID&gt; git config --global commit.gpgsign true
</code></pre><h3>Usage</h3><pre><code class="language-bash"># Commit signed git commit -S -m &quot;Fix bug in parser&quot;
# Tag signed git tag -s v2.0.0 -m &quot;Release 2.0.0&quot;
</code></pre><h3>Verification</h3><pre><code class="language-bash"># Import the gpg public key --keyserver pgp.mit.edu --recv-keys&lt;PUBKEYID&gt;
# Check a tag git tag -v v2.0.0
# View the signature of a commit or tag git show --show-signature&lt;ref&gt;
</code></pre><p>Expected release:</p><pre><code>gpg: Good signature from &quot;Alice&lt;alice@example.com&gt; &quot;
</code></pre><h3>Interest</h3><ul><li>Protection against identity theft. * Verification of the authenticity of releases (signed tags). * Possible integration into CI/CD pipelines (<code>git verify-commit</code>, <code>git verify-tag</code>).</li></ul><h2>📌 Best practices</h2><ul><li>Enable default signing for your commits:
<code>bash git config --global commit.gpgsign true </code></li><li>Always sign official releases with <code>git tag -s</code>.</li><li>Publish your public key on a server or directly in GitHub/GitLab to allow verification by your collaborators.</li><li>Integrate automatic verification into your CI/CD workflows to reject unsigned code.</li></ul><h2>🚀 Conclusion</h2><p>Using SHAs, Git ensures the integrity of the history. Using GPG signatures, it guarantees its authenticity.</p><p>Two complementary mechanisms that make Git a reliable tool, not only for collaboration, but also for securing the software chain.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here:
<a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thank you for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/git-ensuring-the-integrity-and-authenticity-of-history</link><guid>https://blog.darkwood.com/article/git-ensuring-the-integrity-and-authenticity-of-history</guid><enclosure url="http://darkwood.com/media/articles/68bbc4dd5c9dc987216132.png" /></item><item><title>🔄 Reverse to better reign</title><pubDate>Sun, 07 Sep 2025 22:12:46 +0000</pubDate><description><![CDATA[
For nearly ten years, a conceptual blockage held back my experiments: how to properly manage the order of execution in a visual workflow? The answer eventually emerged in a simple but decisive form: invert the blocks to better reign. This blockage, experie...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68be035e87db6000890415.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/iWg6EH1tCNg?si=yIODWIX_wya_xZYg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>For nearly ten years, a conceptual blockage held back my experiments: how to properly manage the order of execution in a visual workflow? The answer eventually emerged in a simple but decisive form: invert the blocks to better reign. This blockage, experienced in my work with Uniflow, pushed me to explore numerous concepts from Flow-Based Programming to Lambda Calculus, including monads and Wave Function Collapse. All these detours finally converged on a clear solution: once a block is executed, it must remain immutable.</p><h2>⏱️ The problem with Canvas and Function blocks</h2><p>In Uniflow, each step of a workflow is represented by a block. Some are very operational, others more abstract. Two of them crystallized my blockage: * the Canvas block, which instantiates a drawing surface; * the Function block, which manipulates data. For a long time, I executed the Canvas before the Function. As a result, the function could return to modify a state already written in the Canvas. It was as if a reader came across the conclusion of a book before even having read the development, or worse, as if an author could rewrite a page already published. This mode of execution violated a fundamental principle: immutability. In a pipeline, each step must produce data that can no longer be altered, but only used in the following steps.</p><h2>🧠 The solution: inversion and immutability</h2><p>The fix consisted of reversing the order: first the Function, then the Canvas. Thus: * the function defines and passes the Canvas variable as input to the Canvas block, * the Canvas block executes its role from its own context, at the precise moment it is called, * and above all, once the Canvas is executed, it can no longer be rewritten. This reversal restores a clear logic, comparable to reading a text: from top to bottom, each line is added to the previous one, but none of them changes what has already been written.</p><h2>💡 Why this changes everything</h2><p>This simple reversal unlocks three essential dimensions: * Immutability: each block remains fixed once executed, which guarantees the consistency of the flow. * Conciseness: thanks to functional programming and currying, each pipe can pop the data produced by the previous ones, without ever rewriting the history. * Clarity: the pipeline becomes readable and predictable, each step naturally feeding the next. With this framework, Uniflow no longer manipulates fragile states, but stable and reproducible flows.</p><h2>⏱️ Concepts explored along the way</h2><p>To overcome this blockage, I had to dive into several concepts that, each in their own way, allowed me to build a broader understanding: * Railway Flow-Based Programming: thinking of pipes as rails where packets of information circulate. * Monads: guaranteeing the reproducibility of input and output types. * Y Combinator: introducing recursion into a language that doesn't have it natively. * Lambda Calculus: theoretical framework for expressing functions and their composition. * Chunk computing: cutting a calculation or an image into pieces, to then reconstitute the whole. * Wave Function Collapse: exploring all possible states and gradually reducing them by constraints. * Lambda Interpreter in PHP: experimenting with a minimal functional language to directly manipulate lambdas. * Flow: the culmination, combining visual orchestration, functional programming and asynchronous execution.</p><h2>💫 Conclusion</h2><p>“Invert and conquer” isn’t just a technical trick, but the resolution of a long-standing blockage: accepting that immutability is key. By reversing the order of block execution, Uniflow gains a consistency that makes it more like reading and writing text: each step builds on the previous one without ever rewriting it. This journey, fueled by years of exploring various concepts, has paved the way for more robust, concise, and powerful workflows.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>⚡Thank you for reading! Let's create smart, fast, and automated workflows together</p>
]]></content:encoded><link>https://blog.darkwood.com/article/reverse-to-better-reign</link><guid>https://blog.darkwood.com/article/reverse-to-better-reign</guid><enclosure url="http://darkwood.com/media/articles/68be035e87db6000890415.png" /></item><item><title>⛓️ Strong vs Weak References: Mastering Memory and Avoiding Leaks</title><pubDate>Tue, 09 Sep 2025 12:16:16 +0000</pubDate><description><![CDATA[In the world of software development, memory management is an often invisible, yet crucial, topic. The wrong approach can lead to memory leaks, degraded performance, or even unmaintainable applications. This is where two key concepts come into play: strong...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68c01a90ab39c834221832.png" /></p><p>In the world of software development, memory management is an often invisible, yet crucial, topic. The wrong approach can lead to memory leaks, degraded performance, or even unmaintainable applications. This is where two key concepts come into play: strong references and weak references.</p><h2>The Basics: Strong vs Weak</h2><ul><li><p>Strong reference This is the default behavior: as long as a variable points to an object, it remains alive in memory. Garbage collection (GC) or reference counting (ARC) cannot free it.</p></li><li><p>Weak reference It does not prevent the object from being freed. If no strong reference exists, the object can be collected, and the weak reference automatically becomes null (or invalid).</p></li></ul><p>In other words:</p><blockquote><p>The strong reference keeps the object alive. &gt; The weak reference observes the object without preventing it from disappearing.</p></blockquote><h2>Examples by language</h2><h3>Java: WeakReference and WeakHashMap</h3><pre><code class="language-java">Object obj = new Object(); // strong
WeakReference&lt;Object&gt; weak = new WeakReference&lt;&gt;(obj);

obj = null; // no more strong
System.gc(); // we force the GC
System.out.println(weak.get()); // can display null
</code></pre><p>WeakReferences are useful in caches. For example, <code>WeakHashMap</code> automatically removes entries whose keys are no longer referenced elsewhere.</p><h3>Rust: Rc vs Weak</h3><pre><code class="language-rust">use std::rc::{Rc, Weak};

let strong = Rc::new(5); // strong
let weak: Weak&lt;i32&gt; = Rc::downgrade(&amp;strong);

drop(strong); // no more strong
assert!(weak.upgrade().is_none()); // weak is invalid
</code></pre><p>Rust illustrates the distinction well:</p><ul><li><code>Rc::clone</code> increases the strong reference count.</li><li><code>Rc::downgrade</code> creates a weak reference, which can be upgraded to strong if the object is still valid.</li></ul><h3>Swift: Avoiding Cycles</h3><pre><code class="language-swift">class Person { var name: String weak var partner: Person? init(name: String) { self.name = name } }
</code></pre><p>Without <code>weak</code>, two partner <code>Person</code> objects would hold onto each other, creating a cycle where neither would ever be freed. With <code>weak</code>, the cycle is avoided.</p><h3>C++: shared_ptr and weak_ptr</h3><pre><code class="language-cpp">#include&lt;memory&gt; #include&lt;iostream&gt;

std::shared_ptr&lt;int&gt; strong = std::make_shared&lt;int&gt; (42);
std::weak_ptr&lt;int&gt; weak = strong;

strong.reset(); // frees the memory
if (auto s = weak.lock()) {
  std::cout &lt;&lt; *s;
} else {
  std::cout &lt;&lt; &quot;Object freed&quot;;
}
</code></pre><p><code>std::weak_ptr</code> allows you to break cycles and access an object only if it is still alive.</p><h2>Concrete use cases</h2><ul><li>Smart caches: use weak references to automatically free unused objects.</li><li>Avoid cycles: bidirectional relationships (e.g., parent ↔ child in Swift).</li><li>Interop and multithreading: fine-tune the lifetime of shared objects.</li><li>Advanced cleanup: via more specialized references (Soft, Phantom in Java).</li></ul><h2>Conclusion</h2><p>The distinction between strong and weak isn't just a matter of syntax: it's a powerful tool for writing safer, more efficient, and more maintainable code. In your next projects, ask yourself: <em>Do I need to keep this object alive, or just access it while it exists?</em></p><p>It's often the answer to this question that makes the difference between robust code and a future memory nightmare.</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>⚡Thank you for reading! Let's create smart, fast, and automated workflows together</p>
]]></content:encoded><link>https://blog.darkwood.com/article/strong-vs-weak-references-mastering-memory-and-avoiding-leaks</link><guid>https://blog.darkwood.com/article/strong-vs-weak-references-mastering-memory-and-avoiding-leaks</guid><enclosure url="http://darkwood.com/media/articles/68c01a90ab39c834221832.png" /></item><item><title>🎲 Rock-Paper-Scissors: A Minimal Model of Balance and Strategy</title><pubDate>Wed, 10 Sep 2025 16:33:15 +0000</pubDate><description><![CDATA[Rock-paper-scissors is often viewed as a simple choice mechanism. Yet, this binary system, expanded to three options, is a canonical example of dynamic equilibrium. Its loop structure illustrates fundamental principles of game theory, mathematical modeling,...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68c2bf0406211462363028.jpg" /></p><p>Rock-paper-scissors is often viewed as a simple choice mechanism. Yet, this binary system, expanded to three options, is a canonical example of dynamic equilibrium. Its loop structure illustrates fundamental principles of game theory, mathematical modeling, and competitive systems.</p><h2>Origins and diffusion</h2><p>The game originated in ancient China (shoushiling), before being adopted and formalized in Japan under the name jan-ken. Its international diffusion is explained by the clarity of its rules: three symbols, three relationships of domination, a closed cycle. This pattern has given rise to numerous expansions, notably rock-paper-scissors-lizard-Spock, which adds new nodes to the relational loop.</p><h2>A cyclic system and its equilibria</h2><p>The principle is based on a circular relationship:</p><ul><li>Rock beats Scissors</li><li>Scissors beats Paper</li><li>Paper beats Rock</li></ul><p>This loop implies the absence of a dominant strategy. In game theory, the situation corresponds to a mixed-strategy Nash equilibrium: each player must adopt a random distribution over the three choices in order to neutralize any exploitation. The interest lies in demonstrating that a very reduced system can illustrate a fundamental principle of equilibrium.</p><h2>Use cases and formalization</h2><p>Rock-paper-scissors can be used as an impartial decision-making protocol between two actors, as an alternative to a one-sided probabilistic coin toss such as a coin toss. The model also serves as an educational and theoretical tool to:</p><ul><li>illustrate the concept of mixed equilibrium,</li><li>introduce notions of probability and strategy,</li><li>demonstrate simple competitive dynamics.</li></ul><h2>Extensions and generalizations</h2><p>By adding new elements, the structure can expand into more complex directed graphs. Variants like RPS-101 generate a much denser network of relationships, but rely on the same fundamental principle: cyclical dominance. This concept goes beyond playful exploration: in evolutionary biology, some species form analogous cycles of competitive dominance. Similarly, in computer science and cryptography, rock-paper-scissors-inspired schemes model equilibria where no single strategy is stable in the long run.</p><h2>Conclusion</h2><p>Rock-paper-scissors illustrates, in its most basic form, a competitive system with no definitive outcome. Its circular structure makes it a prime pedagogical and analytical model for understanding stability through equilibrium, rather than domination. This minimal game is thus an effective conceptual framework for exploring much broader issues, from game theory to algorithms.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/rock-paper-scissors-a-minimal-model-of-balance-and-strategy</link><guid>https://blog.darkwood.com/article/rock-paper-scissors-a-minimal-model-of-balance-and-strategy</guid><enclosure url="http://darkwood.com/media/articles/68c2bf0406211462363028.jpg" /></item><item><title>🚀 Tech watch week 37</title><pubDate>Thu, 11 Sep 2025 14:40:13 +0000</pubDate><description><![CDATA[

This week&#039;s Watch highlights open source projects, applied research in AI and the web, and practical advances in PHP frameworks and development tools.
🎨 Prompt Engineering Framework
The Grace repository explores building a strongly typed prompt engineerin...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68c2e02033cb8086190350.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/XD_UE5CuudY" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>This week's Watch highlights open source projects, applied research in AI and the web, and practical advances in PHP frameworks and development tools.</p><h2>🎨 Prompt Engineering Framework</h2><p>The <strong>Grace</strong> repository explores building a strongly typed prompt engineering framework in Haskell. It highlights functional approaches to designing robust systems where prompts become testable and composable entities. A step closer to industrializing AI uses. 👉 <a href="https://github.com/Gabriella439/grace">github.com/Gabriella439/grace</a></p><h2>🤖 Multi-Agent Systems in Laravel</h2><p>Inspector presents a practical demo for building multi-agent systems in Laravel. The article shows how to orchestrate cooperative AI with simple code, paving the way for advanced applications integrated directly into the PHP ecosystem. 👉 <a href="https://inspector.dev/building-multi-agent-systems-in-laravel-a-practical-demo/">inspector.dev/building-multi-agent-systems-in-laravel-a-practical-demo</a></p><h2>🔢 Character counter and uniqueness</h2><p>Gary Hockin shares a technical insight into string counters and the importance of binary representations. An educational demonstration that illustrates how a coding detail can have real-world implications for software reliability. 👉 <a href="https://www.linkedin.com/posts/gary-hockin-9b06863a_3v4lorg-activity-7369816239499558912-nnvp">linkedin.com/posts/gary-hockin-9b06863a_3v4lorg-activity</a></p><h2>🏛️ DDD and Symfony 7</h2><p>Mykola Vantukh explains how to implement Domain-Driven Design in Symfony 7 using a clean architecture, reinforced by Deptrac. The article highlights best practices for maintaining clear boundaries between domains, applications, and infrastructure. 👉 <a href="https://dev.to/mykola_vantukh/ddd-in-symfony-7-clean-architecture-and-deptrac-enforced-boundaries-120a">dev.to/mykola_vantukh/ddd-in-symfony-7-clean-architecture</a></p><h2>🌀 Distributors in functional programming</h2><p>MorphismTech publishes a post on <strong>distributors</strong>, a mathematical generalization of functors. The text illustrates how these theoretical concepts can be used to structure and reason about complex data transformations. 👉 <a href="https://github.com/morphismtech/distributors/blob/main/blog.md">github.com/morphismtech/distributors</a></p><h2>👁️ Vision-Language World Model</h2><p>Pascale Fung introduces a <strong>vision-language model</strong> capable of reasoning on multimodal representations to create “world models”. A crucial step towards systems capable of anticipating and planning in hybrid text/image environments. 👉 <a href="https://www.linkedin.com/posts/pascale-fung-a3aa05139_introducing-vision-language-world-model-activity-7369704301943771143-gyA2">linkedin.com/posts/pascale-fung-vision-language-world-model</a></p><h2>🧬 SCILLA</h2><p>One thread highlights <strong>SCILLA</strong>, a framework for simulating complex systems inspired by physical laws. The tool allows for modeling multi-agent interactions and could find applications in AI research as well as in gaming. 👉 <a href="https://x.com/ponceto91/status/1963848330082963792?s=12">x.com/ponceto91/status/1963848330082963792</a></p><h2>🗄️ SQLite Vector Extension</h2><p>Philipp Schmid points out that SQLite now has a vector extension. This opens up interesting possibilities for running vector searches directly in a lightweight database, without relying on massive infrastructures like FAISS or Milvus. 👉 <a href="https://www.linkedin.com/posts/philipp-schmid-a6a2bb196_did-you-know-sqlite-has-a-vector-extension-activity-7369718072334622721-hFOE">linkedin.com/posts/philipp-schmid-sqlite-vector-extension</a></p><h2>✂️ Optimized string splitting</h2><p>Daniel Lemire illustrates how to efficiently split a long string into subsequences using implementation tricks. This optimization, when applied at scale, can improve the performance of tools handling massive text. 👉 <a href="https://x.com/lemire/status/1964779187136233964?s=12">x.com/lemire/status/1964779187136233964</a></p><h2>🎥 Veo3 on Replicate</h2><p>Replicate announces the availability of <strong>Veo3</strong>, an advanced video generation model. Accessible via API, it opens new possibilities for integrating generative video content creation into automated workflows. 👉 <a href="https://x.com/replicate/status/1930774344902541564?s=12">x.com/replicate/status/1930774344902541564</a></p><h2>🎨 Relative colors in CSS</h2><p>JoliCode offers a clear article on the use of <strong>relative colors</strong> in CSS. These new features simplify the management of themes and palette variations by making styles more expressive and maintainable. 👉 <a href="https://jolicode.com/blog/les-couleurs-relatives-en-css">jolicode.com/blog/les-couleurs-relatives-en-css</a></p><h2>🔎 Conclusion</h2><p>This week highlights a convergence between theoretical research (distributors, DDD), practical engineering (Laravel multi-agents, SQLite vector), and creative innovation (Veo3, CSS relative colors). A perfect illustration of the ongoing dialogue between fundamental concepts and concrete applications.</p><p>👉 And you, what tech discoveries have made an impression on you this week?</p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/tech-watch-week-37</link><guid>https://blog.darkwood.com/article/tech-watch-week-37</guid><enclosure url="http://darkwood.com/media/articles/68c2e02033cb8086190350.jpg" /></item><item><title>🚀 Symfony AI Hackathon – My online experience</title><pubDate>Fri, 12 Sep 2025 16:25:00 +0000</pubDate><description><![CDATA[
On September 12, 2025, the Symfony AI Hackathon was held, a full day dedicated to exploring and developing the Symfony AI ecosystem. The event took place in Berlin, at Quentic&#039;s offices, but also offered a hybrid mode thanks to Slack and a WorkAdventure in...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/common/images/site/cover.png" /></p><p><img src="/blog/images/articles/symfony-ai-hackathon-my-online-experience/workadventure.png" alt="workadventure.jpg" /></p><p>On September 12, 2025, the Symfony AI Hackathon was held, a full day dedicated to exploring and developing the Symfony AI ecosystem. The event took place in Berlin, at Quentic's offices, but also offered a hybrid mode thanks to Slack and a WorkAdventure instance. I had the opportunity to participate remotely, in the virtual space provided, and to actively contribute on several topics related to the AI Bundle and the Agent.</p><h2>🎯 The objectives of the hackathon</h2><p>Symfony AI is still <strong>very young</strong>. The initiative brings together several building blocks (Platform, Store, Agent, AI Bundle, MCP SDK) but remains in the ideation and experimentation phase. The objective of the hackathon was therefore twofold:</p><ul><li><strong>Explore real-life use cases</strong> of AI integration in Symfony,</li><li><strong>Accelerate contributions</strong> on GitHub repositories via issues and pull requests, by promoting direct collaboration between contributors.</li></ul><p>Fabien Potencier, Nicolas Grekas and other active members of the community were present to guide and support the participants.</p><h2>🗓️ The day's schedule</h2><ul><li><strong>10:00 a.m. – Opening</strong>: Welcome and introduction of objectives.</li><li><strong>10:15 a.m. – Topic selection</strong>: Group formation around themes such as the <strong>Doctrine Store</strong>, <strong>Platform Bridges</strong>, and response error management.</li><li><strong>10:30 a.m. – Intro for beginners</strong>: Setting up the environment (Ollama, API keys, link scripts for components).</li><li><strong>All day</strong>: Collaborative work on GitHub and fluid exchanges in WorkAdventure's virtual rooms.</li><li><strong>4:45 p.m. – Closing</strong>: Feedback, review of the day, thanks.</li></ul><h2>🔧 My technical contributions</h2><p>During the hackathon, I focused on two areas: integrating the <strong>Perplexity Bridge</strong> into the AI Bundle and adding new <strong>tools</strong> to the Agent.</p><h3>1. [AiBundle] Wire Perplexity bridge – <a href="https://github.com/symfony/ai/issues/534">Issue #534</a> ✅</h3><p>Plug the <strong>Perplexity Bridge</strong> (recently merged) into the AI Bundle. 👉 Result: Issue closed after integration.</p><h3>2. [AiBundle][Perplexity] Add platform configuration support – <a href="https://github.com/symfony/ai/pull/537">PR #537</a> ✅</h3><p>Added configuration support for Perplexity in the AI Bundle. 👉 Result: Issue closed with integrated commit (c85a4bc).</p><h3>3. [AI Bundle][Perplexity] Add integration for contract and token usage processors – <a href="https://github.com/symfony/ai/pull/564">PR #564</a> ✅</h3><p>Added <strong>output processors</strong> related to Perplexity (contract and token management). 👉 Result: issue closed with integrated commit (f1d488b).</p><h3>4. [Agent] Add tools for 3rd party integration – <a href="https://github.com/symfony/ai/issues/524">Issue #524</a> / <a href="https://github.com/symfony/ai/pull/549">PR #549</a> ⏳</h3><p>Work in progress on <strong>adding many tools</strong> to the Agent, to expand its integration ecosystem with third-party services. 👉 Contribution: opening a PR (#549) to introduce various tools. 👉 Result: PR still pending, which will be continued and discussed in the coming days.</p><h2>💡 What I learned</h2><ul><li>The hybrid format (in-person + WorkAdventure) allows for true immersion even remotely. * The “<strong>let's hack it together</strong>” approach encourages rapid and concrete contributions. * Symfony AI is moving forward on several fronts:</li><li><strong>Store</strong> (Doctrine, MongoDB Vector Search, etc.),</li><li><strong>Platform Bridges</strong> (including Perplexity),</li><li><strong>AI Bundle</strong> (centralization of integrations),</li><li><strong>Agent</strong> (tooling to interact with third-party APIs),</li><li><strong>MCP SDK</strong> (agent interoperability). * The collective energy and responsiveness of the maintainers make it possible to <strong>accelerate the maturation</strong> of a project still in the exploratory phase.</li></ul><h2>🚀 Conclusion</h2><p>The Symfony AI Hackathon was an <strong>enriching experience</strong>: contributing directly to such a young project, in a collaborative and open framework, is an excellent way to understand real needs and lay the first bricks of the ecosystem.</p><p>Symfony AI remains under construction, but this day confirmed one thing: <strong>the community is already there, motivated and creative</strong>, ready to make Symfony a key player in the integration of artificial intelligence into PHP applications.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/symfony-ai-hackathon-my-online-experience</link><guid>https://blog.darkwood.com/article/symfony-ai-hackathon-my-online-experience</guid><enclosure url="http://darkwood.com/common/images/site/cover.png" /></item><item><title>🎨 Pipe Programming: Linearizing Graph Complexity</title><pubDate>Sun, 14 Sep 2025 17:07:33 +0000</pubDate><description><![CDATA[
In many automation and dataflow tools, logic is represented as node graphs. This approach is intuitive at first glance: each node represents an operation, and arrows represent data flows. But as complexity increases, readability decreases sharply. Function...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68c6f66e564a9281351034.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/h8wUcALEpNA?si=Ymbp-tiqfbUem9vn" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>In many automation and dataflow tools, logic is represented as node graphs. This approach is intuitive at first glance: each node represents an operation, and arrows represent data flows. But as complexity increases, readability decreases sharply. Functional programming offers an elegant alternative: the pipe, a linear construct where transformations flow naturally from top to bottom, like reading a text.</p><h2>The node graph: intuitive but quickly complex</h2><ul><li>Two-dimensional representation.</li><li>Easy for small prototypes.</li><li>But: ambiguities (when does the data “pop”?), visual constraints (intersecting edges), increasing cognitive cost as the graph grows.</li></ul><p>Minimal example:</p><pre><code> [Source A] →  
               ↘
                 [ Merge ] → [ Transform ] → [ Output ]
               ↗
 [Source B] →
</code></pre><h2>The pipe: a linear and concise reading</h2><p>In functional programming, the same process can be represented as a pipeline:</p><pre><code class="language-php">use Flow\Flow;

$result = Flow::pipe(
    yield emit(['foo', 'bar']),    // Source A
    yield emit(['baz']),           // Source B
    yield merge(),                 // Merge
    yield transform(),             // Transform
    yield output()
);

echo $result; // &quot;FOO, BAR, BAZ&quot;
</code></pre><h2>The advantages of the pipe</h2><ul><li>Clarity: One direction, top to bottom, like a sentence being read.</li><li>Conciseness: Less visual noise, only transformations appear.</li><li>Maintainability: Adding or removing a step = adding or removing a line. No need to redraw a graph.</li><li>Predictability: Each step is the result of the previous ones, no uncertainty about “where the flow is”.</li></ul><h2>When to prefer the pipe to the graph?</h2><ul><li>For sequential data transformations.</li><li>For scalable pipelines where steps are added frequently.</li><li>For versioned code: a pipe is diffable in Git, whereas a binary/visual graph is not.</li></ul><h2>Conclusion</h2><p>The node graph remains relevant for visual prototyping or non-developer users. But as soon as the logic grows, the 2D representation quickly becomes a burden. Pipe programming, as implemented in Flow (flow.darkwood.com), offers a powerful alternative: linear, concise, easy to maintain, and above all, readable like text.</p><p>Key message:</p><blockquote><p><em>With a pipe, the logic is in the code, not in the cables.</em></p></blockquote><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/pipe-programming-linearizing-graph-complexity</link><guid>https://blog.darkwood.com/article/pipe-programming-linearizing-graph-complexity</guid><enclosure url="http://darkwood.com/media/articles/68c6f66e564a9281351034.png" /></item><item><title>✨ Meetup SQLI</title><pubDate>Wed, 17 Sep 2025 10:55:14 +0000</pubDate><description><![CDATA[On September 16, 2025, the Paris branch of AFUP launched the new season of PHP meetups. For this back-to-school season, the community gathered at the SQLI Digital Experience premises in Levallois-Perret, with a program focused on real-time communication and...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68ca9392e818b780405418.jpg" /></p><p>On September 16, 2025, the Paris branch of AFUP launched the new season of PHP meetups. For this back-to-school season, the community gathered at the SQLI Digital Experience premises in Levallois-Perret, with a program focused on real-time communication and developer experience.</p><p>The AFUP Paris September meetup was held at SQLI Digital Experience, marking the launch of the 2025-2026 season. As with every meetup, the event brought together the PHP community around two technical presentations, as well as discussions, exchanges, and convivial moments.</p><p>As a reminder, the AFUP (French Association of PHP Users) organizes monthly meetups in Paris (excluding the summer period). These evenings are an opportunity to discover new topics related to PHP and its ecosystems—whether frameworks, databases, DevOps tools, or even methodologies like agility.</p><p>The association lives thanks to its members and partners: - Speakers who come to share their feedback, - Sponsors who host events in their premises, - Volunteers who lead the community and offer formats (mentoring, conferences, forums, etc.).</p><p>At the same time, AFUP also offers two major annual conferences: the PHP Forum, which will be held on October 9 and 10, 2025, at the Hotel New York – Disneyland Paris, and the PHP Tour. These events have become essential for anyone interested in the evolution of PHP and its ecosystem.</p><p>At SQLI, the evening began with a presentation of the company and its activities in digital, e-commerce, and large-scale PHP architectures, before giving way to technical talks.</p><p>1️⃣ Server-Sent Events and ZeroMQ – by Amaury Bouchard</p><p>The first presentation highlighted an elegant alternative to websockets: Server-Sent Events (SSE).</p><p>Concept: a one-way flow from server to client, based on HTTP, simple to set up and compatible with the majority of browsers.</p><p>Practical case: Amaury demonstrated how to integrate SSE with ZeroMQ, a high-performance messaging library. The chosen example was a small real-time chat software, demonstrating the simplicity and robustness of the SSE + ZMQ pair.</p><p>Challenges: This combination makes it possible to build reactive applications without falling into the complexity of websockets, while relying on a proven infrastructure.</p><h2>SSE in two minutes</h2><ul><li>What? A unidirectional channel (server → client) over HTTP/1.1. * Why? Simpler than WebSocket when you don't need permanent upstream (chat, notifications, live metrics, logs, etc.). * How? The server responds in <code>text/event-stream</code>, keeps the connection open, sends formatted events; the client reconnects by itself if the connection breaks. * Bonus: you can multiply the logical flows via the <code>event:</code> field (multiplexing).</li></ul><h3>Minimal client (browser)</h3><pre><code class="language-html">&lt;ul id=&quot;log&quot;&gt;&lt;/ul&gt;
&lt;script&gt;
  const ul = document.getElementById('log');
  const es = new EventSource('/events'); // endpoint SSE

  // Default event es.onmessage = (e) =&gt; { const li = document.createElement('li'); li.textContent = e.data; // payload text ul.appendChild(li); };

  // Multiplexing: listen to a named event type es.addEventListener('chat', (e) =&gt; { const { user, text } = JSON.parse(e.data); const li = document.createElement('li'); li.textContent = `[${user}] ${text}`; ul.appendChild(li); });&lt;/script&gt;
</code></pre><h3>Minimal server (“educational” PHP)</h3><pre><code class="language-php">&lt;?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Connection: keep-alive');

// Emit loop while (true) { $payload = ['ts' =&gt; time(), 'msg' =&gt; 'tick']; // optional event for multiplexing echo &quot;event: tick\n&quot;; echo &quot;data: &quot; . json_encode($payload) . &quot;\n\n&quot;; @ob_flush(); @flush(); // Keep the frame rate and CPU low sleep(2); }
</code></pre><p>Format of an SSE event</p><pre><code>event:&lt;nom-optionnel&gt; id:&lt;cursor-optionnel&gt; retry:&lt;ms-optionnel&gt; data:&lt;ligne-1&gt; data:&lt;ligne-2&gt;&lt;ligne-vide&gt;
</code></pre><h2>Why it works well in PHP</h2><ul><li>No dedicated infrastructure required: it's HTTP. * Easy to deploy behind a reverse proxy. * The client handles the reconnection (<code>EventSource</code>).</li></ul><blockquote><p>Natural limitation: no upstream (client → server). To send a message, we use a classic HTTP request (AJAX/Fetch), and we leave the push to the SSE.</p></blockquote><h2>Add ZeroMQ: structuring the flows</h2><p>ZeroMQ (ØMQ) is a high-performance messaging library offering ready-to-use patterns:</p><ul><li><code>REQ/REP</code> – request/response (simple RPC) * <code>PUSH/PULL</code> – work queue (pipeline) * <code>PUB/SUB</code> – broadcast (broadcast to subscribers)</li></ul><p>Key idea of the talk:</p><ul><li>Browsers listen via SSE. * The application server subscribes to a <code>PUB/SUB</code> broker (ZeroMQ). * Incoming messages (forms, APIs) are pushed (<code>PUSH</code>) to the broker, which publishes (<code>PUB</code>) to all SSE controllers.</li></ul><h3>Diagram (text)</h3><pre><code>[HTTP Client] --POST /message--&gt; [Controller &quot;message&quot;] --PUSH--&gt; [Broker ØMQ] --PUB--&gt; [Controller &quot;events&quot;] --SSE--&gt; [Browser(s)]
</code></pre><h3>Broker-side sketch (PHP + ext-zmq)</h3><pre><code class="language-php">$context = new ZMQContext();

// Receiving application messages $pull = new ZMQSocket($context, ZMQ::SOCKET_PULL); $pull-&gt;bind('tcp://*:5557');

// Broadcast to SSE consumers $pub = new ZMQSocket($context, ZMQ::SOCKET_PUB); $pub-&gt;bind('tcp://*:5556');

while (true) { $msg = $pull-&gt;recv(); // wait for a message $pub-&gt;send($msg); // broadcast }
</code></pre><h3>“events” controller (consumes PUB, emits SSEs)</h3><pre><code class="language-php">header('Content-Type: text/event-stream'); header('Cache-Control: no-cache');

$context = new ZMQContext(); $sub = new ZMQSocket($context, ZMQ::SOCKET_SUB); $sub-&gt;connect('tcp://broker:5556'); $sub-&gt;setsockopt(ZMQ::SOCKOPT_SUBSCRIBE, ''); // All

while (true) { $msg = $sub-&gt;recv(); // JSON {user, text} echo &quot;event: chat\n&quot;; echo &quot;data: $msg\n\n&quot;; @ob_flush(); @flush(); }
</code></pre><h3>“message” controller (receives a POST, pushes to the broker)</h3><pre><code class="language-php">$user = trim($_POST['user'] ?? ''); $text = trim($_POST['text'] ?? ''); if ($user !== '' &amp;&amp; $text !== '') { $context = new ZMQContext(); $push = new ZMQSocket($context, ZMQ::SOCKET_PUSH); $push-&gt;connect('tcp://broker:5557'); $push-&gt;send(json_encode(['user' =&gt; $user, 'text' =&gt; $text])); } http_response_code(204);
</code></pre><h2>Practical notes &amp; pitfalls avoided</h2><ul><li>Proxy-side SSE: Allow long connections and flushing (disable compression on this path, keep <code>X-Accel-Buffering: no</code> under Nginx if necessary). * Back-pressure: Emit at a reasonable rate and flush to avoid accumulating (otherwise memory). * Multiplexing: Use <code>event:</code> to distinguish between streams (<code>chat</code>, <code>metrics</code>, <code>alerts</code>). * Reconnection: <code>EventSource</code> automatically tries; server-side, remain idempotent and allow a <code>retry:</code> if necessary. * Security: Validate/sanitize all messages, never broadcast raw user input.</li></ul><h2>Summary</h2><ul><li>SSE = server-to-browser push, simple and reliable, perfect for live diffs. * ZeroMQ = application glue for cleanly routing/broadcasting messages. * Together, we get a minimalist, clean, and extensible real-time chat — without building a full WebSocket stack.</li></ul><p>2️⃣ Configuration formats and Symfony – by Nicolas Grekas</p><p>The second presentation was led by Nicolas Grekas, a key figure in the Symfony framework.</p><p>Topic: An overview of the configuration formats available in Symfony — YAML, XML, and PHP.</p><p>Key points:</p><p>YAML, long favored for its readability, has maintainability limitations.</p><p>XML, more verbose, keeps specific use cases.</p><p>PHP is gaining popularity because it offers language power, completion, and IDE integration.</p><p>DX (Developer Experience) approach: the discussion showed how the choice of format directly impacts team productivity and experience.</p><h2>The observation</h2><ul><li>Three historical formats coexist: YAML, XML, PHP (fluid config generated from the configuration tree). * This plurality makes discovery more cumbersome (doc, multiple tabs), multiplies the options, and increases the cognitive load for new and old users. * DX: the choice of format impacts onboarding, IDE tooling, navigation/refactor, Flex patches and collaboration (QA teams, non-PHP, etc.).</li></ul><h2>What each format brings (and costs)</h2><p>| Format | Strengths | Limitations / Frictions | | ----------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | | YAML | Simple, concise, known beyond PHP, easy to read/share | Implicit typing, “ugly” references (const/enum), plugin-dependent tooling, indentation errors | | XML | Very explicit, schematizable, used by ecosystems (e.g. Sylius/Sulu) | Verbose, not appreciated for semantic app configuration | | PHP (fluid configuration) | Typed references, IDE completion, robust refactor | Verbose, less “diffable”, incompatible with Flex recipes (complicated automatic patching) |</p><blockquote><p>Key point: Flex can patch YAML/XML deterministically; not arbitrary PHP code. This is a major obstacle for DX and the ecosystem.</p></blockquote><h2>Proposed Direction (work in progress)</h2><ol><li><p>Deprecate XML for semantic configs (e.g. <code>framework</code>, <code>messenger</code>, …) and application-side routes, in favor of PHP (already adopted internally on the Symfony side).</p><ul><li>Keep XML where it remains structural and interop (e.g. service declarations provided by bundles, specific cases of ecosystems).</li></ul></li><li><p>Keep YAML as the major application-side format: readable, stable, widely understood (multi-language teams, QA, CI/CD tooling).</p></li><li><p>Don't &quot;kill&quot; PHP: The fluid PHP format remains the most typed and pleasant option in IDE for those who want it — but without breaking Flex.</p></li></ol><h2>News / in-depth projects</h2><h3>A. Compilation “Resources” (beyond services)</h3><p>Introduce the notion of resource (classes carrying useful metadata) known to the container at compilation:</p><ul><li>Example: entities with validation constraints (attributes), serialization metadata, etc. * Goal: discover and freeze this information at compile time (instead of runtime reflection), for faster startups and more robust DX (less late magic).</li></ul><h3>B. Compiled attributes (not just runtime)</h3><ul><li>Today, attributes work at runtime via reflection. * Work in progress: collect attributes at compile time, generate mappings (validation, serialization, etc.) and reduce runtime load.</li></ul><h3>C. Properly extend/override metadata… without enforced XML</h3><ul><li>Real cases (e.g. Sylius/Sulu): we extend validation constraints via YAML/XML. * Objective: to offer a modern alternative (dedicated “support” classes, compiled attributes) to extend models without locking projects into XML.</li></ul><h3>D. PHP Arrays with Strong Autocompletion</h3><ul><li>Exploration: Describe the config tree so that PHP tables benefit from rich IDE autocompletion (depth-dependent valid keys, inline doc). * Active collaboration with IDE teams (e.g. PhpStorm) to better support comments/doc and nested keys → Table DX greatly improved.</li></ul><h2>DX points discussed (and arbitrations)</h2><ul><li>YAML vs PHP performance: negligible differences in use (parse at build/cache). * Readability: YAML remains compact for app config; PHP gains in refactoring and typing. * Non-PHP teams: YAML remains universal (QA, ops, docs). * Flex: decisive argument for keeping YAML/XML where recipes must patch projects automatically.</li></ul><h2>What could “visibly” change</h2><ul><li>Fewer tabs and ambiguities in the docs (reducing recommended formats based on configuration type). * XML pushed back where it doesn't provide a direct benefit (semantic config &amp; app routing). * Compiled attributes + resources: faster builds, more predictable bundles. * Smarter autocompletion for PHP arrays (better discovery of possible keys and values).</li></ul><h2>Summary</h2><ul><li>No “religious war”: YAML remains comfortable and interop; PHP is strong in IDE; XML is retreating where it is no longer useful. * Efforts are focused on global DX: Flex, doc, tools, compilation of attributes and safer formats. * Course: simplify choices, reduce dispersion, and accelerate the dev loop thanks to compiled metadata and significantly improved autocompletion.</li></ul><p>3️⃣ Beyond the talks: the value of the meetup</p><p>Beyond technical topics, the event confirmed the importance of meetups for:</p><p>Meet the Parisian PHP community and discuss best practices.</p><p>Discover concrete approaches through live code, without superfluous slides.</p><p>Create links between experts, beginners and the curious, in a friendly atmosphere.</p><p>📌 Conclusion</p><p>Between simplified real-time thanks to SSE/ZMQ and reflection on DX in Symfony, this first meetup of the season laid solid foundations for future meetings. Many thanks to SQLI for the welcome and to the speakers for their energy and concrete demonstrations.</p><p>👉 See you next month for the continuation of the AFUP Paris meetings!</p>
]]></content:encoded><link>https://blog.darkwood.com/article/meetup-sqli</link><guid>https://blog.darkwood.com/article/meetup-sqli</guid><enclosure url="http://darkwood.com/media/articles/68ca9392e818b780405418.jpg" /></item><item><title>🔨 API Platform Conference 2025: a look back at two intense days focused on the Symfony and PHP ecosystem</title><pubDate>Sat, 20 Sep 2025 14:11:15 +0000</pubDate><description><![CDATA[The 2025 edition of the API Platform Conference took place on September 18th and 19th. For two days, the Symfony, PHP, and API communities gathered around keynotes, feedback, and passionate discussions. Here&#039;s a talk-by-talk recap to keep a complete record...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68ceba3538fa3911828222.png" /></p><p>The 2025 edition of the API Platform Conference took place on September 18th and 19th. For two days, the Symfony, PHP, and API communities gathered around keynotes, feedback, and passionate discussions. Here's a talk-by-talk recap to keep a complete record of the event's takeaways.</p><h2>🎤 Day 1 – September 18</h2><h3>🔑 Opening Keynote – <em>Kévin Dunglas</em></h3><p>Introducing the new features of API Platform 4.2, with a focus on automation, real-time support (Mercury, SSE), and LLM integration. A clear vision for the future of the ecosystem.</p><h1>🔑 Keynote by Kévin Dunglas – 10 years of API Platform and a major new feature</h1><p>To celebrate API Platform's 10th anniversary, its creator, Kevin Dunglas, took to the stage in Lille with a major announcement: a new feature shared by API Platform and FrankenPHP.</p><h2>👨‍💻 A community and cooperative journey</h2><p>Kévin recalled his many roles: maintainer of Symfony and PHP, co-founder of the Les-Tilleuls.coop cooperative, and initiator of projects such as Mercure, FrankenPHP, and several Symfony components. He emphasized his company's cooperative model, where decisions are made democratically and profits are shared.</p><h2>🎂 Ten years of API Platform</h2><ul><li>It started as a simple Symfony bundle of 2000 lines of code to expose a REST API. * Today: a complete library, usable with Symfony, Laravel or without a framework, with nearly 10,000 GitHub stars and nearly 1000 contributors. * The spirit of the project remains the same: exposing modern APIs from simple PHP classes, while offering multi-style support.</li></ul><h2>🌐 Multi-API Support</h2><p>API Platform now allows you to automatically generate:</p><ul><li>REST (Hydra, HAL, JSON:API) * OpenAPI (machine-readable description) * GraphQL * Async APIs with Mercure and SSE</li></ul><p>This ability to unify multiple API styles with the same code remains a unique strength of the framework.</p><h2>💡 What's new: gRPC with FrankenPHP</h2><p>The big announcement was the arrival of gRPC in the ecosystem.</p><ul><li>gRPC (created by Google) is a high-performance protocol based on Protocol Buffers and HTTP/2. * Advantages: Strongly typed, fast, efficient communication, suitable for microservices, IoT and critical systems. * Until now, PHP could not serve as a gRPC server (technical limitation).</li></ul><p>👉 Thanks to FrankenPHP, written in Go, it is now possible to:</p><ul><li>write Go extensions for FrankenPHP, * create a gRPC server that delegates business logic to PHP workers, * combine the best of both worlds (Go for network performance, PHP for application logic).</li></ul><p>A prototype FrankenPHP gRPC extension is already available on Kevin's GitHub.</p><h2>📈 Perspectives</h2><ul><li>Automatically generate proto files from API Resource entities. * Integrate gRPC directly as a supported format by API Platform. * Facilitate interoperability between PHP, Go, and other languages.</li></ul><h2>🤝 A community above all</h2><p>Kevin concluded by reiterating that the true strength of API Platform is its community: contributors, trainers, and developers. He also paid tribute to Ryan Reza, a major contributor who recently passed away, and called for support for his family through a fundraiser.</p><h3>📌 In summary</h3><p>The opening keynote celebrated 10 years of innovation and community around API Platform, while announcing a major development: ➡️ the arrival of gRPC in the ecosystem via FrankenPHP. This advancement brings Symfony, Laravel, and the PHP world even closer to the future of modern APIs.</p><h3>⚡ Performance</h3><ul><li>180,000 requests per second explained simply – <em>Xavier Leune</em> An educational talk that detailed the techniques behind extreme performance: fine-grained connection management, choice of network architecture, and the importance of runtime.</li></ul><p>Here's a clear, structured, and ready-to-deliver version of Xavier Leune's (FR) talk. I've reorganized the speech, clarified the technical ideas, and kept the demonstrations and practical tips—all while maintaining the educational tone.</p><h1>Network performance and concurrency in PHP</h1><p><em>(kern, non-blocking IO, TCP/TLS, HTTP/2/3, DNS, fork &amp; memory sharing)</em></p><p>Hello—I'm Xavier Leune. Today we're going to talk about very practical things: how to efficiently handle thousands of requests from PHP, why the CPU behaves the way it does, and what techniques to use to avoid running into a connection wall.</p><h2>Context: why we waste CPU time when waiting for responses</h2><p>When you're doing a lot of network requests, most of the time is spent waiting (IO) — not actually computing. However, in a typical synchronous script, you can see a lot of CPU cycles consumed just by running in a loop that polls the IO state: doing <code>false</code>, <code>false</code>, <code>false</code> over and over again. A typical result: you get 10 seconds of real time, but you consume 20s of cumulative CPU, because loops are running in vain.</p><h2>Kernel / Non-blocking IO: Free up the CPU</h2><p>The solution is to let the kernel (or runtime) handle the wait rather than spinning in userland. Two approaches:</p><ul><li>Naive polling: active loop that checks without pausing → expensive in CPU. * Select / epoll / kqueue: we wait for the kernel to signal a ready IO. In PHP, using the equivalent (select, stream_select, or libs/event) drastically reduces iterations and CPU time: we go from thousands of iterations to a few dozen.</li></ul><p>Concretely: replace a <code>while (!done) { check(); }</code> loop with a <code>select</code> which wakes up the script when there are events to process.</p><h2>Attention to the ceiling: establishing connections</h2><p>Establishing a TCP connection costs: system resources, sockets, handlers, etc. If you open 2k, 4k, 8k connections in a short time, you risk:</p><ul><li>full server-side backlog → SYN which is never handled; * client-side timeouts (5–15s) because the connection was never completed; * errors visible only at scale (timeouts, refusals, drops).</li></ul><p>Tip: throttle the number of active connections—for example, limit <em>N</em> simultaneous connections and only launch new ones when one becomes available. Gradually increase <em>N</em> based on actual behavior.</p><h2>TLS (HTTPS): an additional costly step</h2><p>After the TCP handshake, TLS adds round trips (handshakes) and cryptographic computation. This increases the connection latency. If you multiply the number of short encrypted connections, the cost per request increases significantly.</p><ul><li>If possible, reuse connections (connection pooling / keep-alive). * If you need to open a lot of connections, count the TLS cost and test with your actual load.</li></ul><h2>Decorrelation of connections ↔ requests: multiplexing &amp; protocol</h2><p>History:</p><ul><li>HTTP/1.x: one request = one connection (or limited pipelining) → many connections. * HTTP/2: multiplexing on a single connection (multiple streams), independent order, reduced number of connections. * HTTP/3 (QUIC): over UDP, lighter connection, integrated TLS support, designed for high-latency &amp; high-loss mobile networks.</li></ul><p>Practical consequences:</p><ul><li>With HTTP/2, we reduce the number of connections and significantly increase the request rate/s on a well-configured server. * With HTTP/3, we gain resilience on unstable networks, reduced latency in certain mobile scenarios, but the client &lt;-&gt; server side implementations can still be less mature than HTTP/2 depending on the stacks.</li></ul><h2>TCP: retransmission &amp; head-of-line blocking</h2><p>With (reliable) TCP, if a packet loses the third response, TCP will retransmit the entire block in question—which can block other multiplexed responses if you don't have a more modern protocol (QUIC/HTTP3). Hence the interest in using QUIC for certain cases (mobile latency, losses)—but be careful: server-client implementations and tools must be mature.</p><h2>DNS and client-side load balancing</h2><p>If your domain has multiple A records (or multiple backends), how you resolve the IP affects your load distribution:</p><ul><li>DNS resolution on every request can help increase recipient diversity (round-robin). * Client-side caching resolution can concentrate the load on a single backend. * Sometimes rotating DNS resolution (doing your own) helps distribute the load.</li></ul><p>Handy tip: Pre-resolve backend IPs, build your queries on those IPs to force client-side round-robin if needed.</p><h2>Measurements &amp; Comparisons: HTTP/1 vs HTTP/2 vs HTTP/3 (Summary)</h2><p>Classic observations on load tests:</p><ul><li>HTTP/1: Huge number of connections, low RPS per socket, high client CPU. * HTTP/2: Much fewer real connections, very high RPS (thousands → tens of thousands). * HTTP/3: Sometimes better on mobile/unstable links; in practice results vary depending on implementation, but conceptually avoids some TCP blocking.</li></ul><p>Conclusion: HTTP/2 is often the best compromise for most server→browser/API loads, except in mobile/extreme latency cases where HTTP/3 can help — test.</p><h2>Increase CPU on the client side: fork / parallel / pcntl</h2><p>Sometimes you want to fully utilize the client CPU (load testing, heavy processing). Options in PHP:</p><ul><li>pcntl_fork (process fork): child process creation; simple, robust; beware of shared resources (sockets, DB). * parallel (extension): parallel execution in lightweight threads (if available). * pthreads (deprecated / non-CLI), other OS-level solutions.</li></ul><p>Important: after a fork, do not share the same open connections (sockets, DB handles) between parent and child without precautions — it breaks the flow. Two approaches:</p><ol><li>Open the connection after the fork: each process has its own socket/DB. 2. Close and reopen the connection in the child: safe and simple.</li></ol><h2>Communication between processes: shared memory</h2><p>When forking, you need a way to synchronize/communicate:</p><ul><li>Shared Memory (shmop / SysV shm / ext-shm): Create a shared memory area to read/write strings, states, etc. Useful, simple. * Unix semaphores / files / sockets: Alternatives as needed.</li></ul><p>Classic Pattern:</p><ul><li>parent creates shared memory (ftok + shmget), * child writes periodically, * parent reads / waits (poll / sleep); * cleanup at the end.</li></ul><h2>Resources to watch &amp; best practices</h2><ul><li>Limit simultaneous connection creation (throttle). * Reuse connections (keep-alive, pools). * Use select/epoll in non-blocking IO mode — do not spin. * Test TLS cost (handshake): measure the impact on latency. * Monitor server backlog: increase <code>somaxconn</code> or server config if needed. * After <code>fork</code>, reopen connections on the child side. * Pre-resolve / manage DNS if you want to distribute the client-side load. * Measure: client CPU, server CPU, RPS, p95/p99 latency, errors/timeouts.</li></ul><h2>Demo &amp; Results (Summary)</h2><ul><li>Naive synchronous script (200 concurrent, 1000 requests → slow server): very high client CPU. * Same script using <code>select</code> / wait: greatly reduced client CPU, loop iterations divided by &gt;100. * Added throttling on connection establishment: reduced timeouts and errors. * Comparative test HTTP/1 vs HTTP/2 vs HTTP/3: HTTP/2 gives the best throughput on our bench – HTTP/3 interesting but variable depending on stack.</li></ul><h2>Where to find the code and continue</h2><p>All demo code and scripts are available on GitHub (repository linked to the presentation) — you can clone, run the benches and adjust the settings for your infrastructure.</p><h2>Conclusion</h2><ul><li>Effective network concurrency is not just about opening more connections: it's about using the kernel for IO, limiting concurrent connections, reusing resources, and adapting the protocol (HTTP/2/3) to the context. * When you scale up the load, observe the signals: backlog, timeouts, client/server CPU, network errors, and adjust your architecture.</li></ul><p>Thanks — if you have any questions I'm here after the session, and the code is live on GitHub.</p><ul><li><p>API Platform, JsonStreamer and ESA for a skyrocketing API – <em>Mathias Arlaud</em> Highlighting JSON streaming to reduce memory consumption and boost the response speed of large-scale APIs.</p></li><li><p>Scaling Databases – <em>Tobias Petry</em> Exploring database scaling strategies: sharding, replication, index optimization. A reminder of the central role of the database in performance.</p></li></ul><h3>🏗️ Feedback and architecture</h3><ul><li><p>API Platform in PrestaShop, a walk in the park? – <em>Johathan Lelièvre</em> Concrete feedback on the integration of API Platform into an existing e-commerce environment. Challenges: compatibility, performance, and gradual migration.</p></li><li><p>API Platform x Redis – <em>Clément Talleu</em> Presentation of the uses of Redis with API Platform to accelerate cache, sessions and job queue.</p></li><li><p>Design Pattern, the treasure is in the vendor – <em>Smaïne Milianni</em> A conceptual talk: how patterns buried in our dependencies influence our architectures and how to better exploit them.</p></li><li><p>What if we used Event Storming in our API Platform projects? – <em>Grégory Planchat</em> Demonstration of Event Storming as a collaborative method for designing rich and coherent models.</p></li></ul><h1>The quest for “truth” in distributed systems</h1><p><em>The talk by Rob Landers (Engineering Manager, Fintech) — put into an article</em></p><h2>TL;DR</h2><ul><li>“Truth” in software = provable facts → <em>source of truth</em> (database) + <em>prove</em> (application). * Caching accelerates… and introduces lies if poorly designed (incomplete keys, random invalidations, transactional pollution, race-to-stale). * External effects (email, payments, webhooks) do not participate in your transactions. Solution: outbox + message bus + idempotency. * Sharding multiplies truths and destroys your guarantees (transactions, joins, migrations). Avoid as much as possible. * Objective: consistent caches, reliable effects, trustworthy systems when (not if) the failure occurs.</li></ul><h2>What is “truth” for an application?</h2><ul><li><p>Philosophically vague, in software we construct it:</p><ul><li>Bucket of facts = database (source of truth). * Proving these facts = your application (business logic, invariants). * If you can stick to this simple model (App ↔ DB), stick to it.</li></ul></li></ul><h3>The inevitable cache</h3><p>*Perf pressure → “We put a cache and everything will be better.” * Yes… until the day when the cache contradicts the DB and makes the system diverge.</p><h2>The 4 classic cache traps (and how to avoid them)</h2><h3>a) Incomplete keys (key collision)</h3><p>Anti-pattern</p><pre><code class="language-php">$key = &quot;bookstore.revenue.$year&quot;; // missing storeId! return $cache-&gt;remember($key, fn() =&gt; calcRevenue($storeId, $year));
</code></pre><p>Fix: Encode all dependencies in the key.</p><pre><code class="language-php">$key = &quot;bookstore.$storeId.revenue.$year&quot;;
</code></pre><h3>b) Invalidations impossible</h3><ul><li>If your key encodes the <em>what</em> but not the <em>who/when</em>, you don't know what to invalidate on change. * Solution: tags/groups. Example: tag by <code>store:$id</code> and <code>year:$year</code>, then invalidate by tag.</li></ul><h3>c) Transactional pollution</h3><ul><li><p>You write to the cache before <code>COMMIT</code>. * If the transaction rolls back, the cache broadcasts a lie (uncommitted value). * Rule of thumb: write/invalidate the cache <em>after</em><code>COMMIT</code>.</p><ul><li>Implement a transaction-aware cache (post-commit hooks). * Or move the “cache layer” to the DB side (materializations/indexes/query plan) to benefit from ACID properties.</li></ul></li></ul><h3>d) Race-to-stale</h3><ul><li><p>T1 updates DB + invalid → T2 reloads old value between inval and commit → cache obsolete. * Mitigations:</p><ul><li>Order “<code>COMMIT</code> → invalidate/write” (post-commit hooks). * Locks/versions (ETags, object versions) in the cache. * Short TTLs + robust cache-aside.</li></ul></li></ul><blockquote><p>Cache checklist &gt; &gt; * [ ] Keys = all dependencies (user, locale, filters, feature flags, etc.). &gt; * [ ] Invalidations by tags/groups. &gt; * [ ] Post-commit cache writes only. &gt; * [ ] Concurrency tests (race conditions). &gt; * [ ] Observability (hit/miss, stale rate, latencies).</p></blockquote><h2>External effects: truth outside the transaction</h2><h3>The problem</h3><ul><li>Payments, emails, webhooks, third-party APIs: not in your transaction. * Irreversible effect (email sent), invisible state until commit, unchecked retries.</li></ul><h3>The pattern that works</h3><ol><li>Outbox (in your DB): before “publishing”, write a message to the database in the same transaction as your business data. 2. Message bus (e.g. Symfony Messenger with Doctrine transport) reads the outbox after commit, executes the effect, marks success/failure. 3. Idempotency keys on the provider side (payment, email): at least once → only one application of the effect.</li></ol><pre><code class="language-mermaid">flowchart LR A[App] -- Tx begin --&gt; DB[(DB)] A --&gt;|write data + outbox| DB DB --&gt;|COMMIT| Q[Outbox Reader / Messenger] Q --&gt; S[External service] S --&gt; Q --&gt; DB
</code></pre><h3>Bonus</h3><ul><li>Compensating actions: we “cancel” by moving forward (e.g., refund). * Idempotence on the <em>consumer</em> side of webhooks as well (deduplication by key).</li></ul><h2>“Scaling to infinity”: why sharding is (often) a false good idea</h2><ul><li>No more global transactions (or very expensive). * No more inter-shard joins → painful denormalization. * Long and risky migrations (multi-schema <em>long-lived</em> code). * Cache keys to be expanded (include <code>shardId</code>). * Search to be (re)invented. * Non-unique clock (the “now” varies by shard).</li></ul><blockquote><p>Recommendation: First exhaust all vertical/horizontal without sharding &gt; (indexes, queries, read replicas, internal partitioning, consistent caching, CQRS, projections/materialized views). &gt; Sharding comes very far in the curve.</p></blockquote><h2>“Reliable Truth” Recipe</h2><ol><li>DB = source of truth. Database invariants, constraints, transactions. 2. Cache: full dependencies, driven invalidations, post-commit only, race tests. 3. Side-effects: Outbox + Bus + Idempotence (+ compensations). 4. Observability: cache metrics (hit/stale), outbox delays, retry rates, dead-letter queues, audit trail. 5. Resilience: timeouts, backoff, circuit breakers, bulkheads. 6. Tests: concurrency (race), mild chaos (disable a cache node, inject latency). 7. Do not shard as long as other levers exist.</li></ol><h2>Appendix — Anti-patterns &amp; remedies</h2><ul><li><code>if ($isAdmin) { … } if ($isCustomer) { … }</code> → prefer <code>if … elseif …</code> if exclusive; otherwise make compound states (FSM/invariants) explicit. * Write to cache in a transaction → move the write to a post-commit hook or a Doctrine listener. * “By hand” invalidations → tags/groups + “ownership” of keys by bounded context. * Bus without idempotence → deterministic key (e.g. business UUID) → <em>at-least-once</em> becomes <em>effectively once</em>. * Non-deduplicated webhooks → table <code>webhook_receipts(idempotency_key, received_at, status)</code> + unique index.</li></ul><h2>Conclusion</h2><p>“Truth” isn’t found: it’s engineered. By setting clear boundaries (DB, cache, effects), requiring time commitments (post-commit), and treating the outside as untrustworthy by default (outbox/idempotence), we build systems that fail without collapsing—and that tell the truth, even under pressure.</p><h3>🛠️ Tools and practices</h3><ul><li>Composer Best Practices 2025 – <em>Nils Adermann</em> Current recommendations for effectively managing dependencies: version constraints, security, build reproducibility.</li></ul><p>#🧰 Composer Best Practices 2025 — by Nils Adermann</p><blockquote><p>“Many good practices haven’t changed in 5–10 years… but the ecosystem, social security and our tools are changing.” — Nils</p></blockquote><h2>🆕 What changes (2025)</h2><ul><li><p>Goodbye Composer 1 / Packagist API v1</p><ul><li>Upgrade to Composer 2 (mandatory for updates; Composer 1 can no longer resolve via v1). * If you're stuck, private proxies can help... but the safest route remains migration.</li></ul></li><li><p>New supply chain threats</p><ul><li>Typosquatting and AI-induced packages (names invented and then published by attackers). * Increased vigilance on what you add to <code>composer.json</code>.</li></ul></li><li><p>Small features that change life</p><ul><li><code>composer update --minimal-changes</code>: Upgrade only what is strictly necessary to resolve a conflict. * <code>composer update --patch-only</code>: Only take patches (xyz) — ideal for security hotfixes. * <code>composer update --bump</code> (or <code>composer bump</code>): Aligns your <code>composer.json</code> constraints with the installed versions. * <code>composer audit</code> (auto-run on update): Detects known vulnerabilities in your lock.</li></ul></li></ul><h2>🔐 Supply chain &amp; security</h2><ul><li><p>Why everyone is concerned Even a “small” site collects data → potential target (phishing, pivot, etc.).</p></li><li><p>Key best practices</p><ul><li><p>Run <code>composer audit</code> in CI and alert if vulnerabilities appear <em>after</em> deployment. * Add the <code>roave/security-advisories</code> metapackage: prevents installing a vulnerable version. * Use a private Composer repository (Private Packagist / Nexus / Artifactory / Cloudsmith…):</p><ul><li>Mirror artifacts (not just metadata) → protects against deletion or wild retags. * Reliable entry point for your builds (less direct dependency on GitHub). * Never retagged a published version: make a new release. * Sponsor your dependencies (<code>composer fund</code>), the PHP Foundation, etc.: it's your supply chain.</li></ul></li></ul></li></ul><h2>🧭 Semantics &amp; constraints (useful reminders)</h2><ul><li><p>Prefer <code>^</code> (caret) to express “compatible until the next major”:</p><p><code>json { &quot;require&quot;: { &quot;vendor/lib&quot;: &quot;^1.2&quot; } } // [1.2.0, &lt;2.0.0) </code> * Multi-majors (often for PHP):</p><p><code>json { &quot;require&quot;: { &quot;php&quot;: &quot;^8.1 || ^8.2 || ^8.3&quot; } } </code> * Exclude broken versions:</p><p><code>json { &quot;require&quot;: { &quot;vendor/lib&quot;: &quot;^1.2, !=1.3.2, !=1.4.0&quot; } } </code> * Stability: <code>dev</code>, <code>alpha</code>, <code>beta</code>, <code>RC</code>, <code>stable</code> (inferred from tag). Branches = <code>dev-xxx</code>.</p></li></ul><h2>🍴 Forks: temporary vs permanent</h2><ul><li><p>Temporary fork (urgent hotfix)</p><ul><li><p>Reference the VCS repository + alias to make it look like 1.2.3:</p><p><code>json &quot;repositories&quot;: [{ &quot;type&quot;: &quot;vcs&quot;, &quot;url&quot;: &quot;https://github.com/me/lib&quot; }], &quot;require&quot;: { &quot;vendor/lib&quot;: &quot;dev-fix as 1.2.3&quot; } </code> * ⚠️ You won't get upstream updates automatically → monitor and revert upstream as soon as possible.</p></li></ul></li><li><p>Permanent fork</p><ul><li><p>Rename the package (<code>my/lib</code>) and replace the original:</p><p><code>json &quot;replace&quot;: { &quot;vendor/lib&quot;: &quot;self.version&quot; } </code> * Publish your package (e.g. Private Packagist) and remove the VCS source from the project.</p></li></ul></li></ul><h2>🎯 Controlled updates</h2><ul><li><p>Partial:</p><p><code>bash composer update vendor/zebra --with-dependencies composer update vendor/zebra vendor/giraffe --with-all-dependencies </code> * Limit shockwave:</p><ul><li><code>--minimal-changes</code>: Keep current versions whenever possible. * <code>--patch-only</code>: Only take patches. * Block rollback:</li></ul><p><code>bash composer update --bump </code> * Automate:</p><ul><li>Detectors/PRs: Dependabot, Renovate (watch out for gaps); Nils presented Conductor (PHP/Composer targeted tool: executes the update in your CI, understands plugins/scripts, groups PRs better).</li></ul></li></ul><h2>🧩 Monorepos</h2><ul><li><p>Use <code>path</code> repositories to link your local libs (symlink in <code>vendor/</code>):</p><p><code>json &quot;repositories&quot;: [ { &quot;type&quot;: &quot;path&quot;, &quot;url&quot;: &quot;packages/*&quot;, &quot;options&quot;: { &quot;symlink&quot;: true } } ] </code> * Modify a constraint in a mono lib → re-run <code>composer update</code> at the root.</p></li></ul><h2>🔒 The central role of <code>composer.lock</code></h2><ul><li><p>Lock freezes the ENTIRE tree (exact versions + URLs). * Always commit <code>composer.lock</code> (for apps). * Intentional merge conflicts (hash) → reset to <code>main</code>, rerun the exact update command.</p><ul><li>Tip: Paste the <code>composer update …</code> command into the PR commit message.</li></ul></li></ul><h2>🚀 Reliable deployment (pipeline type)</h2><ol><li>CI: <code>composer install --no-dev --prefer-dist --no-interaction --no-progress</code> 2. <code>composer check-platform-reqs</code> (or during image build) 3. Optimized autoload dump: <code>composer dump-autoload -o</code> 4. Build artifact (Docker archive / image) including <code>vendor/</code> 5. Deploy artifact (zero updates in prod) → same code everywhere, no surprises.</li></ol><h2>⚡ Caching that works (CI)</h2><ul><li><p>Cache the Composer cache (<code>~/.composer/cache</code>) and (optional) <code>vendor/</code>:</p><ul><li>Composer cache accumulates (ideal for multi-branch/multi-job). * <code>vendor/</code> bypasses decompression if the state hasn't changed. * In Docker, leverage layers and invalidate on <code>composer.lock</code> change.</li></ul></li></ul><h2>📝 “Dial 2025” checklist</h2><ul><li><p>[ ] Composer 2 everywhere (+ Packagist v2 API). * [ ] <code>composer audit</code> in CI + security alerting outside the update cycle. * [ ] <code>roave/security-advisories</code> to block vulnerable versions. * [ ] Private Composer repo to make artifacts more reliable. * [ ] Frequent updates (Renovate/Dependabot/Conductor), small and regular. * [ ] <code>--minimal-changes</code>, <code>--patch-only</code>, <code>--bump</code> in your routine. * [ ] Commit <code>composer.lock</code> and document update commands. * [ ] Composer cache caching (+ <code>vendor/</code> depending on context). * [ ] Don't retagged; publish a new version. * [ ] Support your dependencies (<code>composer fund</code>).</p></li><li><p>Extending the Caddy web server with your favorite language – <em>Sylvain Combraque</em> Presentation of Caddy’s extension possibilities to integrate custom features directly into the server.</p></li><li><p>Growing the PHP Core — One Test at a Time – <em>Florian Engelhardt</em> A plea to contribute to the language through targeted unit tests. Every test counts to strengthen PHP.</p></li></ul><p>Here is a clear, ready-to-deliver version of Florian's (FR) talk, with a storyline that sticks to what he's saying, synthesized &quot;demo&quot; passages, and memorable punchlines.</p><h1>Become a PHP contributor… by writing tests</h1><p><em>(and a bit of history from 1993 to today)</em></p><h2>👋 Introduction</h2><p>Hi, my name is Florian. I work on the Profiler team at Datadog, where I build a continuous profiler for PHP. I also contribute to open source: PHP core, PHPUnit, GraphQLite… and I co-maintain the parallel extension (multithreading in PHP). I do all this… while being married and the father of 5 children. The bottom line: you can always find a little time to contribute 😉</p><h2>🧒 Personal prehistory</h2><ul><li>1993: first PC (IBM PS/2, 286) + a book “GW-Basic for absolute beginners” → first steps in coding. * 1995: I discover the Internet, HTML/CSS/JS/Perl. We deploy via FTP + F5. * 2000: I join a web agency in Germany. Two teams: JSP and PHP. I am put on the PHP side. I am shown <code>echo 1+1</code> → F5 → 2. I answer: <em>“No one will ever use that.”</em> 😅 Then I am shown MySQL, real code, real projects… and I finally understand what a software engineer does all day.</li></ul><h2>🧭 Why this talk</h2><p>In my 25-year career, PHP has given me everything. I wanted to give back to the community, but without starting by writing C or an RFC. I discovered PHP TestFest (2017 edition): the idea is simple—write tests for PHP. Perfect for learning the codebase and contributing right away.</p><h2>🔧 Build PHP &amp; Run the Test Suite</h2><h3>Compile from source</h3><pre><code class="language-bash">git clone https://github.com/php/php-src.git cd php-src ./buildconf ./configure make -j$(nproc) sapi/cli/php -v # checks: PHP 8.x-dev
</code></pre><h3>Run the tests (in parallel)</h3><pre><code class="language-bash"># From the repo root make test # sequential # or php run-tests.php -j10
</code></pre><ul><li>18k+ tests, pass/skip/fail clearly listed. * Many skips if extensions are not compiled. * Final report with stats and possible fails (to be investigated).</li></ul><h2>🧪 PHPT: the PHP test format</h2><p>A test is a <code>.phpt</code> file in sections:</p><ul><li><code>--TEST--</code> short title (+ <code>--DESCRIPTION--</code> if needed) * <code>--EXTENSIONS--</code> dependencies (e.g. <code>zlib</code>) * <code>--SKIPIF--</code> skip logic (OS, network, etc.) * <code>--FILE--</code> tested PHP code (often <code>var_dump</code>) * <code>--EXPECT--</code> expected output * <code>--CLEAN--</code> housekeeping (isolated from <code>--FILE--</code>)</li></ul><blockquote><p>Tips: each section runs in isolation → no shared variables.</p></blockquote><h2>🧩 Real example: testing <code>zlib_get_coding_type()</code></h2><h3>Context</h3><ul><li><p>PHP can compress the output automatically if <code>zlib.output_compression=On</code> and the client sends <code>Accept-Encoding</code>. * The <code>zlib_get_coding_type()</code> function returns:</p><ul><li><code>false</code> if no compression, * <code>&quot;gzip&quot;</code> / <code>&quot;deflate&quot;</code> depending on the algorithm PHP will use.</li></ul></li></ul><h3>Case ideas to test</h3><ol><li>No <code>Accept-Encoding</code> → <code>false</code> 2. <code>Accept-Encoding: gzip</code> + compression Off → <code>false</code> 3. <code>Accept-Encoding: gzip</code> + compression On → <code>&quot;gzip&quot;</code></li></ol><h3>The pitfalls encountered (and what they learned)</h3><ol><li><p>Headers already sent</p><ul><li><p>If you print something before changing the INI, PHP sends the headers → you can no longer change the compression. * Solution: buffer the output (store in a variable, do not <code>echo</code> too early). 2. Copy-on-write superglobals</p></li><li><p>Changing <code>$_SERVER['HTTP_ACCEPT_ENCODING']</code> to userland does not change the internal value used by the engine. * Solution: Use the <code>--ENV--</code> section of <code>.phpt</code> to inject <code>HTTP_ACCEPT_ENCODING=gzip</code> at the start of the test process. 3. Be careful with the output</p></li><li><p>With compression enabled, the output becomes... gzip binary. * Solution: Capture, change the INI, then emit the expected output clear for the <code>--EXPECT--</code>.</p></li></ul></li></ol><blockquote><p>Result: robust final test, integrated (at the time PHP 7.3), and coverage gained on untested branches.</p></blockquote><h2>🎁 What I learned along the way</h2><ul><li>Superglobals (<code>$_SERVER</code>, <code>$_GET</code>, <code>$_POST</code>…) are copy-on-write → the internal original remains immutable. * <code>ini_set()</code> is not “magic”: after sending the headers, it is sometimes too late to change a behavior that should have been declared in the HTTP response. * There are hidden treasures: while searching the cover, I (re)discovered ZipArchive, etc. * The PHPT format is not reserved for the core: PHPUnit also knows how to execute them — useful for testing a SAPI/CLI or a binary.</li></ul><h2>🚀 Why you should write tests for PHP</h2><ul><li>You stabilize the ecosystem for everyone. * You learn the stepper motor, without writing a single line of C. * You become… a PHP contributor (and that’s cool ✨).</li></ul><h3>Where to start (5-minute checklist)</h3><ol><li>Fork <code>php-src</code>, <code>buildconf &amp;&amp; configure &amp;&amp; make</code>. 2. <code>php run-tests.php -j8</code> for a first run. 3. Open Codecov/coverage → find simple red (switch/return). 4. Write 1 <code>.phpt</code>: <code>--ENV--</code>, <code>--EXTENSIONS--</code>, <code>--FILE--</code>, <code>--EXPECT--</code>. 5. <code>make test TESTS=path/to/your-test.phpt</code>. 6. Small, targeted PR, clear explanations → easier merge.</li></ol><h2>🧑‍💻 Final word</h2><p>We don't do this because it's easy, we do it because we think it's going to be easy... and we learn along the way. Thank you—and if you have any questions, I'm here!</p><ul><li>MongoDB: Ask more from your database – <em>Jérôme Tamarelle</em> Overview of MongoDB's advanced features (aggregations, complex queries) in an API context.</li></ul><h3>🧑‍💻 FrankenPHP in the spotlight</h3><ul><li><p>How Clever Cloud Redesigned Its Way of Deploying PHP Applications with FrankenPHP – <em>Steven Le Roux &amp; David Legrand</em> Feedback on integrating FrankenPHP into a PaaS. Gains in efficiency, simplicity, and performance.</p></li><li><p>FrankenPHP in production, migrating an e-commerce site – <em>Loïc Caillieux</em> Real-life case of migrating a project to FrankenPHP. Performance figures and feedback on stability.</p></li></ul><h3>💡 Other notable talks</h3><ul><li><p>Mercure, SSE, API Platform and an LLM raise a chat(bot) – <em>Mathieu Santostefano</em> Experimentation of a real-time chatbot with Mercure and API Platform, enriched by an LLM.</p></li><li><p>How API Platform 4.2 is Redefining API Development – <em>Antoine Bluchet (Soyuka)</em> Detailed presentation of the new features in 4.2: new filters, DX improvements, better scalability.</p></li></ul><p>Great, here is the written report of Antoine Bluchet's (Soyuka) talk — “API Platform 4.2”.</p><h1>🎉 10 years of API Platform &amp; release of 4.2 (live on stage)</h1><blockquote><p>“The release goes out right after the talk — the Wi-Fi is playing tricks on me.” — Antoine</p></blockquote><h2>🚦 Retro 4.0 → 4.2</h2><ul><li>600 commits, 200,000 lines modified; 300 issues opened, 2/3 of which are closed. * Thanks to Les-Tilleuls.coop for sponsoring Antoine full-time.</li></ul><h2>🧩 Metadata: declare &amp; modify more easily</h2><ul><li>New PHP declaration (in addition to attributes/YAML), ported from Symfony. * Targeted mutators: <code>AsResourceMutator</code> / <code>AsOperationMutator</code> (+ <code>OperationMutator</code> interface) to adjust an operation/resource without any hassle (useful for the <em>Serious Bundle</em>).</li></ul><h2>🔎 Filters, finally decoupled (doc ↔ transformation ↔ validation ↔ SQL)</h2><p>Historically, a filter mixed description, SQL strategy, etc. In 4.2, we separate the responsibilities:</p><ul><li><p>Documentation:</p><ul><li><p><code>JsonSchemaFilterInterface</code> — declares the schema of a parameter (inferred type → automatic coercion/validation on PHP side). * <code>OpenApiParameterFilterInterface</code> — OpenAPI parameters (can override JSON Schema). * Filtering: unchanged storage interfaces (ORM/ODM/ES…).</p></li><li><p>Filters become simple callbacks, without DI, which receive typed parameters.</p></li></ul></li></ul><h3>🧭 Unified HTTP parameters</h3><ul><li>New <code>Parameter</code> (query) &amp; <code>HeaderParameter</code> (header) attributes with advanced options (type, array, formats, coercion, etc.). * Parameters are declared on the operation, independent of entity properties. * Free-text query <code>q=</code> (Hydra style) out-of-the-box. * Composite filters possible, closing very old historical tickets.</li></ul><h3>🔗 “Smart” path parameters</h3><ul><li><code>Link extends Parameter</code> + dedicated provider to resolve a linked resource (e.g. <code>company</code> injected as a ready-to-use entity in the provider).</li></ul><h2>📜 OpenAPI &amp; JSON Schema: lighter, cleaner</h2><ul><li>Schema pooling: a base schema + enrichments (JSON-LD, JSON API, …) by $ref → −30% size on large specs, less I/O. * ⚠️ If you were testing the exact form of the schemas, expect diffs (functional validation remains the same). * New, stricter/updated validator; many inconsistencies fixed.</li></ul><h2>⚡ Performance: FrankenPHP in worker mode, figures to support it</h2><ul><li>NGINX/PHP-FPM vs FrankenPHP Bench (optimized “sweet spot” config). * Without worker: equivalent. With worker: +RPS, latency ÷2 on Sylius page. * Key message: enable worker mode. (And go tease those who haven't done it 😉)</li></ul><h2>🧱 State Options: links and sub-resources… painlessly</h2><ul><li><p>For specific sub-resources, a dedicated callback gives a clear <code>WHERE</code> and avoids large automatic graphs. * Entity-class magic modernized with Symfony ObjectMapper:</p><ul><li>Your shape API no longer has to match the Doctrine entity. * We annotate with <code>#[Map]</code> to describe correspondences (e.g. <code>firstName</code>+<code>lastName</code> → <code>username</code>). * Clean and maintainable bidirectional mapping.</li></ul></li></ul><h3>🛒 Real case (Sylius + JSON-LD / schema.org)</h3><ul><li>Expose a schema.org compliant product sheet in JSON-LD while the Sylius entity does not match. * Provider that reads Sylius → ObjectMapper that remaps → Serializer that emits the JSON-LD. * Return from the API Platform profiler (content-negotiation, provider, serializer, etc.) to see where the time goes (often serialization).</li></ul><h2>🧵 Built-in JSON Streamer: Serialize large payloads faster</h2><ul><li><p>Integration of the Symfony JSON Streamer (+ TypeInfo) for JSON and JSON-LD. * Principle: pre-calculated schema, character-by-character streaming. * Measured gains: up to +32% RPS in Antoine's tests (the bigger the object, the more it gains). * Activation: tool option <code>json_stream: true</code>.</p><ul><li>⚠️ Requires public properties (otherwise, stick with the classic Serializer). * For further information: dedicated talk by Mathias Arlaud.</li></ul></li></ul><h2>🧡 Laravel: Functional coverage in a boom</h2><ul><li>Since the intro last year: 124 PRs &amp; 100 issues addressed. * 80–90% of API Platform features now operational on the Laravel side (including HTTP cache). * Thanks to the Laravel top contributors. And deployment on Laravel Cloud presented by Joe Dixon.</li></ul><h2>🧪 Availability &amp; Compatibility</h2><ul><li>4.2: Released right after the talk (beta exists). * Main breaking change: JSON Schema format (not substance). * OpenAPI defaults adjusted (low risk of impact). * Parameters: No longer experimental — adopt them.</li></ul><h2>🛣️ Roadmap to 5.0</h2><ul><li>Deprecate <code>#[ApiFilter]</code> in favor of the settings system (assisted migration: script &amp; compat kept for a long time). * Extend the JSON Streamer to other formats; feedback &amp; tests welcome. * Continue maturing ObjectMapper (Symfony) via concrete uses in the ecosystem.</li></ul><h2>✋ Key points (TL;DR version)</h2><ul><li>Unified parameters (typed, documented) + decoupled filters ⇒ DX and precision. * OpenAPI lighter and stricter. * FrankenPHP (worker) ⇒ real performance boost. * ObjectMapper ⇒ Clean API even if your entities are not. * JSON Streamer ⇒ faster big payloads. * Laravel: that's it, we're (almost) there feature-by-feature.</li></ul><p>Do you want me to generate a 4.1 → 4.2 migration checklist (parameters, schemas, performance) + examples of annotations ready to copy and paste?</p><ul><li>How Laravel Cloud Uses FrankenPHP in Production – <em>Florian Beer</em> Focus on the synergy between Laravel Cloud and FrankenPHP.</li></ul><h2>🚀 Context</h2><p>Florian Beer (Laravel Cloud infrastructure team) explained how the zero-ops platform launched in February allows you to deploy a Laravel app &quot;in one minute&quot; (GitHub/GitLab/Bitbucket connection → <em>Deploy</em> → public URL). The goal: no client-side infrastructure management (servers, containers, scaling, network... everything is managed).</p><h2>⚙️ Octane, the long-lasting execution</h2><ul><li>Without Octane: Laravel runs on PHP-FPM, the application boots for each request. * With Octane: the app boots once and stays in memory; requests are served by a long-running worker. * Octane supports multiple servers; Laravel Cloud has chosen FrankenPHP.</li></ul><h2>🧩 Why FrankenPHP?</h2><p>FrankenPHP (based on Caddy) provides:</p><ul><li>HTTP/2 &amp; HTTP/3, Early Hints, Auto TLS, * a powerful worker mode, * easy integration into the Laravel/Octane ecosystem.</li></ul><blockquote><p>In practice on Laravel Cloud, activate Octane = switch to FrankenPHP (and return to PHP-FPM if necessary).</p></blockquote><h2>🎬 Live demo (step by step)</h2><ol><li>Create an app via template on Laravel Cloud (Frankfurt region). 2. Initial deployment → app accessible in PHP-FPM. 3. <code>composer require laravel/octane</code>, add a &quot;runtime&quot; route to expose runtime info. 4. Push → auto-deploy (build container, publish). 5. Flip the switch: enable Octane in the interface → redeploy. 6. The &quot;runtime&quot; route now shows FrankenPHP as runtime.</li></ol><p>💡 Warning: In worker mode, monitor for memory leaks on the application code side (customer responsibility). The platform facilitates activation but does not &quot;garbage-collect&quot; your business logic.</p><h2>🏗️ Under the hood of Laravel Cloud</h2><ul><li><p>The platform maintains two families of Docker images:</p><ul><li>PHP-FPM (classic), * FrankenPHP (Octane). * The pipeline takes your repo, builds the image, pushes it, and attaches the service to the public network.</li></ul></li></ul><h2>🤝 Performance &amp; collaboration</h2><ul><li>Direct collaboration with Kévin Dunglas to optimize FrankenPHP on a wide variety of workloads (from side-projects to high-traffic SaaS). * Result: significant performance gains already observed on the client side.</li></ul><h2>✅ Issues &amp; best practices</h2><ul><li><p>When to switch to Octane/FrankenPHP?</p><ul><li><p>Intensive I/O, critical latency, hot endpoints, busy web/API. * Points of attention:</p></li><li><p>Global state &amp; singletons (well re-initialized between requests), * Connections (DB, cache) managed properly in the worker lifecycle, * Observability (metrics, memory usage per worker).</p></li></ul></li></ul><h2>🧭 Key message</h2><blockquote><p>On Laravel Cloud, Octane + FrankenPHP is activated with one click. &gt; You retain the simplicity of zero-ops, while taking advantage of the modern runtime and worker mode for performance.</p></blockquote><ul><li>Help! My Tech Skills Have an Expiration Date – <em>Helvira Goma</em> Reflecting on the rapid obsolescence of skills and how to stay relevant in a constantly changing industry.</li></ul><h2>🎤 Day 2 – September 19</h2><h3>🔑 Keynotes</h3><ul><li>Nicolas Grekas: Symfony's status, new features, and roadmap. * Fabien Potencier: Symfony's long-term vision and a focus on AI-related components.</li></ul><p>Here's a ready-to-deliver version (with slide titles) of Fabien Potencier's talk on &quot;LLMs, Agents, and the Future of APIs.&quot; I've kept the pragmatic tone and concrete examples.</p><p>#1) Why this talk?</p><ul><li>The world of AI is moving so fast that what I say today may be obsolete tomorrow. * Goal: Understand how LLMs and agents are changing the way we design APIs.</li></ul><blockquote><p>Who here uses an LLM to code (almost) every day? Who has never called an API? Try it 😉</p></blockquote><p>#2) What is an “agent”?</p><ul><li>Definition (Anthropic, summarized): a model that uses tools in a loop. * Mental schema: <em>Prompt → chooses a tool → observes → reiterates → produces a result</em>. * Possible tools: web browser, SDK/API, local executable, home-made function… * Important: both “human” and “machine”: plans, has memory, takes initiatives, but remains a program.</li></ul><p>#3) 30 years of interfaces: from website to agent</p><ul><li><p>90s: sites for humans (pure HTML, then CSS/JS). * CLI: for devs/ops. * APIs: machine-to-machine (mashups!), internal or public, with expectations of completeness and determinism. * New: agents interact with everything:</p><ul><li>Websites (scraping / browsing tool), * CLI (via MCP servers), * APIs (via SDKs or direct HTTP).</li></ul></li></ul><p>#4) Current APIs: Perfect for programs, not agents</p><ul><li>Strict inputs/outputs (OpenAPI/JSON), errors via HTTP status (400, 422, 429, etc.). * For deterministic apps, this is perfect: in case of an error, a human corrects the code. * But an agent must self-recover: it needs courses of action, not just “400 Bad Request.”</li></ul><p>#5) When an agent bumps into your mistakes</p><ul><li>400 / 422 / 429: the agent sees the code… and guesses (sometimes wrongly): missing field? bad format? try again later? * Bad loop: it tries, fails, googles, rereads the doc, tries again… → slow, expensive, non-deterministic. * Worse: many SDKs (e.g. in Python) only return the default status code → the detailed error body is lost.</li></ul><p>#6) Making Mistakes… Action Tips</p><ul><li><p>In the response (not just the code):</p><ul><li>problem title + actionable detail, * link to a specific page (not the root doc), * concrete proposal: “the <code>date</code> field must be in <code>YYYY-MM-DD</code> format”, “<code>quantity</code> ≤ 100”, “this endpoint is deprecated, use <code>/orgs/{id}/projects</code>”. * Benefits: fewer iterations, fewer tokens, less cost, fewer hallucinations.</li></ul></li></ul><blockquote><p>Symfony has long supported error structuring (JSON issue): take advantage of this to standardize your error payloads.</p></blockquote><p>#7) Consistency &gt; intelligence</p><ul><li><p>LLMs love predictability: pick a style and stick to it.</p><ul><li><code>user_id</code> everywhere (not <code>userId</code> here and <code>author_id</code> elsewhere). * Fields, URL names, formats: consistency. * Otherwise the agent “guesses”… and makes a mistake.</li></ul></li></ul><p>#8) “AX” Documentation (eXperience Agent)</p><ul><li><p>Unified, up-to-date, centralized: avoid outdated pages and fake examples (LLMs copy them). * Tracks:</p><ul><li>LLMS.txt (inventory for LLMs), * each page viewable in Markdown (LLMs read MD very well), * path guides (e.g. “buy a product”: auth → cart → address → payment), * document possible errors per endpoint, how to resolve them, and provide correct examples.</li></ul></li></ul><blockquote><p>A bad example in context can “contaminate” an LLM’s answers for hours.</p></blockquote><p>#9) Minimize back and forth with the agent</p><ul><li>One API call: 10–100 ms; one LLM call: seconds. * Fewer rounds = faster, cheaper, more stable. * Idea: Expose a few high-level task-oriented endpoints (“checkout”, “full export”, “provision a project”) in addition to your low-level endpoints, to avoid 5 calls when 1 is enough.</li></ul><p>#10) Testing… the indeterministic</p><ul><li><p>Agents are not deterministic. However, tests are needed:</p><ul><li>low temperature, retry limits, more constrained prompts, * metrics (success rate, latency, costs) and dashboards, * accept the “grey” (good enough scenarios).</li></ul></li></ul><p>#11) Tokens: where the bill stings</p><ul><li><p>Billing is per token (not per character). * Surprising impacts:</p><ul><li>English short words = 1 token; French/accents/Unicode = often several; * Random UUIDs &amp; IDs → tokenized very expensive; * <code>category_id</code> can be 1 token depending on the tokenizer, <code>DoneAt</code> vs <code>CompletedAt</code> does not always make a difference. * Verbose JSON is expensive; structured Markdown is often more “readable” for the model and less tokenized. * Long context ≠ precision: the larger the context, the more the agent gets confused. Segment what you expose to agents (MCP, sub-APIs).</li></ul></li></ul><p>#12) Credentials &amp; Security: Don't Let the Agent Play with Fire</p><ul><li>Never put secrets in a prompt. * Prefer a tooled proxy (e.g. MCP server) that holds the keys, makes the calls, and restricts permissions. * Give the agent scoped tokens (read-only, minimal scope). * Case 429 (rate limit): tell what to do (“Retry-After: 3”, backoff recommended, quota per minute, etc.).</li></ul><p>#13) Some “recipes” that you can apply tomorrow</p><ul><li>Actionable errors + specific links; standardize status/body. * Deprecation: report in the response AND the doc; propose the alternative. * Macro endpoints (tasks) in addition to micro ones. * Consistency of names and formats. * Central doc in Markdown, indexed (LLMS.txt). * Limit JSON verbosity, avoid gigantic IDs; paginate. * Integrate an MCP server to properly expose your tools/SDKs to agents.</li></ul><p>#14) From DX/UX to AX (Agent eXperience)</p><p>We've made great progress in DX and UX. The next step is AX: designing understandable, actionable, and predictable APIs for customers… who reason.</p><blockquote><p>What you do for agents also benefits humans: better errors, better documentation, less friction.</p></blockquote><h1>Conclusion</h1><ul><li>Agents are already using your APIs. * Help them: fewer back-and-forths, errors that guide, consistency, usable documentation, controlled security. * The future of APIs is not just machine↔machine: it's machine-that-reasons ↔ well-designed service.</li></ul><p>Thank you 🙏 — questions welcome!</p><h3>🏗️ Architecture and REX</h3><ul><li><p>2025, an API Platform Odyssey – <em>James Seconde</em> An overview of the past and future evolutions of API Platform.</p></li><li><p>Deploying API Platform on Laravel Cloud – <em>Joe Dixon</em> Concrete example of integrating and deploying API Platform in a Laravel Cloud platform.</p></li><li><p>Headless &amp; Scalable: Designing a Decoupled Application with API Platform and Vue.js – <em>Nathan de Pachtere</em> Demonstration of a headless project with API Platform as backend and Vue.js as frontend.</p></li><li><p>A seamless multi-tenant API with API Platform, Symfony and PostgreSQL – <em>Mehdi Zaidi</em> Technical strategies for managing multiple clients on a single API instance, leveraging PostgreSQL.</p></li></ul><h3>🛠️ Tools and best practices</h3><ul><li><p>Make your front-end devs happy with RFC 7807 – <em>Clement Herreman</em> How to normalize API errors with RFC 7807 for better front-end DX.</p></li><li><p>Symfony and Dependency Injection: From Past to Future – <em>Imen Ezzine</em> A history and projection on the evolution of dependency injection in Symfony.</p></li><li><p>Type System and Subtyping in PHP – <em>Gina Peter Banyard</em> Theoretical and practical presentation of the type system in PHP, with an academic perspective.</p></li><li><p>PIE: The Next Big Thing – <em>Alexandre Daubois</em> A look at a new technological proposition that could change the way we work with PHP.</p></li></ul><h1>Pi: the tool that reconciles PHP and its extensions</h1><p><em>Towards a “composer for extensions”, supported by the PHP Foundation</em></p><h2>TL;DR</h2><p>Install, update, and uninstall PHP extensions painlessly, with dependency management, signatures, PHP version detection, composer.json integration, and more. Pi delivers exactly that. Designed and funded by the PHP Foundation, Pi leverages the Packagist ecosystem for metadata, automates php.ini editing, supports private GitHub, Windows, Linux, and macOS — and aims to replace legacy PECL/pickle usage.</p><h2>Why a new tool for extensions?</h2><p>In our projects, installing a PHP library is trivial (<code>composer require …</code>). On the other hand, installing an extension (Redis, MongoDB, Xdebug, PCOV, etc.) often rhymes with:</p><ul><li>system dependencies, <code>./configure &amp;&amp; make &amp;&amp; make install</code>, * variations by OS/ABI/PHP versions, * manual editing of INI files, * fragile consistency between CI/dev/prod environments.</li></ul><p>Initiatives have attempted to smooth out this friction (PECL/pickle, Docker PHP Extension Installer), but with limitations: slow and difficult to maintain site, lack of generalized signatures, imperfect detection of PHP compatibilities, tight coupling to Docker, etc.</p><p>Pi was born from this observation: to bring the experience of a Composer to extensions.</p><h2>Pi in two sentences</h2><ul><li>What it is: An extension manager that automatically downloads, builds (or fetches binaries when relevant), installs, and activates your PHP extensions. * What it changes: You treat your extensions as project dependencies (Packagist metadata, version constraints, composer.json integration), but with the intelligence needed for the extension world (C/Rust/Go, compilation, DLL/SO, ABI, etc.).</li></ul><h2>Key Features</h2><ul><li><p>Simplified installation</p><pre><code class="language-bash">
# Download local cached sources pi download redis

# Build (configure/compile) according to your platform pi build redis

# All-in-one: download + build + installation + activation pi install redis ```

</code></pre></li><li><p>Automatic update of <code>php.ini</code> No need to manually add <code>extension=…</code>: Pi activates the extension in the correct configuration.</p></li><li><p>Smart Compatibility (PHP/OS/arch) Extension authors can restrict OS compatibility and declare PHP min/max bounds; Pi cleanly blocks anything that doesn't match.</p></li><li><p>Signatures and Verifications Pi knows how to consume signed artifacts (e.g. GitHub Releases) and verify integrity before installation.</p></li><li><p>Private &amp; monorepo-friendly Add repositories like Composer: VCS, local path, Private Packagist, etc. — ideal for private extensions.</p><p><code>bash pi repo add my-ext vcs https://github.com/acme/php-ext-foo.git </code></p></li><li><p>Reading <code>composer.json</code> A simple <code>pi install</code> in your project allows Pi to scan your <code>composer.json</code> (e.g. <code>require: { &quot;ext-redis&quot;: &quot;*&quot; }</code>) and install any missing extensions. 🪄</p></li><li><p>Clean uninstall</p><p><code>bash pi uninstall xdebug </code></p></li><li><p>Multi-PHP support Install for a specific PHP binary (useful in multi-die CI):</p><p><code>bash pi install pcov --with-php-path=/usr/bin/php8.3 </code></p></li><li><p>Windows first-class On Windows, Pi fetches precompiled DLLs when available; on Linux/macOS, Pi compiles by default (classic and reliable).</p></li><li><p>Symfony CLI integration Regular users can control Pi via:</p><p><code>bash symfony pi install xdebug </code></p></li></ul><h2>Where are the extension packages?</h2><p>Pi relies on Packagist to index metadata (name, version, PHP/OS constraints, sources, signatures, etc.). Pi-compatible extensions are published under a dedicated vendor (e.g., <code>packagist.org/extensions/...</code>) or via your own repositories. 👉 Consequence: same reflexes as Composer (semantic versioning, ranges, private repositories).</p><h2>Typical workflow (developer &amp; CI)</h2><ol><li><p>Declare your requirements (in the README and/or via <code>composer.json</code>: <code>ext-…</code>). 2. Developer</p><p><code>bash pi install # installs all extensions requested by the project php -m | grep redis </code> 3. CI</p><ul><li>Cache Pi cache and build artifacts for speed. * OS × PHP matrix: Pi handles build and activation differences. * Avoid pipeline-specific <code>apt-get</code>/<code>brew</code>: Pi centralizes.</li></ul></li></ol><h2>Quick Comparisons</h2><p>| Need | PECL/pickle | Docker Ext Installer | Pi | | ------------------------------- | ----------- | -------------------- | -------------------------------- | | Local installation without Docker | Medium | No | Yes | | PHP/OS version detection | Partial | N/A (Docker) | Yes (metadata) | | Signatures &amp; verification | Heterogeneous | N/A | Yes | | Auto-activation (<code>php.ini</code>) | No | N/A | Yes | | Private repositories | Complicated | No | Yes (VCS, Private Packagist) | | Reading <code>composer.json</code> | No | No | Yes | | Windows | Variable | No | Yes (DLL) |</p><h2>Express FAQ</h2><p>Is there a <code>.lock</code> per project like Composer? No. An extension is installed at the system/PHP binary level. Pi tracks what it handles (<code>pi show</code>) and respects the target PHP version (<code>--with-php-path</code>). Reproducibility is done at the CI level (matrix/os/versions) and via your constraints.</p><p>Can I use Pi with private GitHub sources? Yes: Pi reads <code>GH_TOKEN</code> and authenticates private artifact uploads.</p><p>Precompiled binaries on Linux/macOS? By default no (local compilation = ABI robustness), but yes on Windows (DLL).</p><p>Is Pi officially replacing PECL/Pickle? The adoption process is going through RFC/voting on the PHP side; the direction is toward recommending Pi as the preferred path. Either way, you can use it right now.</p><h2>Best practices to adopt today</h2><ul><li>Declare your extensions in <code>composer.json</code> (<code>&quot;ext-redis&quot;: &quot;*&quot;</code>), and document the supported PHP versions. * Standardize your CI pipelines around <code>pi install</code> (rather than OS-specific scripts). * Publish full extension-side metadata: PHP/OS constraints, signatures, build instructions. * Cache the Pi cache in CI and fix extension versions in production (via stable tags).</li></ul><h2>Conclusion</h2><p>Pi finally brings to PHP extensions the ergonomics and reliability that Composer offered to libraries: a unified, reproducible, scriptable, multi-platform workflow — and tailored for modern realities (monorepos, private, CI, Windows).</p><p>If you've ever said &quot;no&quot; to an extension because it seemed risky or time-consuming to install... try again with Pi. You might even get a taste for it. 🚀</p><h3>Appendices – Command Reminder</h3><pre><code class="language-bash"># Inventory of extensions managed by Pi pi show

# Add a private extension repository pi repo add my-ext vcs https://github.com/acme/php-ext-foo.git

# Download the sources pi download xdebug

# Build according to current OS/PHP version pi build xdebug

# Install and activate pi install xdebug pi install pcov --with-php-path=/usr/bin/php8.3

# Uninstall pi uninstall xdebug
</code></pre><h3>🌍 Society</h3><ul><li>Where Have the Women in Tech History Gone? 2.0 – <em>Laura Durieux</em> Inspiring conference highlighting the place of women in history and the importance of inclusion in tech.</li></ul><h3>🎉 Closing</h3><p>A unifying speech concluded the conference, highlighting the importance of community and setting a date for the 2026 edition.</p><h2>📌 Conclusion</h2><p>This 2025 edition was marked by:</p><ul><li>The omnipresence of FrankenPHP, present in the majority of REX. * The rapid evolution of API Platform 4.2, focused on automation, performance and real-time. * The emphasis on best practices: Composer, API filters, error handling, types. * A community that continues to innovate, while addressing human and societal issues.</li></ul><p>A must-attend event for any developer who wants to stay at the forefront of PHP and Symfony technologies.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/api-platform-conference-2025-a-look-back-at-two-intense-days-focused-on-the-symfony-and-php-ecosystem</link><guid>https://blog.darkwood.com/article/api-platform-conference-2025-a-look-back-at-two-intense-days-focused-on-the-symfony-and-php-ecosystem</guid><enclosure url="http://darkwood.com/media/articles/68ceba3538fa3911828222.png" /></item><item><title>🎙️HttpChunk with Flow</title><pubDate>Mon, 22 Sep 2025 05:17:31 +0000</pubDate><description><![CDATA[
Processing HTTP responses in chunks is a recurring challenge:

Multiple requests must be run in parallel. * Some fail (404s, timeouts) and require retries. * Each user returns additional data (todos, posts), resulting in fan-out requests. * This quickly ad...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68d0dbffb588d235213660.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/wCOBEkqclEQ?si=N0T5HwtWRI41L0p4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Processing HTTP responses in chunks is a recurring challenge:</p><ul><li>Multiple requests must be run in parallel. * Some fail (404s, timeouts) and require retries. * Each user returns additional data (todos, posts), resulting in fan-out requests. * This quickly adds up to callback hell, manual state management, and difficult testing.</li></ul><p>Problematic :</p><blockquote><p><em>HTTP chunk processing is complex when it should be fluid.</em></p></blockquote><h3>The problem</h3><p>In PHP, handling asynchronous HTTP streams has often been addressed in an imperative manner:</p><ul><li>Nested callbacks. * Shared state variables. * Difficulty testing and maintaining.</li></ul><p>These approaches make the code difficult to read, fragile and expensive to evolve.</p><h3>The solution with Flow</h3><p>The Flow Framework provides a functional and elegant response to this complexity.</p><ul><li>Jobs: Pure functions that transform data. * Ips: Immutable objects that carry information between jobs. * Drivers: Amp, React, Swoole, or Fiber — abstracted behind Flow. * Y-Flow: Y-Combinator integration to handle recursion without explicit loops.</li></ul><p>The result: a clear, composable, and testable pipeline that naturally orchestrates asynchronous flows.</p><h3>The demo: <code>httpchunkflow.php</code></h3><p>The concrete example:</p><pre><code class="language-bash">php examples/httpchunkflow.php
</code></pre><p>Procedure:</p><ol><li>Three initial queries (<code>/users</code>, <code>/users/404</code>, <code>/todos</code>). 2. Error handling: a 404 is automatically retried to <code>/users/1</code>. 3. Y-Combinator: each user automatically triggers additional queries (<code>/todos</code>, <code>/posts</code>). 4. Concurrent execution: queries run in parallel. 5. Final merge: consolidation of data into a structured result.</li></ol><p>Excerpt from logs:</p><pre><code>*. #1 GET /users ... started *. #2 GET /users/404 ... started *. #3 GET /todos ... started .* #2 404 -&gt; retry /users/1 ..* #1 chunks: parsing via Y ...* #101 QUEUED /users/1/todos ...* #1101 QUEUED /users/1/posts .* #101 200 in 18ms .* #1101 200 in 16ms ....* merging data .....* finalizing results User #1: Leanne Graham (Sincere@april.biz) - Todos: 20 items - Posts: 10 items DONE driver=Flow\Driver\AmpDriver duration=7.99s users=200 retry=1 errors=0
</code></pre><h3>The benefits</h3><ul><li>✅ Readability: No more callback hell. * ✅ Purity: Each job is a testable function in isolation. * ✅ Immutability: Clear and predictable data flows. * ✅ Elegant recursion: Y-Combinator instead of imperative loops. * ✅ Async by design: Flow orchestrates concurrency naturally.</li></ul><h3>Conclusion</h3><p>With Flow and Y-Combinator, chunked HTTP processing goes from a mandatory nightmare to a smooth and functional solution. The result is code that:</p><ul><li>more readable, * more testable, * more maintainable.</li></ul><h3>Resources</h3><ul><li>🔗 <a href="https://github.com/darkwood-com/flow">Flow Framework – GitHub</a> * 🔗 <a href="https://jsonplaceholder.typicode.com">Testing API – JSONPlaceholder</a></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/httpchunk-with-flow</link><guid>https://blog.darkwood.com/article/httpchunk-with-flow</guid><enclosure url="http://darkwood.com/media/articles/68d0dbffb588d235213660.png" /></item><item><title>🚀 Tech watch week 39</title><pubDate>Fri, 26 Sep 2025 16:46:12 +0000</pubDate><description><![CDATA[
This week, I&#039;m sharing a selection of interesting resources about PHP, Symfony, Git, and the open-source ecosystem. Here are the highlights 👇
🛰️ Building a mini-CDN with Symfony and FrankenPHP
A detailed article explains how to set up a mini-CDN from scratc...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68d6c3c182895879462150.jpg" /></p><div class="ratio ratio-16x9"><iframe 
  width="360" 
  height="640" 
  src="https://www.youtube.com/embed/wZ6q8a7nHXU" 
  title="YouTube Short" 
  frameborder="0" 
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" 
  allowfullscreen></iframe></div><p>This week, I'm sharing a selection of interesting resources about PHP, Symfony, Git, and the open-source ecosystem. Here are the highlights 👇</p><h2>🛰️ Building a mini-CDN with Symfony and FrankenPHP</h2><p>A detailed article explains how to set up a <strong>mini-CDN from scratch</strong> with <strong>Symfony 7</strong> and <strong>FrankenPHP</strong>. This type of implementation illustrates the power of modern PHP in system uses usually reserved for other stacks. 👉 <a href="https://www.jschristophe.fr/comment-construire-un-mini-cdn-de-zero-avec-symfony-7-et-frankenphp/">Read the article</a></p><h2>📦 Analyze Composer dependencies</h2><p>The <strong>Composer Dependency Analyser</strong> project allows you to assess the consistency and cleanliness of your dependencies. A useful tool for identifying unused packages or checking whether your dependencies are being properly exploited. 👉 <a href="https://github.com/shipmonk-rnd/composer-dependency-analyser">Discover the tool</a></p><h2>🐘 A new Sylius elephant with Mr. Biz</h2><p>The Sylius community is growing with a <strong>customized “Monsieur Biz” elephpant</strong>. A great way to strengthen the visual and community identity around the PHP e-commerce ecosystem. 👉 <a href="https://sylius.com/blog/sylius-elephpant-monsieur-biz/">See the announcement</a></p><h2>⚔️ JJ – When Google reinvents Git</h2><p>The <strong>Jujutsu (JJ)</strong> project is rethinking the Git experience with a simpler, more modern, and intuitive approach. Initiated by Google, it offers an alternative to traditional workflows for complex repositories. 👉 <a href="https://github.com/jj-vcs/jj">See the Git Hub repository</a></p><h2>🧠 PHP-ORT – Optimization and AI with PHP</h2><p>The <strong>PHP-ORT</strong> (Optimized Runtime Toolkit) project paves the way for new experiments to optimize code with AI-inspired methods. Combined with thoughts on PHP and artificial intelligence, this shows a future where PHP goes beyond the web. 👉 <a href="https://krakjoe.github.io/ort/">PHP-ORT Documentation</a></p><h2>🌐 Upsun – Git instead of PostgreSQL?</h2><p>Upsun proposes a radical idea: replacing PostgreSQL with <strong>Git as the data backend</strong> for certain projects. A unique approach that challenges the way we manage versioning and persistence in modern systems. 👉 <a href="https://devcenter.upsun.com/posts/why-you-should-replace-postgresql-with-git-for-your-next-project/">Read the article</a></p><h2>⚡ Fibers in PHP 8.4</h2><p><strong>Fibers</strong> will continue to evolve with PHP 8.4, making asynchronous more accessible natively in the language. This is another step towards concurrent and efficient PHP applications, without heavy external frameworks. 👉 <a href="https://medium.com/@mathewsfrj/fibers-in-php-8-4-the-future-of-asynchronous-php-28b1a34e90df">Read the article</a></p><p>✅ That's it for this week! Innovations in PHP, Git, and infrastructure tools that open up new perspectives.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/tech-watch-week-39</link><guid>https://blog.darkwood.com/article/tech-watch-week-39</guid><enclosure url="http://darkwood.com/media/articles/68d6c3c182895879462150.jpg" /></item><item><title>🎨 Recursive pipe programming</title><pubDate>Mon, 29 Sep 2025 06:40:24 +0000</pubDate><description><![CDATA[
In programming, we often start by writing imperative loops. Simple, effective... but quickly limited. Let&#039;s take a concrete example: a for loop that displays the values of i from 1 to 3.
for ($i = 1; $i &amp;lt;= 3; $i++) { echo $i . PHP_EOL; }

🔁 The 2D graph...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68da29d8bedae792268968.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/4lhEnNtVcfs?si=qx0t8hbltNo1Wn9d" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>In programming, we often start by writing imperative loops. Simple, effective... but quickly limited. Let's take a concrete example: a <code>for</code> loop that displays the values of <code>i</code> from 1 to 3.</p><pre><code class="language-php">for ($i = 1; $i &lt;= 3; $i++) { echo $i . PHP_EOL; }
</code></pre><h2>🔁 The 2D graph representation</h2><p>We can represent this <code>for</code> in the form of a graph:</p><ul><li>Initialize <code>i = 1</code> * Test for condition <code>i &lt;= 3 ?</code> * Execute the loop body (<code>print i</code>) * Increment <code>i = i + 1</code> * Return to the condition while it is true * Exit when the condition becomes false</li></ul><p>Visually, this results in a cycle with multiple nodes and arrows. This type of graph works, but it has a major problem: the larger the program gets, the more illegible the graph becomes. We end up with dozens of nodes, arrows in all directions... and reading becomes a real headache.</p><h2>📏 The linear version: a functional pipe</h2><p>Instead of thinking in terms of a 2D graph, we can reduce the loop to a linear transformation. We go from an initial state (<code>i = 1</code>), we apply a function that handles the recursion, and we arrive at the output (<code>Exit</code>). Everything is aligned vertically like a data pipeline.</p><p>Schematically:</p><pre><code>i = 1 ↓ Y (recursion) ↓ Exit
</code></pre><p>Here, Y Combinator plays the key role: it allows recursion to be expressed in a functional language without needing to explicitly name the function. Recursion becomes a single node in the pipeline, instead of a tangle of arrows in a graph.</p><h2>🧩 Example in PHP with Y Combinator</h2><pre><code class="language-php">// Y Combinator Definition $Y = fn($F) =&gt; (function ($x) use ($F) { return $F(function (...$args) use ($x, $F) { return $x($x)(...$args); }); })(fn($x) =&gt; $F(function (...$args) use ($x, $F) { return $x($x)(...$args); }));

// for loop transformed into a recursive pipe $step = function ($state) { ['i'=&gt;$i,'max'=&gt;$max] = $state; if ($i &gt; $max) return [$state, true]; echo $i . PHP_EOL; return [['i'=&gt;$i+1,'max'=&gt;$max], false]; };

$recurse = $Y(function ($self) { return function ($state, $step) use ($self) { [$next, $done] = $step($state); return $done ? $next : $self($next, $step); }; });

$init = ['i'=&gt;1,'max'=&gt;3]; $recurse($init, $step);
</code></pre><p>Exit :</p><pre><code>1 2 3
</code></pre><h2>🎯 Why is this interesting?</h2><ul><li>Readability: A linear pipeline is much easier to understand than a 2D graph. * Modularity: Each step is a pure function that can be tested and reused. * Power: Y Combinator allows you to express recursion without relying on imperatives. * Elegance: The structure is clear, from top to bottom, like a data flow.</li></ul><h2>🔮 Conclusion</h2><p>Node graphs are useful for quick cases, but they quickly become <em>visual spaghetti code</em>. By taking a functional approach with pipes and combinators, we gain in readability, reusability, and expressive power.</p><p>👉 Stop drawing your loops as 2D graphs. Express them as functional pipes. It's more concise, clearer, and opens the door to much richer abstractions.</p><p>✨ If you want to go further:</p><ul><li><a href="https://flow.darkwood.com/docs/getting-started/ressources/">Flow documentation</a></li></ul><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/recursive-pipe-programming</link><guid>https://blog.darkwood.com/article/recursive-pipe-programming</guid><enclosure url="http://darkwood.com/media/articles/68da29d8bedae792268968.png" /></item><item><title>🚀 Uniflow 1.1.18</title><pubDate>Mon, 06 Oct 2025 09:22:08 +0000</pubDate><description><![CDATA[✨ Darkwood Update: Uniflow 1.1.18 &amp;amp; Darkwood prototypes integrated on uniflow.io
🧩 Uniflow 1.1.18 – The new HtmlFlow component
Uniflow version 1.1.18 introduces a new key component: HtmlFlow. It now allows you to directly display HTML content stored in...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68e38aebd1638168196805.png" /></p><p>✨ Darkwood Update: Uniflow 1.1.18 &amp; Darkwood prototypes integrated on uniflow.io</p><h2>🧩 Uniflow 1.1.18 – The new <code>HtmlFlow</code> component</h2><p><a href="https://uniflow.io">Uniflow</a> version <strong>1.1.18</strong> introduces a new key component: <strong><code>HtmlFlow</code></strong>. It now allows you to <strong>directly display HTML content</strong> stored in a context variable — whether it's a text fragment, a visual rendering, or even an <strong>iframe</strong> dynamically generated by another flow.</p><p>This component, developed last week, marks an important step in Uniflow's <strong>Flow Based Programming</strong> philosophy: making flows <strong>autonomous, visual and interactive</strong>, without depending on an external interface.</p><h3>⚙️ Minimal example</h3><pre><code class="language-js">// JavascriptFlow const iframe = ` &lt;iframe frameborder=&quot;0&quot;
  src=&quot;https://itch.io/embed-upload/15043973?color=333333&quot;
  allowfullscreen
  width=&quot;640&quot;
  height=&quot;380&quot;&gt; &lt;a href=&quot;https://darkwoodcom.itch.io/darkwaar1&quot;&gt;Play Darkwaar1 on itch.io&lt;/a&gt;&lt;/iframe&gt; `;

context.gameHtml = iframe; return context;

// HtmlFlow → Variable = gameHtml
</code></pre><p>Here, the <code>JavascriptFlow</code> creates an iframe (e.g. to an itch.io game) and stores it in <code>gameHtml</code>. The <code>HtmlFlow</code> retrieves this variable and displays it directly, <strong>without an internal iframe</strong>, thanks to secure client-side rendering.</p><h2>🔒 Secure HTML rendering</h2><p><code>HtmlFlow</code> is not a simple <code>dangerouslySetInnerHTML</code>. It applies <strong>custom DOM filtering</strong>, specifically designed to allow embeds (iframe, simple markup) while blocking XSS attacks or CSS injections.</p><p>Among the rules applied:</p><ul><li>Removed dangerous tags (<code>script</code>, <code>object</code>, <code>embed</code>, <code>form</code>, <code>button</code>, etc.) * Removed <code>on*</code> (e.g. <code>onclick</code>) and <code>style</code> attributes * Strict URL checking (<code>https:</code> or relative only) * Cleaned up <code>iframe</code>: only safe attributes (<code>src</code>, <code>width</code>, <code>height</code>, <code>frameborder</code>, <code>allowfullscreen</code>, <code>sandbox</code>) are kept * Automatically added a <strong>safe sandbox</strong> on iframes * SSR protection: no server-side execution * Memoization and size limits to avoid excessive rendering</li></ul><p>These safeguards ensure a <strong>balance between flexibility and security</strong>, ideal for integrating visualizations or games without compromising the stability of the flow.</p><h2>🎮 Darkwaar – Towards a playable puzzle game</h2><p>Meanwhile, the Darkwood universe continues to take shape. I've started several prototype puzzle games, playable directly on <a href="https://darkwoodcom.itch.io">itch.io</a>, exploring different mechanics:</p><ul><li><strong>Strategic placement</strong> on a grid,</li><li><strong>Turn-based</strong> and pawn management,</li><li><strong>Logic resolution</strong> (find the next winning move).</li></ul><p>These prototypes allow me to quickly iterate on the gameplay before stabilizing a main version. The short-term goal: a playable puzzle in web format, accessible to all from itch.io.</p><h2>🌐 Uniflow × Darkwaar – Native integration via <code>HtmlFlow</code></h2><p>Thanks to the new <code>HtmlFlow</code> component, I was able to <strong>directly integrate the four Darkwaar projects into Uniflow</strong>. Each of the prototypes is now visible <strong>from a dedicated flow</strong> on <a href="https://uniflow.io/flows">uniflow.io/flows</a>.</p><p>This integration concretely demonstrates how Uniflow can serve as a <strong>creative hub</strong>: flows become modules capable of orchestrating, displaying and hosting interactive creations — in this case, Darkwaar games — in the same environment.</p><blockquote><p>💡 This approach paves the way for a space where <strong>automation and playful creation come together</strong>. &gt; Every Darkwaar prototype is a flow, and every flow can become a playable experience.</p></blockquote><h2>🔗 Useful links</h2><ul><li>🧩 <strong>Uniflow 1.1.18</strong> — <a href="https://github.com/uniflow-io/uniflow/releases/tag/v1.1.18">Read the release on GitHub</a></li><li>✨<strong>Full technical article</strong> — <a href="https://uniflow.io/blog/2025-10-06-html-flow">HtmlFlow on the Uniflow blog</a></li><li>🎮 <strong>Prototypes Darkwaar</strong> — <a href="https://uniflow.io/flows">Available on uniflow.io/flows</a></li><li>🌑 <strong>Darkwood</strong> — <a href="https://darkwood.com">darkwood.com</a></li></ul><h2>🔮 And after?</h2><p>Future versions of Uniflow will continue to explore the visual and interactive dimension of flows:</p><ul><li>secure integration presets (itch.io, YouTube, dashboards), * advanced visualization components, * and natural connection between <strong>automation</strong>, <strong>gaming</strong> and <strong>art creation</strong>.</li></ul><p>Darkwaar, for its part, will follow suit. The goal remains the same: to build a coherent universe where programming, imagination, and play meet.</p><p>✍️ <em>Mathieu Ledru</em><em>Darkwood – Automaton. Create. Play. Music</em></p><p>🎁 I offer free 30-minute coaching sessions to help creators like you automate their processes and save time ⏱️</p><p>👉 Book your free session here: <a href="https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process">https://www.bonzai.pro/matyo91/lp/4471/je-taide-a-automatiser-tes-process</a></p><p>Thanks for reading! Let's create smart, fast, and automated workflows together 💻⚡</p>
]]></content:encoded><link>https://blog.darkwood.com/article/uniflow-1-1-18</link><guid>https://blog.darkwood.com/article/uniflow-1-1-18</guid><enclosure url="http://darkwood.com/media/articles/68e38aebd1638168196805.png" /></item><item><title>🎮 Comprendre l’ECS : la brique invisible derrière les jeux modernes</title><pubDate>Mon, 13 Oct 2025 07:43:07 +0000</pubDate><description><![CDATA[
entities (players, enemies, objects, tiles), * behaviors (movement, attack, effect), * and systems (rendering, AI, collisions, status effects, etc.).

Classic object-oriented approaches quickly end up creating overly deep hierarchies: Player extends Charac...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68eccf9517db7726294380.png" /></p><ul><li>entities (players, enemies, objects, tiles), * behaviors (movement, attack, effect), * and systems (rendering, AI, collisions, status effects, etc.).</li></ul><p>Classic object-oriented approaches quickly end up creating overly deep hierarchies: <code>Player extends Character extends Entity extends Drawable extends Object</code>… Result: a gas factory.</p><p>This is where the ECS — Entity Component System comes in.</p><h2>⚙️ The basic idea</h2><p>The ECS starts from a simple principle:</p><blockquote><p>separate data, behavior, and execution.</p></blockquote><p>| Element | Role | Example | | ------------- | ------------------------------------------- | --------------------------------------------------------- | | Entity | Unique Identifier | <code>#23 = Warrior on square (3,2)</code> | | Component | Raw data (no logic) | <code>Position(3,2)</code>, <code>Life(10)</code>, <code>Attack(3)</code> | | System | Behavior (acts on some components) | <code>MovementSystem</code>, <code>CombatSystem</code>, <code>RenderingSystem</code> |</p><p>ECS doesn't replace object-oriented programming—it deconstructs it to make it scalable. Instead of writing <em>what each class does</em>, you define <em>how data interacts</em>.</p><h2>🧩 Concrete example</h2><p>Let's take a simplified example in GDScript (Godot):</p><pre><code class="language-gdscript"># Component Position class_name CPosition extends Resource @export var q:int @export var r:int

# Life Component class_name CVie extends Resource @export var hp:int = 10

# Rendering system extends Node const CPosition = preload(&quot;res://components/CPosition.gd&quot;)

func process_system(dt): for entity in get_entities_with([CPosition]): var pos = entity.get_component(CPosition) draw_unit(pos.q, pos.r)
</code></pre><p>Here :</p><ul><li>the entity doesn't &quot;do&quot; anything — it contains components; * systems trigger on entities that have a certain set of components.</li></ul><p>It's a data-driven approach: everything is driven by data.</p><h2>🧮 Why it's powerful</h2><p>ECS isn't just a trendy design pattern. It's a structuring approach that solves three major problems:</p><h3>1. Scalability</h3><p>You can add new behaviors without breaking old ones:</p><blockquote><p>Adding a <code>CInvisible</code> component is enough for a “Rendering” system to ignore your entity.</p></blockquote><h3>2. Replay and Simulation</h3><p>You can replay a game by applying the same sequence of events, because all game state is pure data, serializable, diffable, and testable.</p><h3>3. Performance</h3><p>Modern ECS (like Flecs, EnTT or Unity DOTS) store data in contiguous memory. The CPU loves this:</p><blockquote><p>fewer calls, less cache-miss, more speed.</p></blockquote><h2>🧱 In Darkwaar 5</h2><p>Darkwaar 5 is based on a lightweight ECS in GDScript, without an external engine. The goal is to have:</p><ul><li>a central world (<code>World</code>), * simple entities (one Node per character or object), * components (<code>Resource</code>) for data, * systems (<code>Node</code>) for logic.</li></ul><p>Simplified example:</p><pre><code class="language-gdscript"># GameRoot.gd @onready var world := $World

func _ready(): var unit = world.create_entity() unit.add_component(CPosition.new()) unit.add_component(CVie.new())
</code></pre><p>Each frame:</p><ul><li>the <code>World</code> passes over the active systems; * the systems traverse the entities that concern them; * and the logic executes on the raw data.</li></ul><p>This separation makes it easy to add:</p><ul><li>a buff system (temporary effects), * a combat resolution system, * or a puzzle system for levels.</li></ul><h2>🧩 ECS ≠ magic</h2><p>ECS doesn't do &quot;better&quot; than an object-oriented approach: it makes it easier to maintain.</p><p>But there is a cost: you have to think in data streams, not object hierarchies.</p><ul><li>No “Player.move()”, but a <code>SystemMouvement</code> which reads the <code>CPosition</code> and <code>CVitesse</code>. * No “Enemy.attack()”, but a <code>SystemCombat</code> which reads the <code>CCombat</code> and <code>CVie</code>.</li></ul><p>It's a paradigm shift—but once understood, everything becomes clearer.</p><h2>🧭 What Darkwood remembers from it</h2><p>At Darkwood, ECS isn't just a game architecture. It's a way of thinking about modularity:</p><ul><li>In Darkwaar, it structures the gameplay and puzzles. * In Uniflow, it inspires the logic of data flows. * In Flow, it serves as the basis for the visual composition of automations.</li></ul><blockquote><p>Same fight: separate data, behaviors and execution logic.</p></blockquote><h2>🔮 And after?</h2><p>The next step for Darkwaar 5:</p><ul><li>integrate the ECS into the isometric map system; * link each box to an entity; * and synchronize the components between the view (top) and the HUD (bottom).</li></ul><p>This will lay the foundation for an open-source isometric tactical engine, designed for procedural generation, puzzles, and emergent systems.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/comprendre-l-ecs-la-brique-invisible-derriere-les-jeux-modernes</link><guid>https://blog.darkwood.com/article/comprendre-l-ecs-la-brique-invisible-derriere-les-jeux-modernes</guid><enclosure url="http://darkwood.com/media/articles/68eccf9517db7726294380.png" /></item><item><title>✨ SyliusCon 2025: The Sylius ecosystem reaches full maturity</title><pubDate>Mon, 20 Oct 2025 07:57:13 +0000</pubDate><description><![CDATA[SyliusCon 2025 confirmed that the Sylius ecosystem is now a major player in the open source e-commerce landscape. Built on the solid foundation of Symfony, Sylius continues its technical growth, while opening up to new horizons: cloud scalability, a moderni...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/68f5eb597e3f3733486412.png" /></p><p>SyliusCon 2025 confirmed that the Sylius ecosystem is now a major player in the open source e-commerce landscape. Built on the solid foundation of Symfony, Sylius continues its technical growth, while opening up to new horizons: cloud scalability, a modernized developer experience, and the growing integration of artificial intelligence.</p><p>This year's packed program reveals a professional setting, focused on production and efficiency. Far from hype, the conferences highlighted concrete topics: migration, performance, automation, and pragmatic AI.</p><h2>Sylius 2024–2025: Community, Product, and B2B Focus, by Mikołaj Król</h2><h3>Community &amp; Ecosystem</h3><ul><li>Record year for meetups (even outside Europe) and conference participation: the strategy is clear—strengthening IRL ties. * 15 new partners join the ecosystem (with a leading partner in France). * Arrival (return) of a CTO, Simon, a contributor from the very beginning. * Hats off to the key contributors and volunteers who maintain the open-source heart.</li></ul><h3>Product rhythm &amp; versions</h3><ul><li>30 releases published over the year (security + features). * Sylius 1.x: last year in 2025, end of support in 2026 → recommended course on Sylius 2 (support tools planned).</li></ul><h3>Doc-First &amp; official extensions</h3><ul><li>Documentation-first shift: write the manual before the feature to accelerate adoption and quality. * Official CMS (simplified UX dev &amp; editor) and Wishlist now maintained Sylius plugins. * MCP standard (commerce agent): first concrete steps to buy via agent in Sylius — strategic topic to follow. * Overhaul of the plugin process: new skeleton, smoother pipeline, dedicated test-app to verify plugins on several versions (Sylius 1 &amp; 2).</li></ul><h3>Front &amp; DX</h3><ul><li><p>Boilerplate React/PWA connected to the Sylius API to shorten headless projects. * Store Wizard: generate a demo/POC in minutes (data + skin), boosted with AI — useful for pre-sales. * New modules:</p><ul><li>Request for Quotation (RFQ) for B2B; * Made-to-Order / Web-to-Print for custom/made-to-order products.</li></ul></li></ul><h3>B2B Focus: “Elasto”</h3><ul><li>Launch of a B2B accelerator (UX review, advanced pricing, integrations, large catalogs tested ~600k SKUs). * Public demo available + live demo on the booth.</li></ul><h3>Roadmap 2026</h3><ul><li>Marketplaces: dedicated accelerator (modern features, polished DX). * B2C Fashion pack: express start for fashion cases. * AI for devs: libraries + contexts to accelerate creations, migrations and maintenance. * Installation of plugins/themes from the admin, and redesign of the Sylius Store to better monetize themes/plugins (call to creators).</li></ul><h3>Things to remember for Darkwood</h3><ul><li>If you are starting or migrating: anticipate Sylius 2; use the test-app and accelerators (B2B/coming Marketplace &amp; Fashion). * For pre-sales: Store Wizard allows you to create a convincing POC in a few minutes. * On the offer side: think RFQ and Made-to-Order if your journeys require it. * If you are editing extensions: window of opportunity with the installation admin and the redesign of the Store.</li></ul><blockquote><p>Key message: Sylius consolidates its base (docs, official plugins, DX), accelerates B2B with a showcase product (Elasto) and prepares 2026 around Marketplaces, B2C packs, IA dev and distribution of extensions from the admin.</p></blockquote><h2>From controlled maintenance to cloud scale</h2><p>Mathias Arlaud's talk on deprecation management set the tone: the Symfony/Sylius pairing is reaching maturity. The time has come to stop racing for new versions and instead focus on rationally planning upgrades. Deprecations are becoming roadmap milestones, not roadblocks.</p><p>The same logic applies to performance. Erwin Hofman demonstrated how Chrome DevTools, enhanced with a built-in AI assistant, now simplifies debugging <em>Core Web Vitals</em>. Performance is becoming a business indicator in its own right.</p><p>And when Gracjan Józefczyk talks about Sylius's scalability in the cloud, the message is clear: the era of cloud-native e-commerce is fully open. ECS containers, Aurora database, S3 + CloudFront, SQS: Sylius proves its ability to handle massive loads, while remaining an open source framework. FrankenPHP plays a key role, modernizing the PHP deployment and execution chain.</p><p>Sylius can handle massive peaks (e.g., thousands of orders/hour or more) provided scalability is treated as a discipline: read/write database, containerized execution, CDN for heavy assets, and observability + fault tolerance. The “video game launch” use case serves as a stress test (AAA volume).</p><p>Context &amp; issues</p><p>Typical customer question: “Can Sylius handle 6,000 orders/hour?”</p><p>Mental benchmark via the gaming industry (Elden Ring, Zelda, Cyberpunk, etc.): AAA releases create global peaks (millions of sales in a few days).</p><p>Conclusion: this level of load exists, we must prepare for it by design.</p><p>Recommended architecture (AWS as an example)</p><p>Database (Aurora/RDS)</p><p>Simple vertical scaling (RAM/CPU/storage) + read replicas in horizontal scaling.</p><p>Pattern read/write split (Doctrine/Symfony): write operations on the primary, massive reads on the replicas (indexing, search, analytics).</p><p>Automatic failover: in the event of a primary failure, a replica takes over (minimizes the incident instead of a costly snapshot restore).</p><p>Containerized Sylius App</p><p>ECS (or K8s) deployment with Auto Scaling: x instances at peak times, ↓ at night.</p><p>Separation of roles: HTTP containers vs workers (Messenger/cron).</p><p>Blue/green/canary: routing a percentage of traffic to V2; instant rollback via the load balancer.</p><p>Content Distribution &amp; Latency</p><p>S3 + CloudFront for assets/heavy downloads (e.g. 100+ GB games) → traffic deported from the application server, edge cache close to customers (Sydney, NY, etc.).</p><p>Image management via Flysystem / LiipImagine + S3/CloudFront adapters (config change, no massive refactor).</p><p>Security &amp; Network</p><p>App &amp; DB in private subnets; only ALB/CloudFront exposed publicly.</p><p>Infrastructure as Code</p><p>Terraform/CloudFormation in Git: PR, review, traceability; everyone understands and can develop the infrastructure (no “wizard admin”).</p><p>SLA and cost of failure</p><p>99% availability = ~2 days 15 hours 36 minutes of downtime/year → losses on order peaks.</p><p>The cloud costs money, but it costs less than downtime at the wrong time.</p><p>Code-side implementation (Symfony/Sylius)</p><p>Multiple connections doctrine (primary/replicas) + “read-only” hints.</p><p>Images/FS: FilesystemInterface (Flysystem) → switch S3/CloudFront without changing the business code.</p><p>Sylius Docker-ready (docker-compose), transposable to production (ECS/K8s).</p><p>Key message</p><p>Sylius &quot;flies&quot; very well in the cloud if you decouple read/write, autoscale the app, and outsource the static/heavy work to the CDN. The bottleneck is not Sylius itself, but the architecture you give it.</p><p>Bonus Resource</p><p>Gracjan is launching a free course “Can Swans Fly?”: Deploying Sylius on AWS with Terraform (blueprints, step-by-step).</p><h2>CMS, API, Mobile: Sylius integrates into all environments</h2><p>The CMS debate between Sulu, DegDitor, and Monsieur Biz demonstrated the vitality of the ecosystem: Sylius no longer seeks to do everything, but to interface well. <em>Headless commerce</em> is finally finding its balance between flexibility and robustness.</p><p>On the mobile side, the presentation by Dominique De Vasconcelos, Célia Maure and Jérôme Caluory on the deployment of a B2B application connected to the Sylius API perfectly illustrates this openness: a single base, several interfaces, and a consistent user experience across all channels.</p><h2>Artificial intelligence, useful and integrated</h2><p>Above all, SyliusCon 2025 marked a shift in the way we approach AI. Gone is the fascination with giant models, and now comes useful integrations.</p><p>With Nicolas Potier and Sabrine Ferchichi, conversational AI is making its way into commerce: a shopping assistant integrated into WhatsApp shows how Sylius can open up to <em>conversational commerce</em>.</p><p>Magda Sadowska pursued this vision with a developer-centric approach. The integration of Codex and the Model Context Protocol (MCP) simplifies documentation, accelerates research, and streamlines collaboration. AI is no longer a gimmicky feature, but an integrated productivity engine.</p><p>Here is a summary ready to be included in the Darkwood blog post of Magda Sadowska's talk (<em>“AI and Sylius: A Promising Partnership”</em>):</p><h2>AI at Sylius: not a magic wand, a multiplier</h2><h3>Thesis</h3><p>At Sylius, AI is neither imposed nor “autopilot”: it’s a measured tool that augments a small team (≈20 people) to deliver better and faster. We measure first, we adopt later, and we keep what proves its value.</p><h3>Principles of use (that really work)</h3><ul><li>Rich context &gt; model: objectives, files, constraints, “done well” criteria. * Planning mode (30 s) before briefing the AI → less back and forth. * Small scopes + frequent context reset. * Rubber-ducking: AI as clarifier (explaining unknown code, change log). * Never mandatory: dissemination is done through short demos and “repeatable wins”. * Seniors set safeguards; juniors explore and find useful patterns. * Lucid reminder: studies show that seniors can be slowed down by AI → we target the right cases (unknown code, onboarding, research, translation/explanation).</li></ul><h3>4 concrete initiatives boosted by AI</h3><ol><li><p>MCP (Model Context Protocol) for Sylius</p><ul><li>“USB-C of AI”: an agent can call real tools from the store (e.g., place an order). * In progress: MCP integration layer for guided setup (payments, taxes, shipping), troubleshooting (“why does the checkout fail in FR?”), CRM/PIM, live rates, labels, etc. * Targeted KPIs: fewer admin clicks, faster demos, clear audit logs of agent actions.</li></ul></li><li><p>Store Wizard (demo generator)</p><ul><li>Generates a Sylius demo (catalog, visuals, structure) in hours from a brief. * Inspired the installation of plugins &amp; themes via UI (PoC validated).</li></ul></li><li><p>AI Context Packs for 1.x → 2.x Migrations</p><ul><li>Rich contexts (BC breaks, checklists, hooks, APIs) that the AI uses to suggest changes and highlight risks. * Dev remains in the driver's seat; goal: quickly unlock plugins &amp; projects. * Planned release of plugin compatibility hints + sharing of upgrade contexts.</li></ul></li><li><p>Redesign of the doc (2.x)</p><ul><li>AI-assisted migration (repo + old docs + internal rules) to more accessible, up-to-date (hooks, APIs) and better interlinked (Symfony, API Platform) docs.</li></ul></li></ol><h3>Also, marketing &amp; research side</h3><ul><li>AI is used for landscaping, monitoring (pricing, changelogs, doc quality), cross-linking — always with human review.</li></ul><h3>What Darkwood Holds Back</h3><ul><li><p>Measure &gt; “hype”: we keep what reduces cycle time, bugs and publisher friction. * Investing in context improves quality more than changing models. * Golden cases for us:</p><ul><li>Accelerated POC demos (Store Wizard), * Guided setups via MCP (ready-to-use payments/shipping), * Assisted Sylius 2.x upgrades (context packs), * AI-clarified docs/procedures.</li></ul></li></ul><h3>Roadmap on the Sylius side</h3><ul><li>Extend MCP (config, troubleshooting, guidance). * Replace unsuitable AI tools; standardize useful contexts. * Publish compatibility guides and share upgrade contexts with the community.</li></ul><blockquote><p>Magda's key message: AI didn't change the team—it changed the way work was orchestrated. No magic, but practices that turn good ideas into results.</p></blockquote><p>Finally, Andrzej Michałowski and Mike Korba explored the future of personalization through Large Behavioral Models (LBMs), systems capable of interpreting user behavior with the same precision as language. Hyper-personalization becomes measurable, contextualized, and truly actionable.</p><p>Andrzej Michałowski opened his conference by tracing 12 years of personalization evolution, from classic recommendation systems to unified real-time architectures. At Synerise, his company, over 1.8 billion personalized messages and 4.6 billion recommendations are generated each month via email, SMS, push, and WhatsApp. The central idea: personalization is no longer a marketing module, but a system for orchestrating customer interactions.</p><ol start="2"><li>The three pillars of modern personalization</li></ol><p>Data always up to date. Synerise has designed its own behavioral data-oriented database, capable of performing segmentations on the fly (decision in 10–20 ms).</p><p>AI not as a substitute, but as an amplifier. AI makes it possible to combine simple signals (name, loyalty points) with complex predictions (propensity, churn, likely products).</p><p>Execution must be unified: data, content, channels and CRM in a single platform, with low-code automation and omnichannel tracking.</p><ol start="3"><li>Large Behavioral Models: post-LLM</li></ol><p>Andrzej introduced the concept of Large Behavioral Models (LBM):</p><p>Fundamental models trained not on language, but on behavior.</p><p>Just as LLMs predict the next word, LBMs predict the next customer action: click, purchase, visit. Once the basic model is built, it becomes trivial to create specialized models for specific use cases (recommendation, churn, scoring) in a matter of hours, instead of weeks. Synerise's results already exceed those of similar work published by Meta and DeepMind.</p><ol start="4"><li>A real case: Decathlon Poland</li></ol><p>The example presented was telling: the Decathlon.pl site personalizes the entire experience in real time:</p><p>Dynamic banners based on purchasing propensities;</p><p>Categories, brands and products suitable for the session;</p><p>Shopping cart recommendations and contextualized product pages;</p><p>Emails and push notifications aligned with the overall journey. Each interaction instantly adjusts recommendations, proving the feasibility of session personalization at scale.</p><ol start="5"><li>The Synerise x Sylius plugin</li></ol><p>In conclusion, Andrzej announced the release of a Synerise plugin for Sylius, allowing to:</p><p>Automatically synchronize customer and product data;</p><p>Leverage customization from the out-of-box;</p><p>Real-time event capture (transaction, shopping cart, visit);</p><p>Deploy multi-channel scenarios without code.</p><ol start="6"><li>Towards Behavioral CMS</li></ol><p>Finally, he introduced a new concept: Behavioral CMS, a fully headless content system that draws directly on behavioral data to generate and personalize content without manual integration. This CMS centralizes content, CRM, and product data for an experience that's always fresh, consistent, and contextual.</p><p>🧩 In summary</p><p>Andrzej Michałowski places personalization in a global framework:</p><p>Unified behavioral data, fundamental models trained on human action, and automated omnichannel execution.</p><p>Sylius thus becomes a brick within a data-centric architecture, where AI does not replace marketing, but streamlines it.</p><h2>Smoother, cleaner development</h2><p>Developer usability (DX) is also progressing. Loïc Frémont and Estelle Gaits presented a modernized Sylius Grid based on the new PHP attributes <code>#[AsGrid]</code>, <code>#[AsFilter]</code> and Symfony UX LiveComponent, for a responsive back office without custom JavaScript.</p><p>For his part, Stephan Hochdörfer recalled the importance of a reproducible development environment with DDEV: no more configuration divergences, less friction between teams.</p><p>Here is an editorial summary (ready to paste into the Darkwood article) of the CMS panel: <em>Johannes Wachter (Sulu)</em>, <em>Filippo Maria Tasca (DegDitor)</em>, <em>Jacques Bodin-Hullin (Monsieur Biz)</em>, with the Sylius CMS (core) perspective.</p><h2>CMS &amp; Sylius: choosing the tool at the right level of complexity</h2><h3>Starting problem</h3><p>You're launching a store, the marketing team asks &quot;can we edit <em>just this small block</em>?&quot; → we need a CMS. The panel asks the right question: which CMS for which context (team size, content importance, e-commerce constraints)?</p><h3>DNA of solutions (why they exist)</h3><ul><li>Sulu (Johannes – Sulu CMS) Born in the DACH (DE/AT/CH): multilingual/multi-portal from birth, symfonic, thought of as a “content application platform”. Double pillar: robust technical base + very neat editor UX. * DegDitor (Filippo) Started from the needs of merchants (ex-Shopify, luxury/fashion): front-end productivity and editor freedom (live preview, drag-drop, cloning), front/back decoupling to iterate quickly. * Monsieur Biz CMS (Jacques) 100% Sylius CMS plugin ecosystem (rich editor, homepage, menu, pages): dev flexibility, zero synchronization on the store side, simple DX to add “homemade” blocks. * Sylius CMS (core vision – Nico) Minimal and simple plugin: base understandable by any Symfony/Sylius dev, extensible without friction. Intentionally non-exhaustive: if the content becomes strategic, move upmarket.</li></ul><h3>What everyone does “best”</h3><ul><li>Sulu: internationalization &amp; multi-site on point, advanced editor UX, front-end performance, and “enterprise” ecosystem (ERP, PIM, integrations). * DegDitor: front-end productivity (autonomous front-end devs), modern editor experience (live preview, cloneable blocks). Ideal when the content “tells” the product (lookbooks, editorials, landing pages). * Monsieur Biz: pragmatic flexibility within Sylius, very quick implementation, safe by design for non-techs, while letting devs create custom UI blocks. * Sylius CMS: simplicity and minimal time-to-value for basic needs (a few pages/blocks), perfect for getting started and prototyping.</li></ul><h3>For whom / when?</h3><ul><li>Small teams, “nice to have” content (B2B, little editorial) → Sylius CMS (starter), then Monsieur Biz if rich blocks are needed. * “Content-driven” brands (fashion, luxury, storytelling, numerous landing pages) → DegDitor (front-end autonomy + UX editor). * “Enterprise” environments (multi-country, ERP/PIM, editorial workflows, large content team) → Sulu (specialized, decoupled, scalable CMS).</li></ul><blockquote><p>Rule of thumb: Measure the size of the content team rather than the size of the catalog. The more editing/approval/SEO is a major factor, the more a specialized CMS is required.</p></blockquote><h3>Collaboration &amp; UX editor</h3><ul><li>Sulu: AI is seen as a feature engine in the UI (buttons, fields, search), not just a chat. * DegDitor: front-first, React editor with live preview, fine control of what the editor can modify (guardrails via YAML of the blocks). * Monsieur Biz: rich modular editor + preview (currently being improved), platform-side security; we don't expose the editor to breaking the front. * Sylius CMS: sober by choice, the UX depends a lot on how the dev extends it.</li></ul><h3>AI &amp; Automation (positions assumed)</h3><ul><li>Sulu: integrates AI into UI (assisted SEO, content optimization) + prepares a “provider-agnostic” AI platform (key, prompts, GDPR, multi-vendors) for agencies. * DegDitor: experiments with translations, content generation, pages via YAML, and Figma → blocks bridge (sketch → component). * Monsieur Biz: targets AI to accelerate the creation of new UI blocks (MCP/LLM for scaffolding). * Sylius CMS: does not pursue “editor” AI as standard (strategic choice: let specialists take care of it).</li></ul><h3>Total Cost of Ownership (TCO)</h3><ul><li>Sulu: OSS, no license; requires experienced Symfony devs; runs from VPS to scalable cloud (K8s, functions). * DegDitor: ~2,500 € one-off license per primary domain (+ 4 subdomains), starter pack to reduce time-to-market; after block creation, little back-end required. * Monsieur Biz: quick installation (Composer); perfect for juniors on block creation; low adoption cost if already on Sylius. * Sylius CMS: MIT, cost = learning + customization; ideal for starting small.</li></ul><h2>Darkwood Reco (express decision grid)</h2><ul><li>Immediate need, small team, 5–10 pages → Sylius CMS. * We want to stay with Sylius but beef up the editing → Monsieur Biz CMS. * Responsive front end, demanding marketing, lots of templates → DegDitor. * Multi-site, multi-language, big workflows &amp; integrations → Sulu.</li></ul><p>Key idea: start integrated (marginal cost), move up in specialization when the content team grows and content becomes a business lever (SEO, storytelling, campaigns).</p><p>Here's a Darkwood blog post-ready summary of Ksenia Zvereva's talk (<em>“Scope, Iterate, Deliver”</em>):</p><h2>Scope, Iterate, Deliver: The Product Survival Kit for Tech Teams</h2><h3>The thesis</h3><p>Stop piling up features and chasing emergencies: frame the problem, limit the appetite (time), ship small and often, then iterate with real signals. The goal is not “more code,” but more impact.</p><h3>The 3 big traps to avoid</h3><ul><li>Functional over-commitment: inflating scope, slipping dates. * Resistance to change: inability to integrate market insights along the way. * Late validations: coding based on untested assumptions.</li></ul><h3>Guiding principles (to be applied by the whole team, not just the PO)</h3><ol><li>Shared product mindset: devs, design and PO co-own the outcome (not just the output). 2. Outcomes &gt; Output: prioritize the business/user effect, not the quantity of tickets. 3. Shape before coding: clarify problem, constraints, pitch → <em>then</em> solution. 4. Define the “appetite”: “How much time are we willing to invest?” → fixed time, flexible scope.</li></ol><h3>Pragmatic techniques</h3><ul><li>Rapid prototyping (hours, not days): clickable mockups to validate journey and hypotheses before the build. * Dedicated cycles (e.g. 6 weeks): <em>out-of-cycle</em> (shaping/betting) → <em>in-cycle</em> (build focus, no distractions) → <em>cool-down</em> (feedback, debt, “little extras”). * T-shirt sizing (S/M/L/XL): common effort language, better load forecast. * Feature flags / incremental deployment: deliver to production under flag, activate 2–5–10% → measure → expand or rollback in 2 clicks. * Pre-mortem (30–45 min): list <em>before</em> go-live what can break (DB, latency, security, LB), and put in place simple countermeasures.</li></ul><h3>Delivery Mantra</h3><blockquote><p>Ship at 70–80%, put it in front of real users, learn, and iterate. “GA” is not an end, it’s a stream of continuous improvement.</p></blockquote><h3>What Darkwood Holds Back</h3><ul><li>Cadence &gt; heroic performance: a team wins through controlled cadence and controlled risk. * Quality comes from the framework (shape, appetite, flags), not from a “magic” sprint. * These practices apply as is to Sylius/Symfony projects (flags, cycles, sizing) and drastically reduce slippage.</li></ul><h3>Mini checklist (30 days)</h3><ul><li>Institute shape doc (1 page) for any topic &gt; 2 days. * Adopt T-shirt sizing in the current backlog. * Implement 1 feature flag end-to-end (CI/CD → progressive activation). * Plan a focus cycle (2–6 weeks) + dedicated cool-down. * Hold 1 pre-mortem before the next go-live.</li></ul><p>Here is a summary ready to be included in the Darkwood article of the talk by Loïc Frémont &amp; Estelle Gaits (<em>“Pole position on the grid”</em>):</p><h2>Sylius Grid: Turbo DX, Live UX and Total Decoupling</h2><h3>The key idea</h3><p>The Grid Bundle becomes a universal data grid (Sylius 1 &amp; 2): less YAML/boilerplate, more PHP attributes, custom data providers (without Doctrine), and a responsive UX with Symfony UX Live Components. The result: fast, modular back offices, ready for non-e-commerce cases.</p><h3>What's new that matters</h3><ul><li><p><code>make:grid</code> generator: now works with any PHP class (not just Doctrine entities). * Attributes</p><ul><li><code>#[AsGrid(...)]</code>: Declares provider, resourceClass, name; <code>__invoke()</code> method instead of <code>buildGrid()</code> (SRP, cleaner code). * <code>#[AsFilter(...)]</code>: Symfony form type, Twig template, filter alias — everything is co-located in the class. * Providers without DB: Demo with OpenF1 (three steps: empty → hard data → API). The provider applies the criteria (e.g. <code>country</code>) and serves the objects to the grid. * Navigation “related grids”: Actions that pre-filter another grid (e.g. “Team radios” button → grid already filtered by driver).</li></ul></li></ul><h3>Responsive UX (experimental)</h3><ul><li>Replaced grid Twig blocks with a Live Component (via <em>Twig hooks</em>). * Pagination, page/limit switching, filters → without reloading. * Multiple grids on the same page, each pre-filtered. * Live components provided for select, string, tab filters (update “as-you-type”).</li></ul><h3>What this changes for us (Darkwood)</h3><ul><li>Back-offices without custom JS: <code>#[AsGrid]/#[AsFilter]</code> + Live Components are sufficient in most cases. * Heterogeneous sources (API, files, internal services) without Doctrine: ideal for ops/transverse screens. * Less state on the front end, more clarity on the PHP side (attributes, providers, localized templates).</li></ul><h3>Mini adoption checklist</h3><ul><li>Migrate an existing grid to <code>#[AsGrid]</code> + <code>__invoke()</code>. * Extract a provider for a non-DB source. * Create a custom filter with <code>#[AsFilter]</code> (type + template). * Connect two grids via action + criteria. * Activate the Live Component on a screen (pagination &amp; filters without reload).</li></ul><blockquote><p>In short: Grid Bundle 1.14 puts DX in pole position and paves the way for responsive, API-first admin panels – with Sylius as the chassis, regardless of the data engine.</p></blockquote><h2>DDEV for Docker dev environments… without the pain, not Stephan Hochdörfer (BitExpert)</h2><h2>Why DDEV?</h2><p>Born in the Drupal community, DDEV is now a generic open-source tool that hides Docker complexity for local developers. Ideal if the team doesn't want to &quot;talk Docker&quot; on a daily basis, while maintaining its benefits (isolation, reproducibility, multi-project).</p><h3>Live demo (with a few surprises 😉)</h3><p>Stephan started a project from scratch:</p><ul><li><code>ddev config</code> → generates .ddev/config.yaml (project name, type Symfony/Drupal/… , docroot, PHP version). * <code>ddev start</code> → builds one image per project with the correct UID/GID (no more root files). * <code>ddev launch</code> → opens the local URL (no more need to remember domains). * Built-in commands: <code>ddev console</code> (alias of <code>bin/console</code>), <code>ddev exec</code>, <code>ddev logs -s db</code>, <code>ddev import-db/export-db</code> (MySQL/PostgreSQL agnostic). * Custom commands (e.g. <code>ddev bootstrap</code>) to chain Composer/Yarn/migrations — the “executable doc” of your README.</li></ul><h3>Add-ons &amp; services</h3><p>An add-on registry allows you to add Redis, OpenSearch/Elasticsearch, Varnish, etc. via <code>ddev add-on get …</code>. Stephan showed how to package your own add-ons (e.g. Algolia) with service dependencies.</p><h3>IDE &amp; DX</h3><p>The DDEV plugin for PhpStorm (now maintained by the DDEV team):</p><ul><li>Autoconfigures PHP, Docker, PHPUnit, Xdebug (&quot;xdebug on&quot; and it works). * Updates the project's DB/Redis connections. Result: we code, not wire.</li></ul><h3>Web servers &amp; exotic stacks</h3><p>Beyond Apache/Nginx, DDEV can run on a generic web server:</p><ul><li>Example shown: FrankenPHP (dedicated Dockerfile + <code>generic_webserver</code> + daemon command). * DDEV can also drive bun.js, Spring Boot, etc. as long as an HTTP endpoint is exposed.</li></ul><h3>Sylius: test-app &amp; plugins</h3><p>Sylius Wink: Stephan plugged the Sylius test-app into DDEV to quickly test plugins (injected DB/Redis env, aka <code>vendor/bin/console</code>). Useful for maintaining a plugin on Sylius 1 &amp; 2.</p><h3>Stop properly</h3><ul><li><code>ddev stop</code>: Stops the project's containers. * <code>ddev poweroff</code>: Also shuts down global containers (traefik, ssh).</li></ul><h2>What we remember for our projects</h2><ul><li>Faster onboarding: 4–5 orders and a workstation is up and running. * Fewer human errors: images per project, aliased orders, standardized add-ons. * Better quality: <code>ddev</code> scripts = reproducible procedures (local CI/CD). * Sylius gains: rapid plugin testing, multi-versions, modular B2B/B2C stacks.</li></ul><blockquote><p>In short: DDEV gives you the power of Docker without the friction—perfect for e-commerce teams (Sylius, Symfony, etc.) who want to deliver quickly, cleanly, and without hunting for ports or container IDs. Oh, and yes… it had stickers 😄.</p></blockquote><h2>Five underlying trends to remember</h2><ol><li>Upgrade-as-a-discipline: version upgrades become a managed and measurable process. 2. Cloud-native by default: containers, messaging, CDN and FrankenPHP as the basic foundation. 3. Agent-oriented APIs: a new generation of APIs designed to interact with autonomous agents. 4. Unified DX: Symfony UX + redesigned Sylius Grid = responsive back-office without front-end complexity. 5. Pragmatic AI: intelligence integrated into the value chain (doc, data, decision), not just into visible functionalities.</li></ol><h2>In conclusion</h2><p>SyliusCon 2025 not only confirmed the framework's technical solidity; it revealed a mature, structured community aware of its challenges. Sylius is becoming a strategic foundation, capable of tackling the complexity of modern commerce, without sacrificing code quality or freedom of integration.</p><p>The maturity of the Sylius ecosystem is now based on three pillars: standardization, scalability and intelligent integration.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/syliuscon-2025-the-sylius-ecosystem-reaches-full-maturity</link><guid>https://blog.darkwood.com/article/syliuscon-2025-the-sylius-ecosystem-reaches-full-maturity</guid><enclosure url="http://darkwood.com/media/articles/68f5eb597e3f3733486412.png" /></item><item><title>🤖 AI Café Club #12: Creation, business, cinema… AI in all its forms at the Monnaie de Paris</title><pubDate>Thu, 27 Nov 2025 15:31:05 +0000</pubDate><description><![CDATA[
On November 26th, the Monnaie de Paris hosted the twelfth edition of the AI Café Club, a now well-established event connecting creators, entrepreneurs, engineers, makers, and curious minds around artificial intelligence. This edition, held at the Café Frap...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69286eb9af8de527584274.jpg" /></p><p><img src="/blog/images/articles/ia-cafe-club-12/meetup.jpg" alt="meetup.jpg" /></p><p>On <strong>November 26th</strong>, the Monnaie de Paris hosted the twelfth edition of the <strong>AI Café Club</strong>, a now well-established event connecting <strong>creators, entrepreneurs, engineers, makers, and curious minds</strong> around artificial intelligence. This edition, held at the <strong>Café Frappé par Bloom</strong>, brought together a diverse audience eager to explore a <strong>creative, practical, and accessible</strong> AI, far removed from media hype and closer to real-world applications.</p><h2>🧠 <strong>An evening dedicated to AI in all its diversity</strong></h2><p>The AI Café Club is not a classic meetup: it's a space where we talk about <strong>business, creation, web, cinema, code, no-code tools, productivity</strong>... everything that makes the digital world move today.</p><p>The objective: to offer a <strong>cross-cutting</strong> and <strong>realistic</strong> view of artificial intelligence — what it is changing now, what it is already enabling, and how everyone can use it to create, transform or undertake.</p><h2>🎤 <strong>4 express talks, 12 minutes each: a dense and effective format</strong></h2><p>Each edition offers a varied program, designed to deliver maximum value in minimum time. Here are the presentations from Café Club #12:</p><h3><strong>1. Loïc Boutet — AI for SMEs: where to start without breaking the bank</strong></h3><p>A simple and pragmatic roadmap for integrating AI into a small or medium-sized business: automation, analysis, accessible tools, quick wins.</p><p>Here is a version ready to paste into the article for the <strong>Loïc Boutet</strong> section. I maintain the clear/educational, SME-oriented and practical tone, while structuring his ideas.</p><h2>💼 Loïc Boutet — AI for SMEs: where to start without breaking the bank</h2><p>In addition to being a co-organizer of the evening, <strong>Loïc Boutet</strong> came with a simple promise: to show how an SME can take advantage of AI <strong>without a colossal budget</strong>, without a dedicated team and without an abstract “global AI” strategy.</p><p>Loïc runs <strong>5000.dev</strong>, a company that designs applications in two weeks for €5,000. Needless to say, he's well aware of the time, budget, and prioritization constraints faced by SMEs. His talk was a complete <strong>demolition of the false &quot;good advice&quot;</strong> we hear everywhere about AI.</p><h3>1. Before agents, start with… assistants</h3><p>Loïc starts with an observation: everyone has been talking about <strong>AI agents</strong> for a year, but the majority of companies <strong>do not even master assistants yet</strong>.</p><p>His advice:</p><p>Don't start with complex agent architectures. Start by creating <strong>assistants dedicated to specific tasks</strong>.</p><p>Examples of assistants he uses daily:</p><ul><li>Writing <strong>functional specifications</strong> for web applications * Preparing <strong>client presentations</strong> * Generating <strong>structured text content</strong> (documents, emails, presentation materials) * Assisting with <strong>preparing one's own talks</strong></li></ul><p>Assistants (GPT, Claude, Gemini, etc.) already cover a huge portion of the uses. You don't need a sophisticated system to start saving time.</p><h3>2. Don't train &quot;everyone&quot;, start with the motivated ones</h3><p>Another myth he debunks:</p><p>“We’re going to train the entire company in AI.”</p><p>According to him, it's the best way to <strong>fail</strong>.</p><p>His recommendation:</p><ul><li>Identify <strong>2 or 3 motivated and curious people</strong> * Give them time, tools, and freedom to experiment * Then let them <strong>spread</strong> throughout the rest of the organization</li></ul><p>AI adoption is not a “massive training plan” but a <strong>core group of pioneers</strong> who are showing concrete results.</p><h3>3. You don't need a “Head of AI” or a data scientist to get started</h3><p>Loïc insists: for the majority of SMEs, the first reaction <strong>should not be</strong>:</p><ul><li>“We’re going to recruit an AI manager” * “We need a data scientist to get the project off the ground”</li></ul><p>With current generative AI, we are no longer in the historical model where a specific model was trained for a specific task.</p><p>Generative AI is a <strong>very powerful Swiss Army knife</strong> that already does <strong>80%</strong> of what you need very well, without custom training.</p><p>A subscription to an AI tool (around twenty euros per month) already allows you to:</p><ul><li>to write, * to analyze, * to summarize, * to generate ideas, * to structure documents, * to assist internal processes.</li></ul><p>That's <strong>enough to start</strong> creating value.</p><h3>4. Forget the “grand strategic AI project”: start with the boring tasks</h3><p>Another cliché debunked:</p><p>“We are going to launch a major global AI project, with a roadmap, massive ROI and total transformation.”</p><p>For Loïc, it's the best way to <strong>never deliver anything</strong>.</p><p>Instead, he recommends starting with a simple question:</p><p>What are the <strong>most unpleasant tasks</strong> of the week?</p><p>Examples given:</p><ul><li>Draft <strong>meeting minutes</strong> * Process <strong>repetitive letters or emails</strong> * Rewrite <strong>contracts/templates</strong> * Assist in answering customer questions using an assistant powered by project documents * Evaluate <strong>sales calls</strong> or support interactions</li></ul><p>This is where AI provides an immediate benefit and where we can measure, very quickly, the <strong>value created</strong>.</p><h3>5. The sandwich method: human → AI → human</h3><p>Loïc introduces a simple image: <strong>the sandwich</strong>.</p><ul><li><strong>Human at the beginning</strong>: clearly define the problem, constraints, and context * <strong>AI in the middle</strong>: produce the first version, doing 80% of the work * <strong>Human at the end</strong>: review, correct, validate, and adapt</li></ul><p>AI excels at going from <strong>nothing</strong> to <strong>something</strong>. Humans excel at going from <strong>something average</strong> to <strong>something good or excellent</strong>.</p><p>Striving for 100% automation is often a dead end. Aiming for <strong>80% automation</strong> with 20% effort yields the best results in practice.</p><h3>6. AI knows almost everything… except who you are</h3><p>A key point of his talk:</p><p>AI knows the world, but <strong>doesn't know you</strong>.</p><p>For an assistant to be truly useful in a professional context, it must be provided with:</p><ul><li>your <strong>internal processes</strong>, * your <strong>methods</strong>, * your <strong>corporate culture</strong>, * your <strong>customer cases</strong>, * your <strong>business rules</strong>, * your <strong>prioritization choices</strong>.</li></ul><p>AI doesn't need to be told what project management, marketing, architecture, etc. are. It needs to be told <strong>how you do these things</strong>.</p><p>This is what transforms a generic tool into a <strong>truly tailored assistant</strong> for your business.</p><h3>7. Don't wait for &quot;perfect maturity&quot;: the time is now</h3><p>Loïc is also responding to a very common reflex:</p><p>“We’ll wait until it’s more mature, more sovereign, better regulated, 100% secure…”</p><p>Except in very specific cases (banking, defense, ultra-sensitive context), waiting is mostly about <strong>letting others get ahead</strong>.</p><p>The market, however, doesn't wait. Competitors are moving forward, tools are evolving, and usage patterns are stabilizing. The right strategy today is to <strong>experiment intelligently</strong>, with simple safeguards, rather than remaining a spectator.</p><h3>8. His simple method for starting tomorrow morning</h3><p>Loïc concludes with a very practical method for getting into AI at work:</p><ol><li><p><strong>Identify a tedious, repetitive, low-value-added but frequent task.</strong> 2. <strong>Manually test the AI on it</strong> until a satisfactory result is obtained: promptness, sequencing, output format. 3. Once the process is stable, <strong>ask the AI itself</strong>:</p><blockquote><p>“What prompt should you have received to produce this result directly?” &gt; Then turn that into a <strong>dedicated assistant</strong>.</p></blockquote></li></ol><p>From there, you have crossed <strong>the first real adoption threshold</strong>: a real task, in your business, partially automated by an AI assistant.</p><h3><strong>2. Dêlidji Hounsonlon &amp; Perla Nsungani — Create websites without coding with Lovable</strong></h3><p>Demonstration of Lovable, the no-code tool that lets you design a complete website through a simple conversation. A glimpse of what web creation can become in the coming months.</p><h2>🌐 Quoable — Create a complete website without coding thanks to Lovable</h2><p>The second presentation of the evening — led by <strong>Delidji Hounsonlon</strong> and <strong>Perla Nsungani</strong> from the <strong>Quoable</strong> collective — focused on a topic that resonates with both creators and entrepreneurs: <strong>how to go from a website idea… to a fully live website, in just a few minutes, without writing a single line of code?</strong></p><p>To achieve this, they introduced <strong>Lovable</strong>, an AI-driven &quot;live coding&quot; platform that democratizes website creation at an impressive speed.</p><h3>💡 The real problem: ideas are plentiful… but time and technology are lacking.</h3><p>The talk begins with a fact that everyone in the room confirmed:</p><p>The obstacle isn't a lack of ideas. The obstacle is the technology, the cost, the time, or the difficulty in finding a developer.</p><p>Lovable removes precisely these barriers — by transforming a simple intention, formulated in natural language, into a <strong>functional website</strong>.</p><h2>⚙️ What is Lovable?</h2><p>Lovable is a web development platform where you <strong>describe</strong> what you want… and where AI <strong>generates the site in real time</strong>.</p><p>Some key points:</p><ul><li>Founded in 2022 by two Swedish entrepreneurs, <strong>Anton Nisica</strong> and <strong>Fabian Näslund</strong> * $100 million raised in less than a year * Estimated valuation of $21 billion * Over 100 million new creations annually * Millions of daily visits to websites generated through the platform</li></ul><p>These figures illustrate a simple reality:</p><p>Lovable responds to a global demand — to make web development <strong>accessible</strong>, fast and modular.</p><h2>🧪 Live coding: write what you want, and AI builds it</h2><p>Lovable's core is based on <strong>live coding</strong>:</p><ol><li>You write what you want in natural language. 2. The AI interprets your intent. 3. It generates <strong>real code</strong>, editable and exportable.</li></ol><p>Unlike other no-code platforms:</p><ul><li>The code is <strong>user property</strong> * It can be exported, versioned, and modified freely * You are not locked into the tool</li></ul><h2>🧱 The tech stack behind Lovable</h2><p>Under the hood, Lovable relies on a modern stack:</p><ul><li><strong>Front-end:</strong> React, TypeScript, CSS * <strong>Back-end:</strong> C++ for the database, user management, and server logic * <strong>Framework used:</strong><strong>Sprite</strong>, integrated directly into the platform * <strong>Deployment:</strong> One click to publish, one click to remove the website from the web</li></ul><p>Everything is designed to shorten the idea → prototype → production site cycle as much as possible.</p><h2>🚀 How does it work, in practice?</h2><p>Creating a website with Lovable involves three steps:</p><h3>1. Describe</h3><p>You write whatever you want:</p><p>“I want a website for a photographer, with a gallery, contact page, and a minimalist black &amp; white style.”</p><p>The AI immediately generates:</p><ul><li>A complete structure * Functional pages * A first version of the design</li></ul><h3>2. Adjust</h3><p>You refine:</p><ul><li>Add sections * Modify style * Change text * Integrate features * Directly edit generated code if needed</li></ul><p>AI adapts in real time.</p><h3>3. Publish</h3><p>With one click, the site is <strong>online</strong>, with a URL ready to be sent.</p><p>Everything can be disabled or updated just as easily.</p><h2>🎥 Live demo: Create a website in minutes</h2><p>To illustrate the simplicity of the tool, the Quoable team demonstrated the creation of a website <strong>live</strong>, in front of the entire Café IA Club.</p><p>The flow:</p><ul><li>A simple idea in text * Generation in seconds * Interactive adjustments * Immediate online publication</li></ul><p>All this <strong>without coding</strong>, but with real code behind it, ready to be exported or handed over to a developer if needed.</p><h2>🎯 Remember the essentials</h2><p>Lovable's promise, as presented by Quoable:</p><ul><li><strong>Reduce website creation time</strong> from several weeks… to just a few minutes * <strong>Make web development accessible</strong> to everyone * <strong>Prototype, launch, test</strong> faster * Enable everyone to <strong>transform an idea into a web product</strong> without technical barriers</li></ul><p>A clear demonstration of how applied AI can change the digital creation chain.</p><p>If you want, I can follow up with:</p><p>✔️ The <strong>Thibault Mardinli — Vibe Coding</strong> section ✔️ The article's conclusion ✔️ A &quot;Subscribe to the AI Club Café&quot; CTA ✔️ A Darkwood visual for this section</p><h3><strong>3. The Bernards Club (Thierry Chovanec &amp; Marine Les Serrano) — AI &amp; Cinema</strong></h3><h1>🎬 <strong>Presentation 1 — The Bernards Club: AI as a driver of creativity in cinema</strong></h1><p>The first talk was hosted by <strong>Le Club des Bernards</strong>, a creative studio specializing in projects blending <strong>image, storytelling, and artificial intelligence</strong>. Their presentation provided a rare glimpse into how AI is now integrated into the <strong>film</strong> pipeline, from <strong>pre-production</strong> to <strong>marketing</strong>, including <strong>art direction</strong> and <strong>world-building</strong>.</p><h2>🎨 A creative studio augmented by AI</h2><p>The speakers presented their organization: a studio that uses AI at all stages of creation — <strong>illustration</strong>, <strong>concept art</strong>, <strong>storyboard</strong>, <strong>previsualization</strong>, <strong>marketing content</strong>, <strong>translations</strong>, <strong>alternative images</strong>, <strong>bilingual materials</strong>, etc.</p><p>AI doesn't eliminate artistic work: it <strong>accelerates tasks</strong> and <strong>multiplies possibilities</strong>. A striking example: an illustrated poster that usually takes <strong>20 hours</strong> to create using purely traditional methods can be reduced to <strong>5 hours</strong> by combining AI and human art direction. The tools don't replace: they amplify.</p><h2>🎥 The context of cinema: fewer resources, more ideas</h2><p>Their observation: the film industry is going through a period where it needs to <strong>produce more with less</strong>. Investors are harder to convince, budgets are shrinking, and business models are evolving.</p><p>It is in this context that their studio intervenes, particularly within a major school and production teams: <strong>their role is to help directors and writers to shape their ideas</strong>, to make a project &quot;visible&quot; even before it exists.</p><h2>🧩 From idea to visual: how AI is transforming pre-production</h2><p>The process is clear:</p><ol><li><strong>Script reading</strong> 2. <strong>Image production</strong>, creating atmospheres and visual concepts 3. <strong>Storyboard creation and pre-visualizations</strong> 4. <strong>Development of materials for investors</strong> (presentations, mood boards, internal trailers)</li></ol><p>They use AI to quickly generate visual proposals consistent with the film's universe. The goal: to allow the director to confirm an artistic direction, and investors to understand the project.</p><p>They showed several examples of posters, scenes, and concept boards produced within this framework.</p><h2>🌐 Building a complete universe: from design to digital</h2><p>In one of their projects, the team developed:</p><ul><li>an <strong>immersive site</strong> to present the narrative universe, * a <strong>fictional journal</strong> in AI, * textual and visual content aligned with the lore, * interactive elements allowing the discovery of narrative clues.</li></ul><p>AI is used as a building block to expand a universe, produce rapid variations and explore multiple artistic directions, while maintaining a coherence specific to the director's vision.</p><h2>🎭 AI and casting: from fiction to visual prototype</h2><p>Another fascinating aspect: the AI used to test casting choices.</p><p>Based on a character description, the studio produces consistent visuals of different actors, in order to explore:</p><ul><li>physical compatibility, * artistic direction, * aesthetic impact on the film.</li></ul><p>Example mentioned: imagining <em>Franck Dubosc</em> or <em>Jean Dujardin</em> in the role of a character inspired by <strong>Jules Verne</strong>, to test the visual potential before discussing it with the producers.</p><p>Here again: AI does not impose a choice, it <strong>opens the debate</strong> and saves time.</p><h2>🖼️ Art direction: multiple atmospheres, a coherent universe</h2><p>From the same paragraph of script, the team generates:</p><ul><li>variations in <strong>colorimetry</strong>, * <strong>darker</strong>, <strong>more colorful</strong>, <strong>more realistic</strong> atmospheres, * alternative compositions.</li></ul><p>These images do not yet replace visuals intended for an 8K screen in a movie theater — but they allow the director to arrive <strong>prepared</strong>, with a clear vision of the shot to be filmed.</p><h2>🎞️ A trailer built entirely to convince Netflix</h2><p>One of their most telling use cases: an <strong>internal trailer</strong> created from a script and visual concepts, intended not for the public but for <strong>decision-makers</strong>.</p><p>The goal: to showcase the world, the aesthetic ambition, and the coherence of the project. This type of trailer, made possible by modern AI, is now a key tool for <strong>selling a film</strong> even before its production.</p><p>Result: the presented project was approved by Netflix.</p><h2>⚖️ Their position: AI should never replace humans</h2><p>The talk concluded with a clear vision:</p><ul><li>AI is a <strong>powerful tool</strong>, not a director. * It accelerates ideas but <strong>should not make decisions</strong> instead of creatives. * Standardization is a real risk if AI is allowed to generate without human guidance. * Artists must remain at the center to guarantee <strong>uniqueness</strong>, <strong>emotion</strong>, and <strong>artistic direction</strong>.</li></ul><p>The studio uses AI to <strong>augment</strong> creativity, never to automate it entirely.</p><h3><strong>4. Thibault Mardinli — From prototype to clients with vibe coding</strong></h3><p>An approach based on creative energy, rapid iteration, and AI-assisted prototyping. A talk focused on entrepreneurship, prototyping, and rapid execution.</p><h2>🔊 Thibault Mardinli — From prototype to creation: “Vibe Coding” as an engine of expression</h2><p>The final talk of the evening was presented by <strong>Thibault Mardinli</strong>, with a spontaneous and authentic account of how AI has transformed his approach to creating, working… and even entrepreneurship. No slides. No formal demonstration. Just a raw, sincere journey and one key idea: <strong>you can create far more than you think</strong>, even without knowing how to code.</p><h3>🌪️ A journey made of failed projects… and discoveries</h3><p>Thibault begins by recalling what he calls &quot;his two specialties&quot;: <strong>planting projects</strong>, and <strong>organizing community events</strong>.</p><p>His latest project: developing a <strong>smart walkie-talkie</strong> using voice AI. Two years of experimentation, voice APIs, testing, prototypes… ultimately resulting in entrepreneurial failure.</p><p>But it was precisely this failure that triggered what he calls his <strong>“happy accident”</strong>.</p><h3>⚡ An intense creative phase: “before finding a job… create something”</h3><p>When it came time to close his business, Thibault made a simple decision:</p><p>“Before going back to work, create something, share what you’ve learned, and help at least one person.”</p><p>It is in this state of mind that he builds what will become his platform — a hybrid between website, database, observatory and resource center around voice AI:</p><ul><li>Database of <strong>400</strong> voice tech products * News filters to avoid information overload * Tutorials for developers and non-developers * Reports, tests, user experiences * Free resources, no upsells, no hidden business model</li></ul><p>Everything is done <strong>in the evening, at home</strong>, with a single driving force: passion.</p><h2>🔧 “Vibe coding”: coding without coding, creating through energy</h2><p>Thibault emphasizes a key point:</p><p>He doesn't know how to code. He doesn't read code. And he doesn't want to learn.</p><p>What interests him is not the technique, but <strong>creation</strong>. And that's where what he calls <strong>vibe coding</strong> comes in:</p><ul><li>Use AI to guide the code, without getting into technical details * Focus on the idea, the use case, the narrative * Let AI generate, structure, and assemble * Keep the human element to choose, connect, and feel the right direction</li></ul><p>For him, the backend — often considered the “forbidden territory” of non-techs — can now be approached by anyone, as long as <strong>curiosity</strong> and <strong>intention</strong> are put into the process.</p><h2>🎯 The happy accident: when creativity meets visibility</h2><p>A simple share on LinkedIn by a friend caused a surge in traffic to his platform. Very quickly, companies started contacting him.</p><ul><li>“What you're doing is useful.” * “Keep going.” * “We want to help you financially.”</li></ul><p>Ironically, while he simply wanted to pass on his knowledge, he attracts the interest of brands — who offer to <strong>sponsor</strong> the continuation of his work.</p><p>Genuine creativity, without commercial intent, has found its place. And Thibault insists: it's <strong>neither simple nor glamorous</strong>, but <strong>possible</strong>.</p><h2>🧠 A call to action: AI as a teacher, as a partner, as a multiplier</h2><p>Thibault develops a strong conviction:</p><p>“The best person to ask a question to create something… is AI itself.”</p><p>He emphasizes the idea that AI is today:</p><ul><li>a <strong>teacher</strong> * an <strong>exploration engine</strong> * a <strong>prototype accelerator</strong> * an <strong>infinite toolbox</strong> * a <strong>creative companion</strong></li></ul><p>It's not a replacement for humans. It's an extension. An amplification. A catalyst for passion.</p><h2>🛠️ Accessible tools to get started immediately</h2><p>Speaking frankly, Thibault discusses the reality of the market: some platforms are very well marketed but too limited to go far. Others are more technical but much more powerful.</p><p>And according to him, if we want to have fun today, create, test, and learn:</p><blockquote><p>“Go to <strong>AI Google Studio</strong>.”</p></blockquote><p>He recommends it because it allows you to:</p><ul><li>to create <strong>images</strong>, * to generate <strong>videos</strong>, * and even to develop <strong>complete apps</strong>… in minutes.</li></ul><p>For him, it's the perfect tool for creative, family, educational or entrepreneurial use.</p><h2>🌍 A pivotal period: voice, education, health, entrepreneurship…</h2><p>Thibault concludes with a broader perspective:</p><p>We are living through a pivotal moment. Voice AI — his obsession — is going to revolutionize:</p><ul><li><strong>education</strong>, * <strong>medicine</strong>, * <strong>access to knowledge</strong>, * <strong>entrepreneurship</strong>, * and <strong>individual creation</strong>.</li></ul><p>His final message:</p><p>Create. Test. Experiment. Ask the machine questions. There's no shame in that: it's a new human skill.</p><p>And most importantly:</p><p>Passion is what unites us all here.</p><p>A perfect closing word for Café IA Club #12.</p><p>If you want, I can now:</p><p>✔️ Provide you with <strong>the article's conclusion</strong> ✔️ Generate a <strong>&quot;3 key ideas&quot; block</strong> for each speaker ✔️ Create a <strong>chapter visual</strong> for this final section ✔️ Write you the <strong>newsletter</strong> version of Café IA Club #12</p><h2>🍸 <strong>Drinks, meetings &amp; networking</strong></h2><p>After the talks, the meetup continued with a friendly aperitif in the Café Frappé space. The venue's atmosphere, both elegant and relaxed, fostered conversations between:</p><ul><li>developers, * designers, * creators, * entrepreneurs, * film professionals, * generative AI enthusiasts.</li></ul><p>This community dimension is what makes <strong>L'IA Café Club</strong> so strong: an open, curious ecosystem, geared towards building concrete projects.</p><h2>📍 <strong>An iconic location: the Monnaie de Paris</strong></h2><p>Organizing this edition at the heart of the Monnaie de Paris gave the event a special dimension. Its historic setting, combined with the modern space of Café Frappé by Bloom, created a unique atmosphere: <strong>cultural heritage versus technological innovation</strong>.</p><h2>🎯 <strong>Why this meeting matters</strong></h2><p>AI Café Club #12 confirms a trend: artificial intelligence is no longer a subject reserved for experts. It now permeates:</p><ul><li>business, * artistic creation, * web development, * audiovisual, * entrepreneurial projects, * personal productivity.</li></ul><p>With an accessible, practical and action-oriented approach, the event allows everyone to leave with <strong>new ideas, tools and perspectives</strong>.</p><h2>📅 <strong>See you at the next edition</strong></h2><p>Places fill up quickly, and each edition is unique. If you want to join the community and not miss any events, follow the upcoming announcements — the AI Café Club continues to explore the new frontiers of artificial intelligence, always with the same spirit: <strong>simple, practical, open, and inspiring.</strong></p>
]]></content:encoded><link>https://blog.darkwood.com/article/ai-cafe-club-12-creation-business-cinema-ai-in-all-its-forms-at-the-monnaie-de-paris</link><guid>https://blog.darkwood.com/article/ai-cafe-club-12-creation-business-cinema-ai-in-all-its-forms-at-the-monnaie-de-paris</guid><enclosure url="http://darkwood.com/media/articles/69286eb9af8de527584274.jpg" /></item><item><title>🧩 Meetup AFUP Paris – Novembre 2025</title><pubDate>Fri, 28 Nov 2025 18:05:52 +0000</pubDate><description><![CDATA[Document validation with Symfony + AI &amp;amp; technical test decryption
On November 27, 2025, the AFUP Paris branch: PHP met at Eleven Labs, at 102 Rue du Faubourg Saint-Honoré, for another meetup of the 2025-2026 season. A friendly, technical evening resolut...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6929e480df33c970299617.jpg" /></p><p>Document validation with Symfony + AI &amp; technical test decryption</p><p>On November 27, 2025, the AFUP Paris branch: PHP met at Eleven Labs, at 102 Rue du Faubourg Saint-Honoré, for another meetup of the 2025-2026 season. A friendly, technical evening resolutely focused on the current challenges of PHP development: AI applied to Symfony, quality, recruitment… and a good time for networking.</p><p>🏢 A welcome at Eleven Labs</p><p>For this edition, Eleven Labs – an IT services company specializing in custom web and mobile projects, with offices in Paris, Nantes, and Montreal – hosted the community on the 5th floor of its premises. An ideal atmosphere for exchanging ideas, learning, and meeting other web enthusiasts.</p><p>🎤 AFUP Introduction &amp; News – Opening presentation of the meetup</p><p>As with every edition, the AFUP Paris team opened the evening with a welcome address, important announcements, and an overview of PHP and community news. Here is a complete summary of the points presented.</p><p>🙋‍♀️ 🎙️ Call for Speakers, Sponsors &amp; Venues</p><p>AFUP Paris regularly changes speakers, venues and even sometimes partners for food and drinks after the talks.</p><p>👉 If you wish:</p><p>suggest a topic,</p><p>to host a meetup at your premises</p><p>or sponsor the aperitif,</p><p>You are welcome! Just contact us we plan meetups several months in advance.</p><p>🎓 AFUP Mentoring Program: two components</p><p>AFUP has two mentoring programs, both voluntary and free:</p><ol><li>Mentoring for speakers</li></ol><p>For those who want to:</p><p>learn how to prepare a talk,</p><p>structuring a presentation,</p><p>or to gain confidence in speaking in public.</p><p>This program is still relatively unknown, but open to all levels. Don't hesitate to register!</p><ol start="2"><li>PHP Mentoring</li></ol><p>For :</p><p>mentees wishing to progress in PHP,</p><p>Mentors who want to pass on their knowledge.</p><p>👉 The registration link is available during meetups and on our social media.</p><p>🗓️ Upcoming AFUP Paris meetups</p><p>The next two dates have already been set:</p><p>Tuesday, December 17 – at Acolia</p><p>Thursday, January 8 – at Libid</p><p>As always, these evenings are free and open to everyone, subject to availability.</p><p>🔄 Overview of Parisian tech meetups</p><p>AFUP takes advantage of each edition to promote related tech events. In early December, several meetups will take place in Paris focusing on:</p><p>Ruby</p><p>Security / AppSec</p><p>Angular</p><p>And other local communities</p><p>A great opportunity to explore other ecosystems and expand your network!</p><p>🗞️ AFUP National News 🔹 AFUP Day 2025 – May 22</p><p>The event was announced last month. It will take place in 24 cities including: Bordeaux, Lille, Lyon… and, for the first time, Paris!</p><p>👉 Registration is open. A QR code was displayed: there are still a few places available at the &quot;blind spot&quot; price.</p><p>🐘 PHP News PHP 8.5 is released!</p><p>The new version has been available for a few days:</p><p>new official website</p><p>performance improvements,</p><p>Welcome new features for developers.</p><p>Results of the AFUP Salary Barometer</p><p>The annual barometer has been published:</p><p>market trends,</p><p>role-based forks</p><p>Evolution of PHP salaries in France.</p><p>Very useful for tracking your progress or negotiations.</p><p>PHPStan massively improves its support</p><p>Specifically for:</p><p>data providers,</p><p>other PHP constructs that have historically been poorly supported.</p><p>Good news for projects with high quality and static requirements.</p><p>📱 LinkTree AFUP Networks &amp; Community</p><p>All useful links are grouped here: LinkedIn, Twitter/X, Discord, Slack, Meetup…</p><p>Feedback questionnaire</p><p>A QR code was provided to collect your feedback on the evening. This feedback helps us improve future meetups.</p><p>🎙️ 1. Symfony + AI: validate your documents before even opening them!</p><p>Speaker: Marianne Joseph-Géhannin</p><p>The evening got off to a great start with a presentation focused on the automated pre-validation of documents using the Symfony + OCR + LLM combination. A very current use case for product teams and platforms that handle heterogeneous files on a daily basis.</p><p>For this first presentation of the evening, Marianne shared a concrete feedback: how to combine Symfony, OCR and language models (LLM) to automate the pre-validation of administrative documents before a human even consults them.</p><p>A practical topic, stemming from a real customer need, combining AI, quality and architecture.</p><p>👤 Who is Marianne?</p><p>Marianne has been developing in PHP since 2011, with a background that has included Symfony since version 1.4. She has been working at Eleven Labs since 2020 and is currently on assignment at Le Monde, notably on the Falcon framework.</p><p>🧩 The problem: documents to process… in bulk</p><p>The use case presented comes from a call for tenders for a company managing school trips and holiday stays.</p><p>Each case requires numerous documents:</p><p>identity card,</p><p>passport,</p><p>certificate,</p><p>various supporting documents…</p><p>For operational teams, manual verification represents:</p><p>a time-consuming task,</p><p>a risk of error,</p><p>a low-value treatment</p><p>and a large variability in the quality of the documents provided.</p><p>🎯 Project objective: to automatically eliminate incorrect documents so that operators only process truly valid files.</p><p>🧰 The three technical pillars of the project</p><p>Marianne built her solution using three main building blocks:</p><ol><li>Symfony + Symfony-AI</li></ol><p>The new Symfony AI initiative offers:</p><p>native integration of LLM into the Symfony ecosystem,</p><p>clients for language models,</p><p>integrated vectorization,</p><p>an “AI Platform” to simplify the use of providers.</p><p>In this project, Marianne mainly used:</p><p>ChatGPT integration via Symfony-AI Platform,</p><p>a first approach to vectorization for structuring rules.</p><ol start="2"><li>OCR with Tesseract</li></ol><p>The documents provided are often images (scans, photos, unstructured PDFs). OCR is therefore essential to extract usable text.</p><p>Functioning :</p><p>cleaning (contrast, noise reduction…),</p><p>detection of text areas,</p><p>character recognition,</p><p>production of a raw text.</p><p>Marianne uses Tesseract via:</p><p>an HTTP client,</p><p>a local Docker container</p><p>an abstract interface to change OCR if needed.</p><ol start="3"><li>An LLM to interpret and classify documents</li></ol><p>Once the text is extracted, an LLM analyzes:</p><p>What type of document is it?</p><p>if the expected information is present,</p><p>if the document is consistent.</p><p>Marianne tested several models:</p><p>ChatGPT → works perfectly</p><p>LLama, Qwen… via Ollama locally → limitations (response time, quality, hardware constraints)</p><p>She observed: ➡️ unpredictable or unusable local responses ➡️ insufficient hardware power ➡️ timeout issues</p><p>Result: for this POC, ChatGPT was the most reliable model.</p><p>📝 The prompt used</p><p>The prompt is intentionally simple:</p><p>provide a list of possible document types (ID card, passport, residence permit…)</p><p>provide the text extracted by OCR</p><p>request a response strictly in JSON format</p><p>This JSON format guarantees the possibility of:</p><p>validate the structure,</p><p>categorize the results,</p><p>save to database.</p><p>ChatGPT consistently adhered to the format which was not the case with local models.</p><p>🔄 Processing architecture (pipeline)</p><p>Here is the complete pipeline:</p><p>📤 Sending the file via a Symfony command (no form for the POC).</p><p>🧠 Tesseract OCR → text extraction.</p><p>💬 LLM → analysis, classification, validation.</p><p>🗃️ Recording of the result in the database, for use by the operators.</p><p>❌ If a document does not match its expected type → rejection + explanatory message.</p><p>The MVC approach is based on:</p><p>a DTO for data,</p><p>a handler,</p><p>specific services (OCR, AI, storage),</p><p>a modular design to replace components as needed.</p><p>🎥 Demonstration</p><p>Marianne showed several documents that were used:</p><p>an identity card,</p><p>a passport,</p><p>a poster reading “French Republic” (to test its robustness),</p><p>And the tool knew:</p><p>recognizing the correct document in simple cases,</p><p>reject false positives in ambiguous cases.</p><p>🧪 Limitations &amp; Lessons Learned ❗ Finding the Right AI Model</p><p>Local models (via Ollama) have shown their limitations: performance, inconsistencies, difficulty in respecting the JSON format.</p><p>ChatGPT has proven to be much more reliable.</p><p>❗ Manage the timeout</p><p>Several attempts were made to stabilize the response time.</p><p>Temperature settings, output constraints…</p><p>Sometimes it is necessary to patch directly into the local engine code.</p><p>❗ The documentation</p><p>Symfony-AI → very good documentation</p><p>OCR / Tesseract → more spartan</p><p>AI doesn't always help us understand what we don't yet understand!</p><p>❗ GDPR and security</p><p>It's impossible to send sensitive documents to an external provider in a real-world context. Hence the advantage of local processing but this requires suitable hardware.</p><p>🔎 What this POC demonstrates</p><p>✔️ AI can bring real business value to document validation ✔️ The Symfony → OCR → LLM pipeline is perfectly feasible ✔️ Operators save time by focusing on real-world cases ✔️ Symfony-AI integration greatly simplifies these processes</p><p>But also :</p><p>⚠️ AI isn't magic: you need to assess its relevance, workload, and costs. ⚠️ Don't underestimate the effort required to make an AI pipeline reliable and usable.</p><p>🎉 Conclusion</p><p>This project perfectly illustrates how Symfony + AI can solve very concrete problems by automating tasks that were previously done manually. It's a pragmatic, measured, and intelligent use of AI—far from being just a buzzword—and perfectly applicable to other sectors.</p><p>Thank you to Marianne for this rich and clear sharing!</p><p>🎙️ 2. The technical test: useful, useless or counterproductive?</p><p>Speaker: Jeanne Londiche</p><p>The second talk delved into a sometimes sensitive but crucial topic: technical testing in recruitment. Useful? Not always. Poorly calibrated? Often. Counterproductive? Sometimes.</p><p>💡 What has been explored:</p><p>What the technical test measures… and what it doesn't measure</p><p>The most common biases</p><p>The impact on stress, communication, and trust</p><p>How a test reveals logic and curiosity, not just code</p><p>What alternatives can be considered for fairer and more effective recruitment?</p><p>Interactive exchanges with the audience: feedback, anecdotes, best practices</p><p>An intervention that asks the right questions and helps both candidates and recruiters to better use (or rethink) this tool.</p><h1>🎙️ Talk: Technical testing – useful, useless, or downright counterproductive?</h1><p><em>By Jeanne Londiche</em></p><p>For the second talk of the evening, Jeanne offered an interactive conference on a topic that many developers know well (and sometimes dread): 👉 <em>technical testing in recruitment processes</em>.</p><p>Objective :</p><ul><li>Review the different types of tests, * share concrete feedback, * question what is actually being evaluated, * and ask: <em>“Does it really help with better recruitment… or not?”</em></li></ul><h2>👤 Who is Jeanne?</h2><p>Jeanne introduces herself:</p><ul><li>She runs an open-source job board focused on recruitment (hosted on GitHub). * She grew up in England and has lived there since 2013. * She has specialized in PHP recruitment since 2011.</li></ul><p>With over a decade of experience, she has seen all kinds of technical tests, from both the candidate and company sides.</p><h2>🧪 The main categories of tests covered</h2><p>Jeanne structures her presentation around several approaches:</p><ul><li>Multiple-choice questions / online questionnaires * In-house / application-based test (develop a small application) * Algorithm test * Refactoring test * Pair programming * Conversational technical interview</li></ul><p>The conference focuses mainly on three very common formats: 👉 multiple-choice questions, in-house tests, and refactoring, with many concrete examples.</p><p>#1️⃣ Technical MCQs: quick but very theoretical</p><p>Multiple-choice quizzes are often offered via specialized platforms. Jeanne asks the room: <em>“Who has already taken a technical multiple-choice quiz? Do you like them?”</em> Almost unanimous answer: no.</p><h3>✅ The positive points:</h3><ul><li>Quick to correct. * Useful for an initial screening of a large number of candidates. * Gives an &quot;objective&quot; aspect to the process (scores, thresholds, etc.).</li></ul><h3>❌ Major limitations:</h3><ul><li>Highly theoretical, often disconnected from the real-world experience of a developer. * Heavily dependent on how the questions are worded. * Can exclude talented candidates who may not have the &quot;correct&quot; definition in mind, but who would be perfectly capable of solving the problem in a real-world context. * Favor those who simply recite the &quot;recipe book&quot; rather than those with curiosity, practical experience, and common sense.</li></ul><p>In summary: ➡️ <em>useful for rough filtering</em> ➡️ <em>very insufficient for judging the true value of a developer</em>.</p><p>#2️⃣ In-house/application testing: practical, but often time-consuming</p><p>In-house (or application) testing involves developing a small application or feature &quot;as if it were in real life&quot;:</p><ul><li>to be done at home, * sometimes with a time limit, * sometimes “to be handed in when it’s ready”.</li></ul><p>In the room, several people testify: some spent 12 to 15 hours there for a single test.</p><h3>✅ The positive points:</h3><ul><li><p>Closer to the reality of work. * Allows you to see:</p><ul><li>Code structuring, * architectural choices, * test management, * documentation, * even a short summary email (“with more time, I would have done…”), which is often as important as the submitted code. * Leaves room for personal expression (technical choices, project organization, etc.).</li></ul></li></ul><h3>❌ Major drawbacks:</h3><ul><li><p>Can be very long: several evenings or an entire weekend. * Very often unpaid, especially for senior positions. * Risk of exploitation:</p><p>Companies sometimes use these tests to advance their own product without ever hiring. Many experienced developers now refuse these tests.</p><p>“It’s my job, I get paid to produce code; my experience and my CV speak for themselves.”</p></li></ul><p>And most importantly: 🟥 The lack of feedback is consistently cited as a major problem. Candidates spend hours on it, and at best receive:</p><blockquote><p><em>“Sorry, we are not continuing the process.”</em> &gt; without understanding what went wrong.</p></blockquote><h2>💬 Feedback: essential… and all too often absent</h2><p>Jeanne insists on one point: 👉 a technical test without feedback is a missed opportunity for both sides.</p><ul><li><p>For the candidate:</p><ul><li>It's frustrating, * impossible to know what was expected, * impossible to make progress.</li></ul></li><li><p>For the company:</p><ul><li><p>This gives a bad image of the process, * Candidates often draw the following conclusion:</p><p>“If even the test is poorly managed, do I really want to work with them?”</p></li></ul></li></ul><p>The room confirms: several people report having had:</p><ul><li>vague remarks such as <em>“not thorough enough”</em> without explanation, * or no feedback at all.</li></ul><p>Jeanne also points out that the technical test assesses the company as much as the candidate. A messy, opaque, or disrespectful process is a sign of a poor fit.</p><p>#3️⃣ Refactoring test: a format often more revealing</p><p>Jeanne then mentions a test format that she particularly likes: 👉 refactoring testing, sometimes presented as a <em>kata</em>.</p><p>Principle:</p><ul><li><p>Existing code is provided, sometimes very &quot;legacy&quot; or intentionally flawed. * The candidate is asked to explain:</p><ul><li>what he would do, * where he would start, * which parts he would refactor and why, * how he would improve readability, architecture, testing.</li></ul></li></ul><p>Sometimes this test is done:</p><ul><li>in pair programming, * or in an interview, based on a projected code excerpt.</li></ul><h3>✅ Why this format can be very interesting:</h3><ul><li><p>It closely resembles the reality of many missions (we rarely work from scratch). * It allows us to see:</p><ul><li>Analytical skills, * understanding of business challenges, * legacy system management, * technical communication. * It facilitates genuine exchange: choices can be explored in depth, discussions held, and challenges made.</li></ul></li></ul><p>But here again, the quality of the exercise depends on:</p><ul><li>clarity of instructions, * presence or absence of a structured debrief afterwards, * and how time is managed (explicit or implicit timer).</li></ul><h2>🤖 And what about AI in all of this?</h2><p>The question is posed: <em>“Will AI change everything for technical testing?”</em></p><p>Jeanne replies:</p><ul><li><p>Not really yet: the processes haven't been widely adapted. * But since AI is already changing our daily lives as developers, it would make sense for it to also change:</p><ul><li>test formats, * what is being assessed (ability to use tools, not just to do everything “by hand”).</li></ul></li></ul><p>We are probably heading towards tests where we appreciate the following equally:</p><ul><li>the ability to model a problem, * and to know how to intelligently rely on tools (including AI).</li></ul><h2>🧭 What Jeanne suggests remembering</h2><p>There is no perfect technical test. But we can ask the right questions:</p><p>For businesses:</p><ul><li><em>What do we really want to measure?</em> * <em>Does this test reflect the reality of the job?</em> * <em>Are we respecting the candidates' time?</em> * <em>Are we providing meaningful feedback?</em></li></ul><p>For developers:</p><ul><li><em>What does this test tell me about the company culture?</em> * <em>Do I really want to work in an environment that recruits this way?</em> * <em>Does the process make me want to join… or raise red flags?</em></li></ul><p>Ultimately, the technical test should be:</p><blockquote><p>a tool for meeting, not a torture test.</p></blockquote><p>🤝 A meetup open to everyone</p><p>As always with AFUP, the evening was open to everyone: beginners, juniors, seniors, tech leads, freelancers, or simply curious individuals. The goal was simple: to share knowledge, demystify concepts, and build connections.</p><p>Participation was free but places were limited, so the event showed great momentum and an engaged audience.</p><p>🎯 Why do these topics matter?</p><p>AI continues to have a significant impact on our PHP and Symfony applications.</p><p>Document quality and validation are real issues in production</p><p>Tech recruitment and its methods are evolving, sometimes too slowly.</p><p>Meetups play a vital role: breaking down silos, sharing experience, and staying up-to-date.</p><p>📅 See you at the next meetup</p><p>The AFUP Paris branch continues its 2025-2026 program with new topics, new speakers and always the same spirit: to share, learn, and advance the PHP community.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/meetup-afup-paris-novembre-2025</link><guid>https://blog.darkwood.com/article/meetup-afup-paris-novembre-2025</guid><enclosure url="http://darkwood.com/media/articles/6929e480df33c970299617.jpg" /></item><item><title>🚀 IA Pulse</title><pubDate>Fri, 05 Dec 2025 07:56:02 +0000</pubDate><description><![CDATA[ai-PULSE 2025 : l’Europe de l’IA passe à la vitesse supérieure
Le 4 décembre 2025, ai-PULSE l’événement IA organisé par Scaleway revient pour une nouvelle édition placée sous le signe de l’ambition européenne. Avec des speakers de premier plan, une programm...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69409d8a04193447942248.jpg" /></p><h1>ai-PULSE 2025 : l’Europe de l’IA passe à la vitesse supérieure</h1><p>Le 4 décembre 2025, ai-PULSE l’événement IA organisé par Scaleway revient pour une nouvelle édition placée sous le signe de l’ambition européenne. Avec des speakers de premier plan, une programmation dense et une vision affirmée (« Smarter, Faster, Everywhere »), ai-PULSE s’est imposé comme l’un des rendez-vous majeurs de l’intelligence artificielle sur le continent.</p><p>Cette année, l’agenda montre clairement une direction : l’Europe veut être un acteur, pas un spectateur, dans la révolution de l’IA.</p><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4007.jpg" alt="IMG_4007.jpg" /></p><h1>🌍 Un début de journée sous le signe des géants : les Opening Keynotes</h1><p>De 09h30 à 11h30, le Master Stage ouvre fort avec une succession de leaders tech :</p><ul><li>Xavier Niel (iliad Group)</li><li>Jérôme Monceaux (Enchanted Tools)</li><li>Pim de Witte (General Intuition)</li><li>Yann LeCun (Meta)</li><li>Rémi Cadene (UMA)</li><li>Neil Zeghidour (Kyutai)</li><li>Aude Durand (iliad Group)</li><li>Damien Lucas (Scaleway)</li></ul><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4012.jpg" alt="IMG_4012.jpg" /></p><p>Un mélange rare : recherche, industrie, cloud, robotique, modèles ouverts… tout ce qui façonne l’avenir de l’IA européenne réuni sur une même scène.</p><p>Voici un texte prêt à coller dans ton article, comme section “Keynote d’ouverture par Xavier Niel (avec Yann LeCun &amp; Pim de Witte)” en français, structuré, et fidèle au contenu que tu as collé.</p><h2>La keynote de Xavier : de l’IA sur écran à l’IA dans le monde réel</h2><p>Xavier ouvre la conférence en posant le décor : selon lui, le plus grand changement de ces dernières années, c’est que l’IA n’est plus confinée aux écrans ni aux endpoints dans le cloud.
Elle entre dans notre environnement :</p><ul><li>via des interfaces naturelles,</li><li>la voix,</li><li>des systèmes embarqués,</li><li>et des robots qui interagissent avec le monde.</li></ul><p>L’IA est désormais « partout ». Mais pour l’embrasser, explique-t-il, il faut d’abord la comprendre. C’est précisément ce qu’ai-PULSE veut permettre : donner des clés pour comprendre cette nouvelle génération d’IA, au-delà du simple effet de mode.</p><p>Avant de rentrer dans le vif du sujet, Xavier remercie les partenaires de l’événement il cite notamment IMD, Ampere et les autres acteurs qui ont contribué aux démos et à l’infrastructure. Sans eux, rappelle-t-il, une conférence de cette ampleur serait impossible.</p><h2>Des mots au monde : la transition vers les <em>world models</em></h2><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4013.jpg" alt="IMG_4013.jpg" /></p><p>Xavier enchaîne ensuite sur le “hot topic” du moment : comment l’IA est en train de passer d’un paradigme où elle prédit simplement le prochain mot… à un paradigme où elle comprend et simule le monde.</p><p>Il introduit la notion de world models : des modèles capables de représenter des environnements, des dynamiques, des actions et leurs conséquences.
L’idée n’est plus seulement de compléter une phrase, mais de simuler ce qui se passe si un agent agit dans un environnement donné.</p><p>Pour explorer cette idée, Xavier invite sur scène celui qu’il présente comme l’un des “pères” de l’IA moderne :</p><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4017.jpg" alt="IMG_4017.jpg" /></p><ul><li>Yann LeCun, lauréat du prix Turing, professeur à New York University, auteur de centaines d’articles qui ont façonné le machine learning, et jusqu’à très récemment Chief AI Scientist chez Meta.
Il glisse au passage qu’il espère que Yann pourra dire quelques mots sur son nouveau projet.</li></ul><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4014.jpg" alt="IMG_4014.jpg" /></p><h2>World models vs LLMs : pourquoi le langage ne suffit pas</h2><p>Xavier lance la discussion en rappelant un point clé qu’il a longuement abordé avec Yann et Pim : pour beaucoup de chercheurs, il est désormais clair que “scaler” uniquement les modèles de langage ne suffira pas à atteindre une intelligence générale.</p><p>Yann explique que l’idée de world models est ancienne dans sa réflexion : il la défend depuis près de vingt ans. Selon lui, comprendre le monde physique est bien plus difficile que comprendre le langage. Les animaux, qui ne parlent pas, sont déjà bien meilleurs que nos robots actuels pour naviguer dans le monde réel.</p><p>Il rappelle le paradoxe déjà formulé par les roboticiens :
on sait entraîner des IA à passer le barreau, écrire de la poésie ou coder, mais on ne sait toujours pas construire un robot qui ait la compréhension intuitive du monde d’un enfant de 6 ans.</p><p>Pour lui, cela veut dire qu’il nous manque quelque chose de fondamental :
des systèmes capables de se construire des modèles internes du monde, d’anticiper ce qui va se passer, et de raisonner sur les conséquences de leurs actions.</p><p>C’est ce qui l’a conduit à développer des architectures non génératives comme JEPA (Joint Embedding Predictive Architecture), et plus largement à défendre un nouveau blueprint pour l’IA orthogonal aux LLMs classiques.</p><h2>L’apport de General Intuition : de la vidéo à l’interaction</h2><p>Xavier introduit ensuite Pim de Witte, cofondateur et CEO de General Intuition. Il rappelle son parcours :</p><ul><li>ingénieur,</li><li>ancien de chez Intel,</li><li>cofondateur de Metal, une plateforme qui a constitué un dataset massif d’interactions de jeux vidéo dataset pour lequel OpenAI aurait proposé 100 M$, offre qu’ils ont refusée pour lancer leur propre labo.</li></ul><p>Avec Pim, la discussion bascule sur un point essentiel : la différence entre modèles vidéo et world models interactifs.</p><p>La vidéo est une excellente source de données, explique Pim, mais regarder le monde ne suffit pas :
un world model doit intégrer l’action et l’interaction.
Il ne s’agit plus seulement de prédire la prochaine image “plausible”, mais de prédire la distribution des futurs possibles en fonction des actions de l’agent.</p><p>Là où un modèle autoregressif “roule” sur lui-même (comme une boule de neige qui grossit en descendant la pente sans savoir ce qui l’attend), un vrai world model doit être capable de “voir le rocher en bas” et d’adapter sa trajectoire exactement comme le ferait un personnage conscient de son environnement.</p><h2>Pourquoi les générateurs de pixels ne suffisent pas</h2><p>Xavier ramène la discussion sur un point très concret pour les ingénieurs : pourquoi prédire des pixels n’est pas la bonne voie.</p><p>Yann explique que, dans une vidéo réelle, l’immense majorité des détails est fondamentalement imprévisible.
Si l’on filme la salle et qu’on demande à un modèle : “complète la suite de la vidéo”, il peut deviner qu’il y aura des gens assis, une scène, des lumières…
Mais il est impossible de prédire le visage exact de chaque personne, la position exacte de chaque main, etc.</p><p>Résultat :
un modèle qui essaie de prédire chaque pixel tombe soit dans le flou, soit dans le bruit, mais n’apprend rien d’utile pour l’action.</p><p>Les architectures non génératives, au contraire, apprennent des représentations abstraites des scènes et se révèlent bien plus efficaces en auto-supervision pour ce type de données continues, bruitées, riches.</p><h2>Données, compute et nouvelle vague de laboratoires</h2><p>Xavier revient ensuite sur les aspects très concrets que tout le monde a en tête :
les données et la puissance de calcul nécessaires.</p><p>Quelques points clés ressortent de l’échange :</p><ul><li><p>Il est plus facile d’obtenir beaucoup de données vidéo que beaucoup de texte de qualité.
Là où le texte “web” plafonne vite, des années de vidéo peuvent être collectées ou simulées.</p></li><li><p>Les world models ne nécessitent pas forcément des budgets délirants :
entraîner certains de ces modèles demande “quelques milliers de GPU”, loin des méga-clusters requis pour les plus gros LLMs.</p></li><li><p>Les datasets d’actions sont précieux :
hors des jeux vidéo ou de contextes très instrumentés, il est difficile d’obtenir des étiquettes d’action au niveau “ground truth”.
C’est un enjeu clé pour les prochains labs et startups.</p></li></ul><p>C’est aussi là que Xavier fait ressortir le contexte européen :</p><ul><li>l’Europe dispose d’un vivier énorme de talents,</li><li>il y a de la place pour des laboratoires indépendants, plus ouverts,</li><li>et pour une approche de l’IA qui ne soit pas uniquement “scale LLMs à l’infini”.</li></ul><p>Yann évoque son nouveau projet de labo indépendant (AMI Advanced Machine Intelligence), porté notamment en Europe, avec Meta comme partenaire mais pas comme actionnaire majoritaire, justement pour ouvrir le spectre des applications et favoriser une recherche moins enfermée dans le paradigme LLM.</p><p>Parfait, on enchaîne avec la partie “Yann LeCun”.
Voici un texte en français, propre et structuré, que tu peux intégrer tel quel dans ton article (par exemple juste après la partie sur Xavier).</p><h2>Yann LeCun : l’IA a besoin d’ouverture, pas de murs</h2><p>Lors de la discussion, Yann LeCun insiste sur un point souvent sous-estimé dans le débat sur l’IA : la manière dont un modèle est gouverné compte autant que sa performance.</p><p>Il prend l’exemple des modèles chinois : même si leur niveau technique peut être excellent, une partie de la communauté reste méfiante, car ces systèmes sont contraints de respecter les principes et la ligne politique du gouvernement chinois. Autrement dit, ce ne sont pas seulement des modèles techniques, ce sont aussi des modèles idéologiques.
Pour Yann, cette dimension limite naturellement leur adoption internationale.</p><h2>Pourquoi l’IA a autant progressé : la force de l’open source</h2><p>Yann rappelle ensuite un fait historique : si l’IA a progressé aussi vite ces dix, vingt, cinquante dernières années, c’est grâce à l’ouverture :</p><ul><li>logiciels open source,</li><li>publications en libre accès,</li><li>datasets et idées partagés au sein de la communauté.</li></ul><p>Il cite le rôle de FAIR (le labo de Meta), qui a fortement poussé ce modèle de recherche ouverte et a incité d’autres laboratoires comme DeepMind à devenir plus transparents et plus ouverts, sous la pression de la compétition scientifique.</p><p>Pour lui, c’est simple :</p><ul><li>la recherche ouverte est le meilleur moyen de progresser vite,</li><li>et c’est aussi le meilleur moyen d’attirer les meilleurs chercheurs.</li></ul><p>Si vous dites à un scientifique “tu ne peux rien publier de ce que tu fais”, vous n’attirez pas les meilleurs profils.</p><h2>JEPA : un concept récent, déjà repris partout</h2><p>Yann prend ensuite un exemple très concret : JEPA (Joint Embedding Predictive Architecture).
Il explique que si l’on tape aujourd’hui ce terme dans un moteur de recherche, on obtient déjà des centaines de résultats, alors que le concept n’a été formalisé que quelques années plus tôt.</p><p>En quelques années, des équipes du monde entier se sont emparées de l’idée, l’ont testée, adaptée, étendue à de nouveaux domaines.
C’est exactement ce qu’il veut illustrer : l’innovation en IA ne peut pas être réservée à quelques laboratoires fermés, elle a besoin de milliers de cerveaux qui expérimentent en parallèle.</p><h2>Ce qu’il faut ouvrir… et ce qu’on peut garder fermé</h2><p>Yann ne défend pas une naïveté totale : il ne dit pas que tout doit être gratuit et public.</p><p>Il propose plutôt une frontière claire :</p><ul><li><p>Ce qui doit être ouvert :</p><ul><li>les idées,</li><li>les architectures,</li><li>les briques fondamentales,</li><li>les prototypes de recherche.</li></ul><p>C’est ce qui alimente le progrès scientifique global.</p></li><li><p>Ce qui peut rester propriétaire :</p><ul><li>l’industrialisation,</li><li>la mise en produit,</li><li>les couches spécifiques de valorisation commerciale.</li></ul></li></ul><p>Autrement dit :
open source en amont, business en aval.
C’est ce compromis qui permet à la fois d’avancer vite, de garder une communauté scientifique vivante, et de construire des entreprises viables.</p><h2>Kyutai × General Intuition : une alliance européenne pour les world models</h2><p>La discussion rebondit ensuite sur le thème des collaborations, avec l’annonce d’un partenariat entre Kyutai et General Intuition.</p><p>L’idée est la suivante :</p><ul><li>General Intuition doit rester très focalisé sur ses clients et usages concrets,</li><li>mais la construction des “fondations scientifiques” des world models mérite d’être menée dans un cadre de recherche ouverte.</li></ul><p>Kyutai apporte ce cadre : un laboratoire de recherche européen, indépendant, qui peut publier, partager, et faire vivre une communauté scientifique autour de ces briques fondamentales.
L’ambition : développer ensemble des blocs de base (architectures, méthodes de training, représentations) qui pourront être rendus publics, tout en laissant à General Intuition la capacité de les transformer en produits et plateformes.</p><h2>Un futur plus global et plus collaboratif</h2><p>En conclusion, Yann résume bien l’enjeu :
l’avenir de l’IA ne sera ni purement américain, ni purement chinois, ni monopolisé par quelques géants fermés.</p><p>Il sera :</p><ul><li>global,</li><li>multi-acteurs,</li><li>construit sur une alternance de recherche ouverte et de transferts technologiques.</li></ul><p>Et pour que cette vision fonctionne, il faut exactement ce qu’incarne ai-PULSE :
des laboratoires indépendants, des partenariats entre chercheurs et industriels, et une culture de l’open source suffisamment forte pour que les meilleures idées puissent naître partout dans le monde, pas seulement dans deux ou trois buildings sur la planète.</p><p><img src="/blog/images/articles/ia-pulse-2025/IMG_4026.jpg" alt="IMG_4026.jpg" /></p><h2>Message aux ingénieurs dans la salle</h2><p>Pour conclure, Xavier résume le message adressé aux développeurs et ingénieurs :</p><ul><li><p>Il est temps d’apprendre à comprendre le monde des pixels aussi bien que celui du code et du texte.</p></li><li><p>Les opportunités sont énormes du côté :</p><ul><li>des pipelines vidéo à grande échelle,</li><li>de l’infrastructure de données pour l’interaction,</li><li>des capteurs (robots, lunettes connectées, etc.),</li><li>des systèmes capables de planifier en imaginant les conséquences de leurs actions.</li></ul></li></ul><p>L’IA ne se limite plus à prédire le prochain token.
Elle commence à percevoir, simuler et agir dans le monde.</p><p>C’est cette transition des LLMs aux world models que Xavier met en lumière dans sa présentation, en s’appuyant sur les travaux de Yann LeCun et Pim de Witte : une nouvelle feuille de route pour l’IA, où l’Europe peut jouer un rôle central.</p><p>Voici un texte prêt à coller dans ton article, pour couvrir Jérôme Monceaux (Enchanted Tools) et le CEO de Scaleway.
Je garde le même ton que les sections précédentes : clair, tech, mais lisible.</p><h2>Jérôme Monceaux (Enchanted Tools) : des robots pensés pour les humains, pas pour les labos</h2><p>Après une démonstration de robot sur scène, la transition est toute trouvée : on accueille Jérôme Monceaux, CEO d’Enchanted Tools connu pour avoir fondé Aldebaran Robotics et participé à la création de robots sociaux iconiques aujourd’hui au musée.</p><p>Son nouveau projet, Enchanted Tools, mélange robotique, IA et design de personnages 3D pour créer des robots qui ressemblent moins à des machines industrielles et davantage à des “présences” dans notre quotidien.</p><h3>Des robots qui doivent “danser” avec leurs utilisateurs</h3><p>Jérôme explique qu’il travaille sur les robots depuis les années 90 et qu’il a beaucoup appris de leurs déploiements dans la vraie vie : la manière dont les gens réagissent, ce qu’ils attendent, ce qui les rassure… ou au contraire les bloque.</p><p>Quelques principes forts ressortent :</p><ul><li>Un robot doit être sûr et lisible dans ses mouvements.</li><li>L’environnement doit être designé avec le robot : ils conçoivent aussi des accessoires, du mobilier et des éléments au sol pour faciliter l’usage.</li><li>L’utilisateur est au centre : on ne peut pas “poser” un robot dans un hôpital ou un magasin et espérer que les gens comprennent spontanément comment l’utiliser.</li></ul><p>Jérôme parle d’une véritable “danse” entre le robot et l’utilisateur : gestes, regards, distance, timing… tout doit être pensé pour que l’interaction soit fluide et naturelle surtout quand les utilisateurs sont des enfants, des patients, des aides-soignants, des infirmières, qui n’ont pas du tout envie de devenir experts en robotique.</p><p>Côté techno, Enchanted Tools s’appuie notamment sur :</p><ul><li>des briques d’IA pour l’analyse de scène (vision, compréhension de l’environnement),</li><li>des modèles de comportement et de proximité pour gérer la sécurité,</li><li>des composants de machine learning embarqué pour adapter le comportement du robot au contexte.</li></ul><p>Environ 50 robots sont déjà déployés sur le terrain.</p><h3>Anticiper, pas seulement réagir</h3><p>Un point central de la vision de Jérôme :
un bon robot ne doit pas seulement réagir, il doit anticiper.</p><p>Exemples concrets :</p><ul><li>Quand un robot tend un objet à quelqu’un, à quel moment doit-il le lâcher ?</li><li>Comment interpréter un sourire, un recul, un regard hésitant ?</li><li>Comment adapter son comportement selon qu’il a en face de lui un enfant, un adulte, un soignant pressé ?</li></ul><p>Ces micro-détails sociaux, évidents pour un humain, sont très difficiles à modéliser.
Pourtant, si on veut des robots qui vivent dans nos espaces (hôpitaux, commerces, maisons de retraite), c’est là que tout se joue.</p><h3>Des robots pour les hôpitaux : impact réel, pas gadget</h3><p>Jérôme insiste sur un point : ses robots ne sont pas pensés pour des vidéos virales, mais pour améliorer des situations très concrètes, notamment à l’hôpital.</p><p>Pourquoi ce choix ?</p><ul><li>Parce que l’hôpital est un environnement où l’impact humain est énorme.</li><li>Parce que c’est un contexte semi-standardisé :
on connaît la nature du sol, la largeur des couloirs, la hauteur des portes, les règles de circulation, les contraintes de sécurité.</li></ul><p>Ce cadre permet de déployer des robots de manière fiable, en s’assurant qu’ils ne deviennent jamais un facteur de risque.</p><p>Il raconte notamment un projet dans un service de radiothérapie pour enfants :</p><ul><li>Les enfants doivent entrer seuls dans un bunker de radiothérapie.</li><li>Les parents et les médecins ne peuvent pas rester dans la pièce pendant la séance.</li><li>Beaucoup d’enfants vivent ce moment comme anxiogène, au point qu’il faut souvent les sédater pour que la séance soit possible.</li></ul><p>L’équipe médicale s’est rendu compte que ce qui manquait, c’était une présence dans la pièce.</p><p>Ils ont donc décidé d’introduire le robot d’Enchanted Tools dans le bunker, après validation des contraintes liées aux radiations.
Résultat :</p><ul><li>une séance qui durait 60 minutes dans la douleur se transforme en moment de jeu et de complicité avec le robot ;</li><li>les enfants ne sont souvent plus sédatés ;</li><li>la productivité de la machine augmente ;</li><li>et le bien-être des enfants, des parents et des soignants s’améliore.</li></ul><h3>Humanoïdes : utilité, joie et expérience de vie</h3><p>Pour Jérôme, un robot humanoïde n’est pas là pour remplacer les humains ni pour faire “juste” de la logistique.</p><p>Son objectif :</p><blockquote><p>Créer des expériences de vie dans les lieux où nous passons du temps :
magasins, hôpitaux, EHPAD, services pédiatriques…</p></blockquote><p>Les humanoïdes peuvent apporter :</p><ul><li>de l’utilité (aider, guider, assister),</li><li>de la joie (présence rassurante, ludique),</li><li>de l’harmonie (fluidifier les interactions plutôt que les compliquer).</li></ul><p>Ce n’est pas un robot de chaîne industrielle. C’est un robot pensé pour cohabiter avec nous, dans nos lieux de vie.</p><h2>Damien Lucas (Scaleway) : bâtir l’usine européenne de l’IA</h2><p>Après la robotique et les interactions physiques, place à l’infrastructure.
Le CEO de Scaleway, Damien Lucas, prend la parole pour parler de ce dont tous les builders IA ont besoin :
des plateformes et une infrastructure robuste.</p><h3>“Bring AI to the data” : l’infrastructure suit la vision</h3><p>Damien commence par rappeler un mantra posé lors d’une édition précédente :</p><blockquote><p>Il faut amener l’IA aux données, pas l’inverse.</p></blockquote><p>En 2025, cette phrase s’est traduite en vraie feuille de route :</p><ul><li><p>Scaleway a étendu sa présence au-delà de la France :
Pays-Bas, Pologne, et désormais Italie, Suède, bientôt l’Allemagne,
avec l’ensemble du portefeuille de produits disponible dans ces régions.</p></li><li><p>Côté données, Scaleway a enrichi son catalogue avec :</p><ul><li>Kafka, OpenSearch, Data Warehouse,</li><li>outils d’orchestration et de gestion de données…
pour permettre aux entreprises d’héberger et d’exploiter leurs données au plus près de leurs workloads IA.</li></ul></li></ul><h3>CPU, GPU, QPU : l’arsenal matériel européen</h3><p>Sur la partie compute, Damien déroule une stratégie en trois axes :</p><ol><li><p>CPU pour l’IA</p><ul><li>Nouvelle offre basée sur des CPU Ampere,</li><li>expérimentation autour de CPU Fujitsu,
pour des workloads IA plus sobres et mieux adaptés à certaines charges.</li></ul></li><li><p>Quantum computing</p><ul><li><p>Il rappelle qu’il y a deux ans, Scaleway a été parmi les premiers à proposer du quantum-as-a-service en mode émulation,
pour permettre aux chercheurs d’explorer des algorithmes quantiques avant l’arrivée du vrai hardware.</p></li><li><p>L’année suivante, arrivée de véritables QPU via un premier partenaire.</p></li><li><p>Cette année, annonce de nouveaux partenariats avec des acteurs quantiques européens utilisant des technologies différentes :</p><ul><li>systèmes à atomes neutres,</li><li>systèmes supraconducteurs.</li></ul></li><li><p>Intégration avec les frameworks open source du moment afin que les devs puissent tester ces backends sans friction.</p></li></ul><p>L’idée : devenir la plateforme de référence pour le quantique en Europe, en l’intégrant directement dans les workflows IA et d’optimisation.</p></li><li><p>GPU, encore et toujours</p><ul><li>Mise à disposition des toutes dernières générations de GPU NVIDIA sous forme de GPU Pods.</li><li>Intégration native de mesures de consommation énergétique dans ces pods, pour que les utilisateurs puissent quantifier l’impact énergétique réel de leurs workloads d’IA.</li></ul></li></ol><h3>Models-as-a-Service : utiliser l’IA sans gérer l’infra</h3><p>Damien sait que tout le monde ne veut pas gérer des clusters de GPU à la main.
Scaleway pousse donc une approche “Models as a Service” :</p><ul><li>une offre entreprise dédiée, avec des exigences élevées en matière de sécurité et d’isolation ;</li><li>une offre plus ouverte pour les développeurs, permettant d’appeler des modèles facilement pour du texte, de l’audio, etc.</li></ul><p>Dans ce cadre, Scaleway :</p><ul><li>héberge des modèles open weights de pointe,</li><li>a noué un partenariat avec Hugging Face pour exposer plus largement l’écosystème open source,</li><li>travaille avec des acteurs européens comme Mistral :
l’un de leurs modèles a été entraîné sur l’infrastructure Scaleway, et est désormais proposé en service managé.</li></ul><h3>Vers des “AI factories” européennes</h3><p>Damien conclut sur une ambition claire :</p><blockquote><p>Pour que l’Europe réussisse, il faut rêver plus grand.
Pas seulement héberger quelques modèles, mais construire de véritables usines de l’IA, des <em>AI factories</em> et <em>Giga factories</em>.</p></blockquote><p>Pour cela, Scaleway a :</p><ul><li>monté un consortium d’ingénieurs et d’experts issus de plusieurs entreprises et domaines critiques (hardware, énergie, réseaux, data, légal, souveraineté),</li><li>planifié des infrastructures capables de gérer des centaines de milliers de GPU à terme.</li></ul><p>L’idée n’est plus seulement d’être un fournisseur de cloud parmi d’autres, mais de devenir une pièce maîtresse de la capacité de calcul IA européenne, du CPU au GPU, du quantique aux modèles managés.</p><p>Voici un texte en français que tu peux intégrer tel quel dans ton article pour la partie voice AI / démo robot (Mochi).</p><h2>Voice AI en temps réel : la démonstration de Neil et de son “petit robot”</h2><p>Après avoir parlé de modèles de monde et de robots humanoïdes, la conférence bascule vers un autre élément clé de l’IA moderne : la voix.
Sur scène, on accueille Neil, chercheur qui a passé plusieurs années à repousser les limites des modèles audio, et qui vient tout juste de lancer sa nouvelle société de voice AI, née dans le prolongement des travaux de Kyutai.</p><h3>De la recherche ouverte à un produit industriel</h3><p>Neil commence par rappeler le contexte :
chez Kyutai, le travail consistait à faire de la recherche ouverte, à inventer de nouveaux systèmes de conversation speech-to-speech, et à open-sourcer les prototypes.</p><p>L’idée initiale était simple :</p><blockquote><p>on publie les briques fondamentales,
la communauté s’en empare
et construit des produits autour.</p></blockquote><p>Dans les faits, il s’est passé autre chose :</p><ul><li><p>le marché a montré énormément d’intérêt,</p></li><li><p>mais les prototypes restaient… des prototypes :</p><ul><li>latence encore trop élevée,</li><li>robustesse insuffisante,</li><li>qualité pas encore au niveau d’un produit grand public.</li></ul></li></ul><p>La nouvelle société de Neil est donc née de ce constat :
séparer clairement :</p><ul><li>la recherche fondamentale, qui reste ouverte et publiée ;</li><li>et le travail d’ingénierie produit, qui consiste à pousser les limites de la latence, de la qualité et de la robustesse pour rendre la voice AI réellement utilisable à grande échelle.</li></ul><p>Sa mission :</p><blockquote><p>transformer la recherche de Kyutai en modèles audio “industry grade”, intégrables dans des produits concrets.</p></blockquote><h3>Une équipe “full-stack audio” pour la voix de demain</h3><p>Neil décrit ensuite l’ADN de la société :</p><ul><li><p>une équipe composée d’anciens de Kyutai, de Google et d’autres grands acteurs,</p></li><li><p>des experts “full stack audio” :</p><ul><li>transcription,</li><li>synthèse,</li><li>traduction,</li><li>amélioration et transformation du signal.</li></ul></li></ul><p>Contrairement à beaucoup d’acteurs de la voice tech qui sont spécialisés soit en STT (speech-to-text), soit en TTS (text-to-speech), son équipe conçoit des modèles audio fondationnels qui couvrent la chaîne de bout en bout.</p><p>Leur thèse :</p><ul><li><p>la voix n’exploite aujourd’hui “même pas 1 %” de son potentiel comme interface homme–machine ;</p></li><li><p>la voice AI va servir aussi bien à parler aux machines qu’à médiatiser des interactions entre humains :</p><ul><li>traduction,</li><li>changement de voix,</li><li>personnalisation,</li><li>accessibilité, etc.</li></ul></li></ul><p>La société ne vise pas à lancer une seule app grand public, mais à fournir des briques utilisées par d’autres :
des entreprises qui veulent créer des agents vocaux, des expériences audio, des NPC parlants, du support client vocal, des contenus médias personnalisés, etc.</p><h3>Un premier produit : transcription + synthèse en temps réel</h3><p>À peine quelques mois après la création de la société, Neil annonce leur premier produit :</p><ul><li>transcription en temps réel,</li><li>synthèse vocale en temps réel,</li><li>exposées via une API.</li></ul><p>Concrètement, cela permet :</p><ul><li>de transformer n’importe quel agent textuel (un LLM déjà connecté à vos données) en agent vocal,</li><li>de changer la voix, l’accent, le style, sans toucher au cœur logique,</li><li>d’ouvrir un champ d’applications très large :</li></ul><p>Parmi leurs premiers clients, il cite :</p><ul><li>des studios de jeux vidéo (NPC parlants, commentateurs d’e-sport),</li><li>des services de customer support,</li><li>des groupes médias (contenus audio personnalisés),</li><li>des cas d’accessibilité (restauration ou augmentation de la voix pour des patients),</li><li>et même de la publicité digitale.</li></ul><p>L’idée :</p><blockquote><p>“On devient simplement le “wrapper vocal” d’un système IA qui existe déjà.”</p></blockquote><h3>La démo “Mochi” : un petit robot, plusieurs voix, plusieurs langues</h3><p>Pour montrer concrètement ce qu’ils ont construit, Neil amène sur scène un petit robot développé par leurs amis de 3DFace.</p><p>Sur le plan technique :</p><ul><li>le robot est connecté à leur API speech-to-text / text-to-speech,</li><li>reliée à un modèle de langage open source local,</li><li>le tout fonctionne en quasi temps réel.</li></ul><p>La démonstration parle d’elle-même :</p><ol><li>Le robot se présente avec une voix claire, naturelle, capable de moduler le ton, l’émotion et le style.</li><li>Neil lui demande de prendre la voix d’un “gym bro”, coach de musculation :
le robot répond avec une voix plus énergique, motivante, prête à “breaker des PR à la salle”.</li><li>Puis il lui demande de l’aider à apprendre à danser : le robot devient coach de danse, donne des consignes simples, encourage, compte le rythme.</li><li>Enfin, il lui demande de passer en accent québécois, en français, puis de reformuler en anglais :
le robot change de langue, d’accent et de registre, tout en gardant la même fluidité.</li></ol><p>À la fin, Neil lui pose une question plus conceptuelle :</p><blockquote><p><em>Comment la voice AI multilingue et multi-accents peut améliorer la communication entre humains et machines… et entre humains tout court ?</em></p></blockquote><p>Le robot répond que la voice AI permet :</p><ul><li>de casser les barrières linguistiques,</li><li>de faire discuter des personnes qui ne partagent pas la même langue comme si elles étaient dans la même pièce,</li><li>de rendre l’IA moins robotique, plus personnelle.</li></ul><h3>De l’open research au product-market fit</h3><p>Neil insiste sur un point intéressant pour tout l’écosystème :</p><ul><li>ce qu’ils annoncent sur scène n’est pas seulement une levée de fonds ou une création d’entreprise ;</li><li>c’est déjà un produit en production,</li><li>qui traite des centaines de milliers d’appels pour leurs clients.</li></ul><p>Comment ont-ils avancé aussi vite ?</p><ul><li>en réutilisant le momentum scientifique créé chez Kyutai,</li><li>en entraînant leurs propres modèles from scratch,</li><li>en construisant une nouvelle infrastructure adaptée à l’audio,</li><li>et en alignant très tôt la techno avec un besoin marché clair.</li></ul><p>Pour Neil, c’est un modèle à suivre :</p><blockquote><p>la recherche fondamentale reste ouverte et partagée,
elle fait émerger des idées et des briques technologiques,
puis des startups se créent pour pousser ces briques jusqu’au produit.</p></blockquote><p>Leur ambition est assumée :</p><blockquote><p>devenir un leader mondial de la voice AI.</p></blockquote><h3>Et après ? Les défis qui restent pour la voice AI</h3><p>Malgré la qualité de la démo, Neil rappelle que beaucoup reste à faire.</p><p>Quelques défis majeurs :</p><ul><li><p>Compréhension émotionnelle
Aujourd’hui, on a encore des IA qui répondent “Super !” quand on leur dit “Mon chien est mort”.
Comprendre le contexte émotionnel d’une phrase est indispensable, notamment pour :</p><ul><li>la thérapie assistée,</li><li>le support sensible,</li><li>les interactions longues et personnelles.</li></ul></li><li><p>Robustesse en environnement bruyant
La plupart des démos se font dans des environnements calmes.
Mais dans la vraie vie, une voice AI devra fonctionner :</p><ul><li>dans une usine,</li><li>dans un entrepôt,</li><li>dans un magasin plein de monde,</li><li>avec du vent, des bruits de fond, plusieurs personnes qui parlent.
Il faut alors savoir qui dit quoi, à quel moment, à quelle distance : un problème toujours largement ouvert.</li></ul></li><li><p>Intégration avec la robotique
Mettre de la voice AI dans des robots qui bougent, interagissent, comprennent à qui ils s’adressent et dans quelle langue, reste un frontier challenge.</p><h3>Conclusion : la voix comme couche naturelle de l’IA</h3></li></ul><p>Neil termine sur une note optimiste :
la voice AI n’est pas un gadget, c’est une couche naturelle de l’IA moderne.</p><ul><li>Elle rend les machines plus accessibles.</li><li>Elle permet de connecter des humains qui ne parlent pas la même langue.</li><li>Elle ouvre des usages nouveaux dans le jeu vidéo, les médias, la santé, la relation client, la robotique…</li></ul><p>Son message aux builders présents dans la salle :</p><blockquote><p>“Allez sur notre site, testez l’API, parlez-nous de vos cas d’usage et si vous êtes talentueux, rejoignez l’équipe.”</p></blockquote><h1>⚡ Master Stage : là où se dessine le futur de l’IA</h1><p>Les talks de l’après-midi suivent les trois axes de la conférence :
Smarter Faster Everywhere (plus Optimization &amp; Scalability).</p><h3>🔧 12:05 12:20 | Inference Everywhere</h3><p><em>Steeve Morin, ZML</em>
L’accent est mis sur les performances, l’optimisation et l’exécution d’IA “partout”. Les enjeux autour de l’inférence distribuée sont au cœur de la bataille pour le coût et la rapidité.</p><p>Voici un texte en français prêt à intégrer dans ton article pour la session “Inference-powered training / ZML”.</p><h2>Inference-powered training : quand les ingénieurs IA reprennent la main sur la prod</h2><p>La session “Inference-powered training” pose un constat simple mais souvent éludé :
l’entraînement et l’inférence sont deux mondes radicalement différents, et aujourd’hui c’est trop souvent l’entraînement (et donc Python) qui dicte les choix techniques jusque dans la production… au prix de nuits blanches pour les équipes infra.</p><h3>Entraînement vs inférence : même modèles, réalités opposées</h3><p>Le speaker commence par rappeler la différence :</p><ul><li><p>Entraînement (training)</p><ul><li>Terrain naturel de la recherche : on fait “une seule fois” un gros job.</li><li>On privilégie l’itération rapide : plus vite on teste une idée, mieux c’est.</li><li>On ne va pas chipoter sur l’overhead : l’important, c’est le résultat scientifique.</li><li>Python est parfait pour ça : flexible, expressif, une super DX.</li></ul></li><li><p>Inférence</p><ul><li><p>C’est la production, là où tout casse à 4h du matin.</p></li><li><p>On fait des milliards de requêtes.</p></li><li><p>On veut :</p><ul><li>une latence prévisible,</li><li>une variabilité faible (P99 plat),</li><li>un code compilé, typé, maîtrisé.</li></ul></li><li><p>Dans ce monde-là, “less is better” : chaque allocation, chaque branche compte.</p></li></ul></li></ul><p>Problème : dans la plupart des stacks actuelles, c’est le <em>monde training</em> qui gagne.
Tout est conçu autour de Python, de frameworks pensés pour expérimenter, pas pour faire tourner un service 24/7.</p><p>Résultat : les “AI laborers”, les ingénieurs back-end / MLOps qui doivent opérer ces systèmes, se retrouvent à bricoler autour de stacks pas faites pour eux :
ils se lèvent la nuit, recollent les morceaux, gèrent la dette.</p><h2>ZML : un framework pensé d’abord pour l’inférence</h2><p>Pour sortir de ce piège, l’équipe a créé ZML, un framework orienté inference-first.</p><p>Leur objectif : rendre l’inférence :</p><ul><li>agnostique du hardware (GPU NVIDIA, AMD, TPU, Trainium, etc.),</li><li>compilée de bout en bout,</li><li>prédictible en termes de latence,</li><li>intégrable facilement dans des environnements type Kubernetes.</li></ul><p>Sous le capot, ZML repose sur :</p><ul><li>Zig (Z) : un langage compilé, moderne, très proche du métal, mais beaucoup plus agréable que le C.</li><li>MLIR / XLA : pour la partie compilation et graphes de calcul.</li><li>Bazel : pour l’écosystème build et la reproductibilité.</li></ul><p>Avec le même code source, sans changer une ligne, ils peuvent cibler :</p><ul><li>des GPU NVIDIA,</li><li>des GPU AMD (ROCm),</li><li>des TPU,</li><li>du Trainium AWS, etc.</li></ul><p>Et ce sans compromis de performance : ce n’est pas “ça tourne… mais plus lentement”. L’ambition est de coller au plus près des perfs natives, en compilant le modèle “jusqu’au métal”.</p><p>Autres caractéristiques clefs :</p><ul><li>Tout est explicite : pas de compilation “magique” en lazy JIT qu’on découvre en prod.</li><li>Cross-compilation intégrée : développer sur un Mac, cibler Linux, builder une image optimisée sans y passer deux heures de Docker build.</li><li>Packaging et runtime inclus : CUDA / ROCm, libs nécessaires et sandbox sont embarqués dans une image minimale prête à être déployée.</li></ul><p>En résumé :</p><blockquote><p>tu construis <em>une</em> image spécialisée, tu la déploies, et “ça tourne”.
Pas de dance infinie autour des dépendances GPU dans les containers.</p></blockquote><h2>LLMD : un serveur LLM optimisé, prêt à l’emploi</h2><p>Sur cette base, l’équipe a développé un premier produit : LLMD, un serveur LLM construit entièrement au-dessus de ZML.</p><p>Caractéristiques annoncées :</p><ul><li>Distribué en image Docker (gratuite, mais pas open source).</li><li>Cold start 10x plus rapide qu’un serveur Llama.cpp classique : on parle de secondes, pas de minutes.</li><li>Image ~4x plus petite qu’une image Llama.cpp équivalente :
~2,4 Go, incluant CUDA + ROCm.</li><li>Time-to-first token environ 3x meilleur,</li><li>Throughput (tokens/sec) amélioré de 5 à 30 % selon la plateforme.</li></ul><p>Le tout sans tuning extrême pour l’instant : ils présentent ça comme un “point de départ” plus que comme une fin.</p><h2>Attention B : casser la complexité quadratique… depuis un CPU distant</h2><p>Autre brique clé : Attention B, une solution pour attaquer de front la complexité quadratique de l’attention.</p><p>Contexte :</p><ul><li><p>L’attention est le cœur des architectures modernes (transformers, LLMs).</p></li><li><p>Sa complexité quadratique est la raison pour laquelle :</p><ul><li>on parle de contextes limités,</li><li>on a besoin de mémoire HBM énorme sur GPU,</li><li>on invente des stratégies de RAG pour contourner le problème.</li></ul></li></ul><p>Avec Attention B, ils prennent une autre route :</p><ul><li>Au lieu de brute-forcer l’attention sur le GPU,</li><li>ils modélisent l’attention comme un graphe et la calculent sur CPU,</li><li>parfois même sur un CPU distant, joint via un réseau 10 Gbps.</li></ul><p>Le pipeline ressemble à ça :</p><ol><li>Extraction des données d’attention depuis le GPU.</li><li>Envoi sur le réseau vers un CPU distant.</li><li>Calcul de l’attention sur le CPU, avec un algorithme graphique plus parcimonieux.</li><li>Renvoi sur le GPU pour continuer le reste du calcul.</li></ol><p>Et malgré ce détour réseau, c’est plus rapide que le calcul local sur GPU, pour deux raisons :</p><ul><li>le CPU n’est pas “magiquement plus rapide”,</li><li>mais l’algorithme fait beaucoup moins de travail (graphe vs brute force).</li></ul><p>Conséquences :</p><ul><li>Le KV cache peut être stocké en mémoire système côté CPU :
→ jusqu’à 2x plus de capacité pour les contextes sans toucher au GPU.</li><li>Le GPU est délesté de 30 à 70 % de son temps passé en attention :
→ il peut se concentrer sur ce pour quoi il est vraiment bon (matmul, dense ops).</li><li>On n’a plus besoin d’un réseau HPC ultra-exotique :
→ 10 Gbps suffit (25 Gbps étant encore mieux),
→ pas besoin d’InfiniBand monstrueux ni de fabrics 800 Gbps.</li></ul><h2>Vers un écosystème inference-first</h2><p>La présentation se termine sur une idée forte :
l’équipe ne veut pas juste lancer un framework de plus, mais un écosystème inference-first :</p><ul><li>ZML open source pour structurer la stack,</li><li>des produits comme LLMD &amp; Attention B pour prouver que ça tient en prod,</li><li>et une approche globale où l’inférence n’est plus un “afterthought”,
mais un cas d’usage primordial autour duquel on conçoit les outils.</li></ul><p>L’objectif final :</p><blockquote><p>faire de l’IA un primitif fiable à intégrer dans des systèmes réels,
pas seulement un “quelque chose-AI” bricolé autour de notebooks Python.</p></blockquote><h3>🧠 12:25 12:55 | Agents that actually do the work</h3><p><em>BLACKBOX AI, SOCLE AI, AMD, Scaleway</em>
Le sujet central de 2025 : les agents autonomes. L’idée : ne plus simplement générer du texte ou des images, mais exécuter des tâches de bout en bout.</p><p>Voici un texte en français prêt à intégrer dans ton article pour la session
“Agents that actually do the work – how autonomy changes the way we build” (12h25).</p><h2>Agents qui font vraiment le travail : où ils brillent, où ils cassent, et ce qu’il reste à inventer</h2><p>Le panel réunit trois profils complémentaires :</p><ul><li>des builders d’agents pour les organisations où la fiabilité est critique (industrie, médical, conformité),</li><li>des builders d’agents pour le code, capables d’opérer sur des bases très complexes,</li><li>et un constructeur de puces qui conçoit le hardware sur lequel ces agents tournent, du datacenter jusqu’au rover sur Mars.</li></ul><p>L’objectif : comprendre où les agents apportent de la valeur, où ils échouent, et comment ils transforment la manière de construire des systèmes.</p><h3>Où les agents sont déjà utiles aujourd’hui</h3><p>Les intervenants listent plusieurs terrains où les agents ne sont plus de la science-fiction :</p><ul><li><p>Code &amp; développement logiciel</p><ul><li>agents qui lisent les logs de production en temps réel,</li><li>identifient une erreur,</li><li>patchent le code,</li><li>ouvrent une pull request, lancent les tests,</li><li>et, si l’équipe l’autorise, merge et déclenchent un nouveau déploiement, avec rollback possible.
On parle de “full self-coding”, déjà disponible publiquement.</li></ul></li><li><p>Industrie &amp; sécurité</p><ul><li>agents déployés sur des sites à risque (plateformes pétrolières, chantiers, etc.) qui analysent capteurs, alertes, caméras et signalent des situations dangereuses avant qu’elles ne dégénèrent.</li></ul></li><li><p>Médical &amp; monitoring</p><ul><li>systèmes qui suivent l’état de patients via des capteurs multiples et déclenchent des actions ou des alertes selon des seuils prédéfinis.</li></ul></li><li><p>Éducation personnalisée</p><ul><li>agents capables d’adapter le contenu, le rythme et la difficulté à l’attention réelle de l’élève, pas à un profil théorique.</li></ul></li><li><p>Transcription &amp; conformité légale</p><ul><li>exemple d’un cabinet d’avocats qui utilise un pipeline d’IA pour transcrire des auditions internes, mais avec un contrôle humain final obligatoire pour garantir une exactitude à 100 %, impossible à garantir avec l’IA seule.</li></ul></li></ul><h3>Agents autonomes, mais pas sans humains : l’importance du “human-in-the-loop”</h3><p>Tout le panel est d’accord sur un point clé :
à court et moyen terme, les humains restent dans la boucle.</p><ul><li><p>Dans la sécurité, l’éducation, le médical ou le code,
les agents proposent, mais ce sont les humains qui valident les décisions structurantes.</p></li><li><p>Dans les workflows de code avancés, l’agent peut :</p><ul><li>corriger un bug,</li><li>push une branche,</li><li>ouvrir une PR,</li><li>exécuter les tests,
mais c’est l’ingénieur qui décide (ou non) d’autoriser le merge automatique en production.</li></ul></li></ul><p>À long terme, certains imaginent des agents dépassant le niveau humain sur certains domaines, avec moins de validation manuelle. Mais aujourd’hui, confiance et UX imposent encore une supervision humaine.</p><h3>Les gros problèmes non résolus : monde physique, souveraineté, sécurité, UX</h3><p>Les intervenants pointent plusieurs verrous majeurs :</p><ol><li><p>Le monde physique est beaucoup plus dur que le texte</p><ul><li><p>un agent dans un hôpital, un drone ou un robot doit :</p><ul><li>percevoir (vision, son, capteurs),</li><li>raisonner en temps réel,</li><li>planifier une action,</li><li>exécuter,</li><li>apprendre de ses erreurs.</li></ul></li><li><p>c’est d’un ordre de complexité bien plus élevé que de traiter des tokens dans un LLM.</p></li></ul></li><li><p>Souveraineté &amp; conformité (surtout en Europe)</p><ul><li>beaucoup d’équipes pensent encore que souveraineté = moins de performance.</li><li>le panel insiste : c’est un faux dilemme.</li><li>le vrai sujet, c’est de construire des stacks performantes, mais souveraines et conformes (notamment pour la santé).</li></ul></li><li><p>Sécurité &amp; modèles fermés</p><ul><li>les entreprises sont tentées d’utiliser des modèles fermés très performants, au prix de la sécurité et de la maîtrise des données.</li><li>en parallèle, les modèles open source deviennent suffisamment bons pour justifier des architectures end-to-end chiffrées, où l’entreprise sait ce qui tourne, où, et comment.</li><li>un des intervenants mentionne la mise en place d’un agent entièrement chiffré de bout en bout : l’utilisateur sait qu’il utilise un modèle open source, et non un modèle fermé opaque.</li></ul></li><li><p>UX &amp; “prompting” comme facteur limitant</p><ul><li>la valeur extraite d’un agent dépend énormément de la capacité de l’utilisateur à bien le piloter.</li><li>si l’agent dépasse le niveau technique de l’utilisateur, ce dernier peut être incapable
d’évaluer si la réponse est bonne… alors même que l’agent a fait un travail excellent.</li><li>conclusion : les agents doivent être pensés UX-first, pas juste “API-first”.</li></ul></li></ol><h3>Hybrid AI : agents dans le cloud, sur Terre… et sur Mars</h3><p>La partie hardware rappelle que l’IA ne vit pas seulement dans un datacenter :</p><ul><li><p>AMD fournit des puces pour :</p><ul><li>des voitures (Subaru iSight, ultra faible latence),</li><li>des avions, des satellites,</li><li>le rover sur Mars,</li><li>des systèmes de détection ultra-rapide (comme au CERN) où l’on doit analyser des événements en nanosecondes.</li></ul></li></ul><p>Ces puces issues du rachat de Xilinx combinent :</p><ul><li>CPU embarqué,</li><li>accélérateurs IA,</li><li>logique programmable (FPGA).</li></ul><p>Cela permet un modèle hybride :</p><ul><li>Edge / Endpoint :
perception + décision critique en local, ultra faible latence, consommation minime.</li><li>Cloud :
raisonnement lourd, entraînement et ré-entraînement, agrégation de données.</li></ul><p>À terme, avec la progression des performances / watt, un smartphone ou un device edge pourra exécuter des capacités aujourd’hui réservées aux GPU de datacenter.</p><h3>L’agent, ce n’est pas juste un LLM avec des outils</h3><p>Le panel insiste : un agent, ce n’est pas simplement un LLM + quelques tools.</p><p>Il faut aussi :</p><ul><li><p>un protocole (MCP, architectures multi-agents, etc.),</p></li><li><p>une enveloppe d’exécution (container, VM, sandbox)
qui définit ce à quoi il a le droit d’accéder :</p><ul><li>commandes terminal,</li><li>fichiers,</li><li>secrets,</li><li>clients (navigateur, mobile, etc.),</li></ul></li><li><p>une sécurité zero-trust :
même à l’intérieur du firewall, personne n’est considéré comme “de confiance” par défaut.</p></li></ul><p>Pour le code, par exemple :</p><ul><li>les agents tournent dans des environnements isolés qui simulent au mieux la prod,</li><li>on leur donne accès à des clients réalistes (browser, app mobile) pour tester des scénarios complets,</li><li>l’environnement est presque aussi important que le modèle lui-même.</li></ul><h3>Mesurer, benchmarker, garder le contrôle</h3><p>Question clé : comment savoir si un agent fonctionne bien, alors que tout est plus “flou” que dans le ML classique ?</p><ul><li>Oui, il existe des benchmarks publics (SWE-Bench, SWE-Lancer en code, etc.) utiles comme repères.</li><li>Mais ils ne reflètent pas la complexité des systèmes réels.</li></ul><p>Les intervenants défendent une approche user-centric :</p><ul><li><p>définir des métriques liées au contexte d’usage réel,</p></li><li><p>suivre :</p><ul><li>les tâches effectivement accomplies,</li><li>les merges acceptés par les humains,</li><li>les corrections validées,</li></ul></li><li><p>construire des benchmarks internes, continus, plutôt que s’en remettre uniquement aux scores publics.</p></li></ul><h3>Coûts &amp; futur : où part l’argent, et comment en sortir</h3><p>Sur la question des coûts :</p><ul><li>aujourd’hui, le gouffre, ce sont les racks GPU, le réseau, la mémoire HBM – surtout avec les modèles de raisonnement qui génèrent énormément de tokens internes.</li><li>à chaque génération, le hardware devient plus performant… mais les modèles deviennent plus lourds.</li></ul><p>À long terme, une partie de la solution est claire :</p><ul><li><p>déplacer une grande part des workloads vers l’edge,</p></li><li><p>profiter du fait que les devices grand public rattrapent (et dépassent) d’anciennes générations de supercalculateurs,</p></li><li><p>concevoir les agents comme des containers légers, déplaçables, capables de vivre :</p><ul><li>dans le cloud,</li><li>sur un endpoint,</li><li>ou sur une machine locale.</li></ul></li></ul><h3>Garder les agents dans les clous : échecs courants et garde-fous</h3><p>Enfin, comment éviter qu’un agent ne parte en vrille :</p><ul><li><p>Limiter ses permissions :
décider explicitement à quoi il a accès (fichiers, secrets, commandes, API).</p></li><li><p>Mettre des garde-fous de supervision :</p><ul><li>notifications (Slack, SMS, appels vocaux automatiques) quand l’agent est bloqué,</li><li>demandes explicites de validation humaine pour certaines actions critiques.</li></ul></li><li><p>Donner de la visibilité aux utilisateurs :
dashboards, logs, explications pas à pas – pour que l’utilisateur puisse comprendre, rejouer, corriger.</p></li></ul><p>Le panel se termine sur cette idée :
les agents existent déjà dans les systèmes, sur l’edge, dans les usines, dans le code.
Mais leur succès dépendra moins de la magie des LLM que de la qualité des protocoles, de l’UX, de l’infra et des garde-fous que nous mettrons autour.</p><h3>⚡ 13:00 13:15 | Inside Photoroom’s Open-Source T2I Model</h3><p>Le behind-the-scenes d’un modèle texte-vers-image européen puissant et ouvert.</p><p>Voici un texte en français prêt à coller dans ton article pour la partie Photoroom / PRx.</p><h2>Photoroom : entraîner son propre modèle T2I… et l’ouvrir au monde</h2><p>Sur scène, Yoann Almazan et David Berthouin, research scientists chez Photoroom, viennent raconter quelque chose qu’on ne voit presque jamais : l’envers du décor des modèles de génération d’images.</p><p>On connaît tous la magie perçue de Stable Diffusion, Flux, Midjourney, DALL·E et consorts.
Mais rarement le coût réel :</p><ul><li>après 200 heures GPU, le modèle ne sait même pas reconnaître une forme,</li><li>après 1 000 heures, on obtient à peine quelque chose qui ressemble à une bouteille,</li><li>après 10 000 heures, ça commence à ressembler à une vraie bouteille de vin,</li><li>après 50 000 heures, on retrouve matières, reflets, détails.</li></ul><p>Autrement dit : c’est beau <em>à la fin</em>, mais c’est lent, douloureux, cher et fascinant à décortiquer.</p><h2>PRx : un modèle léger, open source, documenté de bout en bout</h2><p>Photoroom a décidé de faire un truc rare :</p><blockquote><p>entraîner son propre modèle texte→image from scratch,
le publier en open source,
et documenter tout le process, y compris ce qui n’a pas marché.</p></blockquote><p>Ce modèle s’appelle PRx :</p><ul><li><p>Taille : ~1,2 milliard de paramètres
(à comparer à Flux ~20B – on est clairement sur un modèle “lightweight”).</p></li><li><p>Licence : Apache 2.0, usage commercial permis.</p></li><li><p>Ressources :</p><ul><li>code,</li><li>expériences,</li><li>ablations,</li><li>résultats intermédiaires,
tout est public, y compris les essais ratés.</li></ul></li></ul><p>L’objectif :</p><ul><li><p>offrir un “playground sérieux” aux chercheurs, étudiants, équipes R&amp;D qui veulent :</p><ul><li>comprendre comment se construit un modèle de diffusion,</li><li>tester de nouvelles idées sans 10 000 GPU-jours,</li></ul></li><li><p>et disposer d’un modèle assez léger pour itérer vite, y compris sur des GPU de “simple mortel”.</p></li></ul><p>En interne, ce travail a eu plusieurs impacts :</p><ul><li>Compréhension profonde de la génération
→ meilleure maîtrise des modèles d’édition d’images et des features côté app.</li><li>Pipeline réutilisable
→ toutes les techniques validées sur PRx ont été réinjectées dans les modèles de production.</li><li>Communauté
→ un Discord très actif, qui n’existerait pas sans l’ouverture complète du projet.</li><li>Brand &amp; hiring
→ le projet rend visible un niveau de travail qui, sinon, serait resté enfoui dans des notebooks internes.</li></ul><h2>Rappel express : comment fonctionnent les modèles de diffusion</h2><p>Yoann prend 1 minute pour remettre tout le monde au même niveau.</p><ul><li><p>En génération</p><ul><li>on part d’un pur bruit,</li><li>étape par étape, le modèle apprend à retirer le bruit dans la “bonne direction” (par ex. “une bouteille de vin sur une table en bois”),</li><li>en ~20–50 pas, on obtient une image cohérente.</li></ul></li><li><p>En entraînement, c’est l’inverse :</p><ul><li><p>on part d’une vraie image,</p></li><li><p>on y ajoute progressivement du bruit,</p></li><li><p>on montre au modèle :</p><ul><li>l’image bruitée,</li><li>le texte associé,</li><li>la cible “propre”,</li></ul></li><li><p>et on lui demande de prédire l’image (ou le bruit) à chaque niveau de dégradation.</p></li></ul></li></ul><p>Intérêt :
on n’a pas besoin d’annotations complexes ; juste des paires (image, texte).
Problème :
il en faut des centaines de millions, voire des milliards.</p><h2>Accélérer avec un modèle léger : architecture + recette d’entraînement</h2><p>Avec PRx, l’équipe s’est fixé deux contraintes :</p><ol><li>Un modèle assez léger pour tourner sur des GPU accessibles.</li><li>Un entraînement le plus rapide possible, sans sacrifier la qualité.</li></ol><p>Deux leviers classiques en ML :</p><ul><li>Architecture :
analyser les modèles SOTA (Stable Diffusion, SDXL, etc.)
→ identifier les briques <em>vraiment</em> cruciales
→ les recombiner dans une architecture plus compacte.</li></ul><p>Résultat :</p><ul><li><p>PRx est ~60 % plus léger que certaines architectures récentes,</p></li><li><p>~40 % plus rapide à entraîner / inférer,</p></li><li><p>sans chute notable de qualité.</p></li><li><p>Recette d’entraînement :
intégrer les meilleures techniques récentes pour converger plus vite.
David en détaille une, simple à comprendre mais très efficace : la re-captionisation riche.</p></li></ul><h2>Ré-annoter tout le dataset pour apprendre <em>plus</em> avec les mêmes images</h2><p>Point de départ :
les datasets web (LAION &amp; co.) sont extrêmement hétérogènes.</p><ul><li><p>Ça contient :</p><ul><li>des photos sublimes,</li><li>des images de catalogue,</li><li>des crops bizarres,</li><li>des images moches avec bordures blanches,</li><li>etc.</li></ul></li></ul><p>Traditionnellement, beaucoup d’équipes :</p><ol><li>Entraînent sur tout le dataset,</li><li>Puis fine-tunent sur un sous-ensemble “propre” filtré par heuristiques.</li></ol><p>Problèmes :</p><ul><li>Difficile d’automatiser un filtrage parfait.</li><li>Le fine-tune sur un sous-ensemble peut faire “oublier” certains concepts appris au départ.</li></ul><p>Photoroom explore une autre voie :
au lieu de changer les images, on enrichit radicalement les légendes.</p><h3>Du “chat sur une chaise” à des descriptions ultra détaillées</h3><p>Exemple simple :</p><ul><li>Si on montre au modèle seulement des images légendées “un chat sur une chaise”,
il finit par apprendre grossièrement “qu’est-ce qu’un chat ?”.</li></ul><p>Mais si on légende :</p><ul><li>“un chat orange sur une chaise”,</li><li>“un chat blanc sur une chaise”,</li></ul><p>alors le modèle peut :</p><ul><li><p>désentrelacer les concepts :</p><ul><li>“chat” ≠ “orange” ≠ “blanc”,</li><li>“orange” devient un concept réutilisable ailleurs (orange car, orange sofa, etc.).</li></ul></li></ul><p>Photoroom pousse cette idée à l’extrême :</p><ul><li>ils passent tout leur dataset par des vision–language models SOTA,</li><li>ils demandent des descriptions très riches,</li><li>chaque image se voit dotée de dizaines de concepts explicites :
style, matière, couleur, lumière, contexte, etc.</li></ul><p>Un prompt initial du type :</p><blockquote><p><em>“tabby sleeping cat on a wheelchair”</em></p></blockquote><p>devient quelque chose comme :</p><blockquote><p><em>“a minimalist white wheelchair in a bright studio,
with a tabby sleeping cat curled on the seat, soft shadows, high-key lighting, etc.”</em></p></blockquote><p>Paradoxe intéressant :</p><blockquote><p>on rend les légendes plus complexes,
pour rendre l’apprentissage plus efficace,
avec exactement les mêmes images.</p></blockquote><p>Le modèle apprend plus de concepts, mieux séparés, pour un coût d’échantillon inchangé.</p><h2>Pourquoi c’est important pour l’écosystème</h2><p>Ce que montre Photoroom avec PRx, c’est qu’on peut :</p><ul><li><p>faire de la vraie recherche appliquée en T2I sans être une Big Tech,</p></li><li><p>outiller la communauté avec :</p><ul><li>un modèle léger,</li><li>une licence permissive,</li><li>des logs d’expériences et d’échecs,</li></ul></li><li><p>et prouver qu’une approche qualité de dataset + ingénierie d’architecture + transparence peut rivaliser sérieusement.</p></li></ul><p>Pour la communauté IA comme pour les builders produits, PRx est autant :</p><ul><li>un modèle utilisable,</li><li>qu’un cas d’étude vivant de ce que ça veut dire, concrètement, de former un modèle de génération d’images en 2025.</li></ul><h3>🌐 13:20 13:50 | From lab to product (Voice models)</h3><p>Kyutai + Indigo.ai expliquent comment transformer des modèles vocaux en produits industriels.</p><p>Voici un texte prêt à intégrer dans ton article pour la partie “From lab to product with European voice models” (Kyutai + Indigo AI).</p><h2>Des modèles de voix européens : de la recherche au produit</h2><p>Sur scène, deux mondes se rencontrent :</p><ul><li>Neil Zeghidour, chercheur en speech chez Kyutai (Moshi, modèles TTS, STT, traduction, etc.),</li><li>Enrico Bertino, co-fondateur d’Indigo AI, leader italien des assistants conversationnels en entreprise (avec, au passage, un BERT italien qui porte littéralement son nom : <em>Bertino</em>).</li></ul><p>Ensemble, ils posent un constat simple :
l’audio est l’interface la plus naturelle… et la plus compliquée à maîtriser.</p><h2>Pourquoi la voix est beaucoup plus dure que le texte</h2><p>Neil rappelle un ordre de grandeur qui calme tout le monde :</p><ul><li>1 heure de parole enregistrée ≈ 700 Mo d’audio brut,</li><li>la transcription texte de cette heure ≈ 50 000 fois moins d’information.</li></ul><p>Le texte est :</p><ul><li>compact,</li><li>structuré,</li><li>optimisé par des millénaires d’évolution culturelle pour transmettre de l’information.</li></ul><p>La voix, elle, est :</p><ul><li>massivement redondante,</li><li>extrêmement variable (accent, timbre, micro, bruit, émotion, contexte),</li><li>porteuse de signaux non verbaux : rythme, hésitations, sourire, colère, fatigue…</li></ul><p>Même phrase, mille façons de la prononcer mais un système doit toujours comprendre la même intention (“Quelle est la racine carrée de 9 ?”), que ce soit dans la montagne avec un vieux micro pourri ou sur scène à Paris avec un casque broadcast.</p><p>Enrico complète avec le point de vue produit :</p><ul><li><p>au début, ils pensaient : <em>“la voix, c’est juste un canal en plus pour nos chatbots”</em> ;</p></li><li><p>en pratique : c’est un autre monde :</p><ul><li>si tu rates un mot à l’oral, tu peux perdre le sens entier,</li><li>tu ne peux pas “relire” comme sur du texte,</li><li>il faut gérer le latency budget, les interruptions, le tour de parole, la prise de confiance.</li></ul></li></ul><h2>Évaluer la qualité : métriques objectives vs ressenti humain</h2><p>La voix transporte de l’émotion, et c’est précisément ce qui rend son évaluation toxique :</p><ul><li><p>côté “machine”, on peut mesurer :</p><ul><li>taux d’erreur de mots (WER),</li><li>taux de mots mal prononcés,</li><li>latence moyenne, etc.</li></ul></li><li><p>mais côté humain, tout peut être biaisé par :</p><ul><li>l’humeur du testeur,</li><li>la voix choisie,</li><li>un seul mot critique mal transcrit (date, montant, nom propre) qui ruine l’expérience.</li></ul></li></ul><p>Enrico raconte un cas client :</p><ul><li>version 1 : le client teste un voicebot, trouve la qualité “pas au niveau, pas prêt pour la prod”,</li><li>ils ne changent quasiment rien côté agent, seulement quelques paramètres de voix / rendu,</li><li>version 2 : <em>“parfait, on le met en prod demain”</em>.</li></ul><p>Même pipeline, même intelligence derrière seule la perception a changé.</p><p>D’où la nécessité de combiner :</p><ul><li>tests objectifs (métriques, benchmarks),</li><li>évaluations subjectives façon “clinical trial” : double-aveugle, anciens vs nouveaux modèles mélangés, large panel d’écoute, sans dire aux testeurs “c’est la nouvelle version”.</li></ul><h2>Deux grandes architectures : cascade vs speech-to-speech</h2><p>Aujourd’hui, deux architectures dominent.</p><h3>1. Architecture en cascade (ASR → LLM → TTS)</h3><p>Pipeline “classique” :</p><ol><li>ASR : conversion de la voix en texte (streaming).</li><li>LLM / agent : compréhension, raisonnement, appels d’API, RAG, outils métiers.</li><li>TTS : réponse vocalisée dans la voix cible.</li></ol><p>Avantages :</p><ul><li><p>parfait pour plugger de la voix sur un existant textuel :</p><ul><li>bots métiers, workflows d’API, systèmes bancaires / assurance, etc.</li></ul></li><li><p>facile d’ajouter :</p><ul><li>function calling,</li><li>RAG,</li><li>formats complexes (tableaux, chiffres, résumé structuré).</li></ul></li></ul><p>Limites :</p><ul><li><p>obligé de découper en tours de parole (turns) :
→ dès qu’on sort d’un dialogue propre, ça casse (interruptions, chevauchements, back-channels, etc.),</p></li><li><p>la latence peut vite dériver :</p><ul><li>attendre la fin perçue d’une phrase,</li><li>capturer les petits <em>“euh”</em>, <em>“oui, en fait”</em>,</li><li>envoyer au LLM,</li><li>attendre la réponse,
→ on fini parfois à plusieurs secondes de délai.</li></ul></li></ul><p>Enrico note que la cascade reste très adaptée aux cas :</p><ul><li><p>inbound service client :</p><ul><li>questions complexes,</li><li>appels d’API bancaires / assurance,</li><li>l’utilisateur s’attend à ce que ça prenne quelques secondes,</li><li>on peut “masquer” la latence avec des trucs UX (<em>“Je vérifie vos informations…”</em>).</li></ul></li></ul><h3>2. Architecture speech-to-speech native</h3><p>Ici, le modèle :</p><ul><li>prend directement l’audio en entrée,</li><li>génère directement de l’audio en sortie,</li><li>gère le dialogue sans découper en tours stricts.</li></ul><p>Forces :</p><ul><li>latence 200 ms possible, au niveau humain,</li><li>gestion naturelle des interruptions, des overlaps, des <em>“hmm”</em>, des <em>“oui”</em> pendant que l’agent parle,</li><li>expérience beaucoup plus fluide → ce qu’on a vu sur scène avec le robot <em>Richie Mini</em>.</li></ul><p>Faiblesses actuelles :</p><ul><li><p>difficile à brancher directement sur un existant LLM / API :</p><ul><li>il faut inventer des stratégies hybrides,</li><li>ou réentraîner des modèles plus complexes qui “parlent et pensent” à la fois,</li></ul></li><li><p>pour une grosse boîte qui a déjà investi des fortunes dans un LLM texte,
→ <em>“rajouter la voix”</em> devient un nouveau chantier complet : tests, perf, sécurité, conformité…</p></li></ul><p>Enrico souligne que le speech-to-speech brille surtout dans les cas outbound :</p><ul><li>c’est le bot qui appelle le client,</li><li>conversations rapides, multi-tours, beaucoup d’interruptions possibles,</li><li>l’agent pose des questions, l’humain répond vite,</li><li>la cascade devient fragile, là où le speech-to-speech reste fluide.</li></ul><h2>Agents hybrides : un “petit modèle vocal” piloté par un “grand cerveau”</h2><p>Chez Kyutai, Neil décrit une approche intéressante :</p><blockquote><p>un petit modèle speech-to-speech,
qui gère la conversation en temps réel,
et qui appelle ponctuellement un grand modèle (LLM / agent) lorsqu’il a besoin de réfléchir.</p></blockquote><p>En pratique :</p><ul><li><p>le petit modèle :</p><ul><li>comprend ce que dit l’utilisateur,</li><li>improvise, relance, rassure,</li><li>gère les silences, les <em>“attendez”</em>, les reformulations,</li></ul></li><li><p>quand il atteint une question “dure” (chiffres, logique, back-office, etc.),
→ il demande de l’aide au gros modèle (le fameux “joker”),</p></li><li><p>pendant que le LLM réfléchit, le modèle vocal peut continuer à parler :
<em>“Je regarde vos dernières opérations…”, “Je vérifie ça pour vous.”</em></p></li><li><p>dès que la réponse arrive, il la reformule en audio.</p></li></ul><p>Deux bénéfices majeurs :</p><ol><li><p>UX fluide par design (les “trucs UX” sont intégrés dans l’architecture).</p></li><li><p>Robustesse à la connectivité :</p><ul><li>le petit modèle peut tourner en local sur le device,</li><li>si la connexion tombe, la conversation continue,</li><li>seules les tâches “complexes” nécessitent un retour réseau.</li></ul></li></ol><p>Enrico, côté Indigo, appelle ça un “dummy agent” :</p><ul><li><p>un agent vocal qui sait :</p><ul><li>écouter,</li><li>reformuler,</li><li>rassurer,</li><li>gagner du temps,</li></ul></li><li><p>pendant que le gros cerveau (LLM + APIs + RAG) fait le boulot en arrière-plan.</p></li></ul><h2>Accents, diversité et équité d’accès</h2><p>Autre sujet : la fairness.</p><ul><li>Si tu parles “anglais CNN”, tout marche.</li><li>Si tu parles avec un fort accent, un dialecte ou un mélange de langues (cas suisse ou italien), beaucoup moins.</li></ul><p>Pour que les systèmes soient réellement inclusifs, il faut :</p><ul><li><p>des données d’entraînement issues de speakers très variés,</p></li><li><p>des annotateurs qui comprennent vraiment les accents / dialectes ciblés :</p><ul><li>même un Français natif peut peiner à transcrire correctement un Québécois,</li></ul></li><li><p>des modèles multilingues / multi-accents robustes.</p></li></ul><p>Enrico explique que :</p><ul><li>l’ASR est aujourd’hui la partie la plus délicate,</li><li>en Suisse par exemple, ils doivent gérer 4 langues dans le même flux,</li><li>la plupart des systèmes demandent de fixer la langue au début de la conversation,
→ les bascules en cours de route sont mal gérées.</li></ul><p>Pour le TTS, ils jouent au contraire avec les accents :</p><ul><li>en Italie, ils préférent des accents légers (Rome, Sicile…) plutôt qu’un italien totalement neutre,</li><li>ça rend le bot plus chaleureux, moins “voix robot de central téléphonique”.</li></ul><h2>Le vrai travail : contrôle, compliance et téléphonie</h2><p>Enrico distingue deux gros chantiers pour amener tout ça en production entreprise :</p><h3>1. Contrôle &amp; conformité</h3><p>Derrière la “simple” brique ASR → LLM → TTS, il faut :</p><ul><li>guardrails (ce que l’agent peut dire ou pas),</li><li>obfuscation / masking des données sensibles,</li><li>gestion de la vie privée (RGPD, stockage, droit d’accès, etc.),</li><li>monitoring et auditabilité des conversations,</li><li>latence maîtrisée malgré ces couches de contrôle.</li></ul><p>C’est un monde à part, qui demande :</p><ul><li>d’autres compétences,</li><li>d’autres outils,</li><li>une culture proche de la sécu / gouvernance.</li></ul><h3>2. La couche télécom, héritée des années 90</h3><p>Pour passer du chatbot web au voicebot téléphonique, Indigo a dû :</p><ul><li>plonger dans le monde SIP, PBX, PSTN, call centers,</li><li>gérer l’handover fluide vers un humain,</li><li>construire en interne une équipe dédiée téléphonie.</li></ul><p>La pile télécom n’a pas été pensée pour l’ère des LLM, et l’intégration est loin d’être triviale.</p><h2>Et maintenant ? Deux “big unlocks” pour l’Europe</h2><p>Pour conclure, les deux intervenants reviennent sur ce qui, selon eux, va débloquer la suite :</p><ol><li><p>Un écosystème européen durable</p><ul><li><p>On n’a ni Google, ni Meta, ni les mêmes VCs que la Silicon Valley.</p></li><li><p>Pourtant, en IA, l’Europe est bien partie (Kyutai, Mistral, pangea de labs, etc.).</p></li><li><p>Pour garder l’avance, il faut des modèles économiques soutenables :</p><ul><li>pas seulement des démos spectaculaires,</li><li>mais des entreprises qui tiennent dans la durée.</li></ul></li></ul></li><li><p>La latence côté humain, plus côté IA</p><ul><li>Aujourd’hui, la friction vient souvent de l’agent : latence perçue, coupures, étrangetés.</li><li>Avec des speech-to-speech à 200 ms, l’objectif est que le “bouchon” vienne du temps de réflexion humain, pas de la machine.</li></ul></li></ol><blockquote><p><em>“Le vrai tournant, ce sera quand la latence ressentie viendra de l’utilisateur, et non plus du système d’IA.”</em></p></blockquote><h3>📡 13:55 14:10 | Translation &amp; transformer limits</h3><p>Un talk de Translated sur les frontières actuelles des modèles autoregressifs.</p><p>Voici un texte prêt à mettre dans ton article pour la partie “Translation to Translation”.</p><h2>Vers le traducteur universel : quand la traduction devient un laboratoire d’AGI</h2><p>Pour Translated, la traduction n’est pas juste un service linguistique : c’est un terrain d’entraînement idéal pour l’intelligence artificielle générale.</p><p>L’intervenant pose le cadre dès le début :</p><ul><li>Toutes les espèces ont développé le contrôle moteur.</li><li>Mais aucune, à part l’humain, n’a développé un langage complexe.</li><li>C’est par le langage que l’on coopère, qu’on se projette dans le futur, qu’on aligne nos intentions.</li></ul><blockquote><p>« Certains pensent que le problème le plus important, c’est d’aller sur Mars.
Moi, je pense que le plus important, c’est qu’on se comprenne déjà sur Terre. »</p></blockquote><p>C’est ce problème-là que Translated attaque : comprendre toutes les langues, dans les deux sens, sans perte de sens.</p><h2>Mesurer le progrès : non pas en FLOPS, mais en secondes par mot</h2><p>Plutôt que de raisonner en “taille de modèle” ou “tokens vus”, Translated utilise un indicateur super concret :</p><blockquote><p>Combien de temps met un traducteur pro
pour corriger la traduction de la machine, mot par mot ?</p></blockquote><p>Ils mesurent :</p><ul><li>le temps de post-édition par mot,</li><li>année après année, sur des traducteurs professionnels.</li></ul><p>Résultat historique :</p><ul><li>de 2010 à 2023 : courbe quasi linéaire vers la “singularité humaine”,</li><li>cette singularité est fixée à 1 seconde par mot :
→ le moment où l’humain ne modifie plus rien, il ne fait que valider.</li></ul><p>Jusqu’il y a peu, la projection disait : on atteindra ça vers 2027.</p><p>Mais en mettant à jour la courbe avec 2024–2025, surprise :</p><ul><li>la courbe ralentit,</li><li>la droite “tout droit vers la singularité” se casse,</li><li>on se retrouve plutôt à l’horizon 2030–2032.</li></ul><p>Même ressenti côté utilisateurs :</p><ul><li>GPT-5 n’est pas un choc comme GPT-4,</li><li>5.1, Gemini 3 : ce sont des améliorations incrémentales, pas des ruptures.</li></ul><p>La question devient : jusqu’où peut-on aller avec l’approche actuelle, autoregressive, word-first ?</p><h2>La traduction : un “gym” brutal pour les modèles</h2><p>Pourquoi la traduction est un excellent test pour l’AGI ?</p><p>Parce que, contrairement à un chatbot générique :</p><ul><li><p>on n’a pas le droit d’halluciner :</p><ul><li>inventer une phrase ou un fait en trad est immédiatement visible,</li><li>la moindre hallucination fait rire… ou fait perdre un contrat.</li></ul></li><li><p>Il faut une cohérence fine :</p><ul><li>garder le sens,</li><li>respecter les contraintes (longueur, ton, terminologie),</li><li>ne pas “lisser” ou simplifier le contenu.</li></ul></li></ul><p>La traduction force le modèle à développer un véritable modèle du monde, pas seulement un modèle de texte.</p><h2>Quand les coûts d’entraînement explosent</h2><p>Historiquement, Translated entraînait ses modèles de bout en bout :</p><ol><li>Modèle de langue (LM).</li><li>Modèle de traduction spécialisé (MT).</li></ol><p>Timeline :</p><ul><li>modèles statistiques →</li><li>modèles neuronaux (vers 2010) →</li><li>Transformers →</li><li>gros LLM ouverts + fine-tuning.</li></ul><p>Le problème, ce sont les coûts d’entraînement :</p><ul><li>autrefois : 100 heures GPU pour un modèle,</li><li>puis : 1 000 heures (gros, mais gérable),</li><li>aujourd’hui : 5 millions d’heures GPU rien que pour du fine-tuning,</li><li>et ~20 millions d’heures pour un full pre-train… pour un modèle qui vivra 1 an.</li></ul><p>Conclusion :</p><blockquote><p>entraîner un modèle propriétaire complet n’a plus de sens économique à chaque génération.</p></blockquote><p>Translated s’est alors appuyé sur des LLM open-source comme base…
et c’est là qu’ils ont identifié trois gros angles morts.</p><h2>Trois limites structurelles des LLM actuels</h2><h3>1. Tokenisation cassée : la confusion commence à la première étape</h3><p>Aujourd’hui, la tokenisation (BPE, etc.) est un pré-process séparé du modèle :</p><ul><li>on découpe le texte en sous-unités (<em>“cas”</em>, <em>“ing”</em>, <em>“##ion”</em>, etc.),</li><li>puis seulement ensuite, on encode et on envoie dans le réseau.</li></ul><p>Problème :</p><ul><li><p>un même segment (ex : “cas”) peut correspondre à :</p><ul><li><em>“casa”</em> en italien,</li><li><em>case</em>, <em>casual</em>, <em>cascade</em>, etc.</li></ul></li><li><p>l’embedding initial devient ambigu dès l’entrée,</p></li><li><p>le transformer essaie de réparer cette ambiguïté, mais seulement jusqu’à un certain point.</p></li></ul><p>Idée de Translated pour le modèle Boops :</p><ul><li><p>apprendre la tokenisation avec le modèle, via backprop,</p></li><li><p>traiter en entrée non pas des “tokens BPE”, mais des bytes bruts,</p></li><li><p>et laisser le réseau découvrir lui-même :</p><ul><li>comment segmenter le texte,</li><li>et, à terme, comment intégrer aussi images, vidéo, signaux multimodaux.</li></ul></li></ul><p>Autrement dit :</p><blockquote><p><em>“On ne veut plus de pré-processing opaque. On veut un cerveau qui apprend lui-même à lire ses sens.”</em></p></blockquote><h3>2. Raisonnement en parallèle, dans l’espace latent</h3><p>Aujourd’hui, le raisonnement des LLM, c’est :</p><ul><li>autoregressif,</li><li>token après token,</li><li>avec parfois des chaînes de pensée réinjectées dans le prompt.</li></ul><p>Mais tout se fait dans le flux de texte, ce qui impose des limitations étranges.</p><p>Exemple simple (en italien) :</p><blockquote><p>“Tre parole importanti : non sei solo.”</p></blockquote><p>Traduction naïve en anglais :</p><blockquote><p>“Three important words : you are not alone.”</p></blockquote><p>Problème :</p><ul><li><p>“you / are / not / alone” = 4 mots,</p></li><li><p>donc la traduction correcte serait plutôt :</p><blockquote><p>“Four important words: you are not alone.”</p></blockquote></li></ul><p>Aucun modèle actuel ne gère ça proprement, car il doit :</p><ul><li>compter les mots,</li><li>décoder en même temps,</li><li>dans un flux où tout est mélangé.</li></ul><p>Le cerveau humain, lui, fait différemment :</p><ul><li>plusieurs zones traitent en parallèle (vision, langage, logique…),</li><li>la “functional connectivity” permet de raisonner avant de parler,</li><li>puis seulement ensuite on produit une sortie.</li></ul><p>Objectif de Boops :</p><ul><li><p>déplacer le raisonnement dans un espace latent interne,</p></li><li><p>laisser le modèle :</p><ul><li>manipuler des représentations abstraites,</li><li>vérifier des contraintes (compter, aligner, contrôler),</li><li>avant de générer le texte final.</li></ul></li></ul><h3>3. Apprendre pendant l’inférence : de l’expérience, pas seulement des données passées</h3><p>Dernière limite :</p><blockquote><p>On ne dépassera jamais l’intelligence humaine cumulée si l’on se contente de recycler des données humaines passées.</p></blockquote><p>Les humains apprennent :</p><ul><li><p>un peu par supervision (livres, cours, corrigés),</p></li><li><p>beaucoup par expérience directe :</p><ul><li>essayer, rater, recommencer,</li><li>sans qu’un “oracle” explicite donne une récompense numérique,</li><li>en se donnant soi-même des objectifs, des valeurs, une forme d’agence.</li></ul></li></ul><p>Translated a déjà exploré ce principe en 2017 :</p><ul><li><p>en traduction, ils ont laissé le système apprendre en continu à partir :</p><ul><li>des corrections de traducteurs,</li><li>du temps de post-édition,</li><li>du comportement réel en production.</li></ul></li><li><p>ce retour d’expérience a significativement amélioré le modèle,</p></li><li><p>au point de contribuer à faire de Translated une entreprise proche des 100 M$ de revenus.</p></li></ul><p>L’ambition maintenant :</p><ul><li><p>généraliser cette approche au-delà de la traduction,</p></li><li><p>créer des modèles qui apprennent pendant qu’ils infèrent :</p><ul><li>ils décomposent les tâches,</li><li>estiment eux-mêmes la qualité / valeur de ce qu’ils font,</li><li>se ré-entraînent localement, sur la base de leur propre expérience.</li></ul></li></ul><h2>Boops : un modèle européen, ouvert, orienté recherche longue</h2><p>Pour pousser ces idées, Translated a obtenu :</p><ul><li>30 M€ de financement de recherche européen,</li><li>~100 M€ d’équivalent compute en crédits GPU.</li></ul><p>Feuille de route annoncée :</p><ul><li><p>2026 : première version de Boops</p><ul><li><p>open-weights, open-source,</p></li><li><p>~10B de paramètres,</p></li><li><p>entraînée pour explorer :</p><ul><li>la tokenisation apprise,</li><li>le raisonnement latent,</li><li>l’apprentissage en ligne.</li></ul></li></ul></li><li><p>2027 : version ~27B.</p></li><li><p>2028 : version finale intégrant l’ensemble des briques.</p></li></ul><p>Le tout hébergé en priorité sur les infrastructures européennes (Scaleway &amp; co.), puis ouvert au reste de l’écosystème.</p><h2>Un traducteur qui explique ses choix</h2><p>En parallèle de la recherche “heavy”, Translated propose déjà un outil grand public :</p><ul><li><p>laratranslate.com</p><ul><li>traduction de haute qualité,</li><li>et surtout :
→ la possibilité de demander au système pourquoi il a choisi tel mot plutôt qu’un autre.</li></ul></li></ul><p>Ce n’est plus juste “voilà la traduction” :</p><ul><li>le modèle expose ses critères terminologiques,</li><li>justifie ses choix de style ou de vocabulaire.</li></ul><p>Pour la suite, Translated coordonne un consortium d’environ 70 chercheurs (Oxford, EPFL, ETH, etc.) autour de ces questions.</p><blockquote><p><em>“Si l’un de ces sujets de recherche te parle, viens nous voir.”</em></p></blockquote><h3>📊 14:15 14:45 | Benchmarking the frontier</h3><p>Une nouvelle façon d’évaluer l’« AI stack » moderne : hardware, modèle, pipeline, inference.</p><p>Voici un résumé structuré et prêt à intégrer dans ton article pour la conf “AI Benchmarking” (Micah Hill-Smith – Artificial Analysis).</p><h1>📊 Benchmarking de l’IA : mesurer vraiment ce que valent les modèles</h1><p>Micah Hill-Smith, co-fondateur et CEO d’Artificial Analysis, présente comment son équipe mesure et compare les modèles d’IA, les infrastructures et les puces. Leur promesse : donner aux builders des données indépendantes pour choisir les bons modèles, au bon prix, pour les bonnes applis.</p><h2>👥 Qui est Artificial Analysis ?</h2><ul><li><p>Site : artificialanalysis.ai</p></li><li><p>Rôle : tiers de confiance pour :</p><ul><li>mesurer l’intelligence des modèles (LLM, image, audio, vidéo),</li><li>évaluer latence, coût, efficacité, tokens utilisés,</li><li>comparer labs, clouds, chips.</li></ul></li><li><p>Clients : labs de haut niveau + entreprises qui construisent des produits IA.</p></li><li><p>Outils : un Intelligence Index (score synthétique) et des datasets/évals custom pour les besoins spécifiques.</p></li></ul><h2>📈 Où en sont les LLM aujourd’hui ?</h2><p>Ils affichent une courbe d’évolution de leur Intelligence Index depuis GPT-3.5 :</p><ul><li><p>Période “OpenAI dominé tout” après GPT-4.</p></li><li><p>Puis arrivée des reasoning models fin 2024 → gros saut de performance sur les benchmarks de raisonnement.</p></li><li><p>En 2025, les trois “frontier labs” sont au coude à coude : OpenAI, Anthropic, Google (et XAI en embuscade).</p></li><li><p>Sur les use cases concrets (notamment le code) :</p><blockquote><p>il y a un an, les agents de code faisaient peu de choses utiles.
aujourd’hui, ils fonctionnent vraiment.</p></blockquote></li></ul><p>Même si GPT-5 n’a pas “senti” comme une révolution pour tout le monde, si on zoome à l’échelle 2,5 ans, le saut est gigantesque.</p><h2>🧱 La stack IA vue par Artificial Analysis</h2><p>Micah découpe l’écosystème en 4 couches :</p><ol><li><p>Applications
– ChatGPT, copilots, produits B2B, apps finales.</p></li><li><p>Modèles de fondation
– GPT-5, Mistral Large, Qwen, etc.</p></li><li><p>Cloud d’inférence / APIs
– Endpoints que les devs appellent (OpenAI, Anthropic, Groq, etc.).</p></li><li><p>Matériel / Accélérateurs
– GPUs (NVIDIA), TPUs (Google), autres chips spécialisés.</p></li></ol><p>Google est l’acteur le plus intégré verticalement (du chip aux apps). Les autres adoptent des stratégies plus partielles.</p><h2>💸 IA : en même temps beaucoup moins chère… et beaucoup plus chère</h2><p>Micah pose un paradoxe :</p><blockquote><p>“L’IA est devenue 100× moins chère… mais vos requêtes coûtent souvent 10× plus qu’avant.”</p></blockquote><h3>1. Pourquoi c’est moins cher pour un niveau donné d’intelligence ?</h3><p>Pour un “niveau GPT-4” par exemple :</p><ul><li>Modèles plus petits + sparsité → moins de paramètres activés à chaque requête.</li><li>Optimisations logicielles d’inférence.</li><li>Nouveaux hardwares plus efficaces (nouvelles générations de GPU/TPU).</li><li>Résultat : le coût pour produire un token de qualité GPT-4 a chuté d’environ ×100.</li></ul><h3>2. Pourquoi vos requêtes coûtent plus cher au final ?</h3><p>Parce qu’on fait faire beaucoup plus de choses au modèle :</p><ul><li><p>Modèles plus gros au sommet (certains dépasseraient GPT-4 en taille).</p></li><li><p>Reasoning models → ils “pensent” avec des milliers de tokens avant de répondre.</p></li><li><p>Agents IA :</p><ul><li>chain-of-thought sur plusieurs appels,</li><li>recherche web, RAG, outils,</li><li>agents de code qui modifient des fichiers, exécutent du code, relancent des tests, etc.</li></ul></li></ul><p>Donc :
🧠 <em>Intelligence par dollar</em> augmente.
💶 <em>Coût par requête utile</em> explose si tu laisses l’agent travailler longtemps.</p><h2>🧠 Reasoning models &amp; efficacité en tokens</h2><p>Avant, la distinction était simple :</p><ul><li>modèles “normaux” vs</li><li>reasoning models (avec trace de réflexion explicite, beaucoup plus de tokens internes).</li></ul><p>Maintenant, c’est plus flou :</p><ul><li>Certains modèles sans “mode reasoning” parlent beaucoup et font quand même beaucoup de raisonnement implicite.</li><li>Certains reasoning models récents sont beaucoup plus efficaces en tokens.</li></ul><p>Artificial Analysis parle désormais plutôt de :</p><blockquote><p>token efficiency = nombre de tokens utilisés pour atteindre un certain niveau d’intelligence.</p></blockquote><p>En pratique, pour un builder, il faut regarder :</p><ul><li>pas seulement <em>“raisoning on/off”</em>,</li><li>mais combien de tokens le modèle consomme pour ton type d’usage (latence + facture).</li></ul><h2>🟦 Open weights vs modèles propriétaires</h2><p>Ils comparent la meilleure perf open-weights et la meilleure perf propriétaire :</p><ul><li>Le <em>gap</em> entre les deux reste réel…</li><li>… mais le fait marquant est que les modèles open-weights suivent le rythme de près.</li></ul><p>Top open-weights actuels (selon eux) :</p><ul><li>Beaucoup viennent de Chine (DeepSeek V3.2, Minimax M2, Qwen 3, etc.).</li><li>OpenAI a aussi sorti GPT-OSS (open-weights).</li><li>Côté Europe : Mistral Small / Medium occupent une très bonne place, surtout en multimodal petit modèle.</li></ul><p>Point important sur Mistral Large 3 :</p><ul><li>Le modèle évalué est un instruct, pas encore un reasoning RLHF complet → il est plus token-efficient mais n’écrase pas Medium 1.2 sur leurs indices de reasoning.</li><li>Une future version reasoning pourrait logiquement le placer au-dessus.</li></ul><h2>🧪 Nouveaux types de benchmarks : connaissance &amp; hallucinations</h2><p>Ils ont construit des évals spécifiques pour mesurer :</p><ol><li><p>Connaissances factuelles
– questions fermées où il y a une bonne réponse clairement définie.</p></li><li><p>Comportement face à l’incertitude
– quand le modèle ne sait pas, est-ce qu’il :</p><ul><li>dit “je ne sais pas / je ne suis pas sûr”, ou</li><li>invente une réponse fausse avec confiance ?</li></ul></li></ol><p>Ils mesurent donc :</p><ul><li>Accuracy (pourcentage de bonnes réponses).</li><li>Taux de “hallucinations” : proportion de cas où le modèle répond faux alors qu’il aurait dû reconnaître qu’il ne savait pas.</li></ul><p>Observation notable :
les modèles d’Anthropic (Claude) sont très puissants, mais parfois mal calibrés sur “je ne sais pas” vs “je tente ma chance”.</p><h2>🧬 L’“Openness Index” : à quel point un modèle est vraiment ouvert ?</h2><p>Ils présentent aussi un Openness Index, un score pour mesurer à quel point un modèle est réellement “open” :</p><ul><li><p>Pas seulement : est-ce que les poids sont disponibles ?</p></li><li><p>Mais aussi :</p><ul><li><p>quelles sont les conditions de licence ?</p></li><li><p>a-t-on accès à :</p><ul><li>la recette d’entraînement,</li><li>la composition du dataset (au moins en grandes lignes),</li><li>les scripts / configs ?</li></ul></li></ul></li><li><p>Un score parfait signifierait :</p><blockquote><p>“On peut recréer le modèle depuis zéro en suivant la doc publique.”</p></blockquote></li></ul><p>Mistral obtient un des meilleurs scores actuels parmi les LLM propriétaires/open-weights “sérieux”.</p><h2>🖼️ Au-delà du texte : image &amp; vidéo</h2><p>Micah termine sur un point important : le monde ne se résume pas aux LLM texte.</p><p>Artificial Analysis benchmarke aussi :</p><ul><li>Génération d’images (diffusion, LLM visuels),</li><li>Génération vidéo (surtout image→vidéo),</li><li>Modèles audio / speech.</li></ul><p>Ils utilisent notamment des “preference arenas” :
des interfaces où des humains comparent deux sorties et choisissent celle qu’ils préfèrent → ce qui permet d’évaluer des dimensions comme :</p><ul><li>qualité visuelle,</li><li>cohérence,</li><li>utilité perçue.</li></ul><h3>✈️ 14:50 15:05 | The first AI flying a fighter jet</h3><p>Helsing montre que l’Europe avance aussi sur les usages sensibles.</p><p>Voici un texte clair, structuré et prêt à être intégré dans ton article, qui résume parfaitement la conférence <em>Flight – L’IA qui pilote un avion de chasse</em>.</p><h1>🚀 Flight : Quand une IA devient copilote de combat</h1><h3>L’histoire de la première IA à piloter un avion de chasse opérationnel</h3><p>La scène s’ouvre sur une vidéo impressionnante : un avion de chasse en vol, manœuvré non pas par un pilote humain, mais par une IA embarquée. Le chercheur de Helsing raconte comment ils ont construit Centaur, le premier copilote d’IA capable de mener un combat aérien moderne.</p><p>Et pour comprendre pourquoi c’est une révolution, il faut d’abord déconstruire un mythe…</p><h2>🛩️ Le combat aérien moderne n’a plus rien à voir avec <em>Top Gun</em></h2><p>L’imaginaire collectif pense encore aux <em>dogfights</em> :</p><ul><li>deux avions qui se tournent autour,</li><li>les pilotes qui s’observent à vue,</li><li>l’affrontement physique et instinctif.</li></ul><p>La réalité 2025 ? Rien de tout ça.</p><p>Le combat n’est plus visuel. Il est :</p><ul><li>à 10 000 m d’altitude,</li><li>à des centaines de kilomètres de distance,</li><li>entièrement piloté par des radars, capteurs, écrans,</li><li>100 % dans l'information et la prise de décision.</li></ul><blockquote><p>C’est un jeu d’échecs 3D à grande vitesse, en pleine tempête.
Celui qui gagne est celui qui traite l’information le plus vite.</p></blockquote><p>Et c’est précisément là que l’IA excelle.</p><h2>⚠️ Pourquoi l’armée a besoin d’IA maintenant</h2><p>Trois facteurs rendent l’IA indispensable dans les systèmes de défense :</p><h3>1. La vitesse</h3><p>Les menaces modernes évoluent à la seconde. Un humain ne peut plus suivre.</p><h3>2. La surcharge cognitive</h3><p>Un pilote doit :</p><ul><li>gérer radars, missiles, alliés, météo, trajectoires,</li><li>analyser des téraoctets d'information,</li><li>prendre des décisions vitales en quelques instants.</li></ul><p>C’est <em>trop</em> pour un cerveau humain.</p><h3>3. La maturité de l’IA</h3><p>On sort du buzzword : les agents sont maintenant
→ fiables,
→ réactifs,
→ capables d’exécuter des stratégies complexes.</p><p>Même le ministère de la Défense du Royaume-Uni l’a déclaré :</p><blockquote><p><em>« Nos adversaires doivent savoir que nous innovons à un rythme de temps de guerre. »</em></p></blockquote><h2>🎯 Centaur : le copilote IA pour les engagements BVR</h2><p><em>(Beyond Visual Range)</em></p><p>C’est le cœur du problème : les combats BVR, ceux où on ne voit jamais l’ennemi.</p><p>L’environnement BVR, c'est :</p><ul><li>information partielle,</li><li>incertitude totale,</li><li>anticipation, bluff, estimation,</li><li>décisions sous stress et sous 9G.</li></ul><p>C’est littéralement un mélange de :</p><p>🧠 Échecs → planification long terme
🎲 Poker → incertitude, bluff, probabilités</p><p>Et l’IA parfaite pour ça ?
→ Un agent de Reinforcement Learning.</p><h2>🤖 Le rôle de Centaur dans le cockpit</h2><p>Centaur reçoit en entrée :</p><ul><li>objectif de mission,</li><li>commandes humaines,</li><li>données capteurs (radar, instruments de vol…),</li><li>informations provenant d’autres avions.</li></ul><p>Et en sortie, il produit :</p><ol><li><p>Commandes de guidage
(orientation, trajectoire, gestion des distances)</p></li><li><p>Recommandations tactiques
(quand tirer, quand manœuvrer, quand éviter)</p></li><li><p>Communication d’intention
→ vers le pilote humain
→ vers les alliés</p></li></ol><p>C’est un véritable copilote doté d’une vision tactique parfaite.</p><h2>🧪 L’ingrédient secret : un simulateur IA-first</h2><p>Les simulateurs traditionnels sont :</p><ul><li>très fidèles graphiquement,</li><li>conçus pour entraîner des pilotes humains.</li></ul><p>Mais pour du RL, il faut :</p><ul><li>des milliards d’expériences,</li><li>de la vitesse (x100, x1000),</li><li>de la variabilité.</li></ul><p>Helsing a donc construit un simulateur propriétaire, capable de :</p><ul><li>s’exécuter des milliers de fois en parallèle,</li><li>tourner bien plus vite que le temps réel,</li><li>modifier aléatoirement les conditions de vol, la météo, les capteurs…</li></ul><p>L’IA peut ainsi vivre des décennies d’expérience en quelques jours.</p><h2>🧬 L’apprentissage : de zéro à expert</h2><p>L’agent RL :</p><ul><li>ne connaît rien,</li><li>joue contre lui-même,</li><li>teste, échoue, corrige, recommence,</li><li>explore toutes les tactiques possibles.</li></ul><p>Résultat :</p><blockquote><p>Sans jamais voir une stratégie humaine,
il invente ses propres tactiques.</p></blockquote><p>Tactiques émergentes observées :</p><ul><li>feintes de missile,</li><li>gestion d’altitude pour éviter les radars,</li><li>conservation de munitions,</li><li>manœuvres anticipées selon les probabilités ennemies.</li></ul><p>Le tout avec une performance superhumaine.</p><h2>🛫 Du simulateur au vrai jet : mission Gripen</h2><p>Mettre une IA au commande d’un avion réel exige trois choses :</p><h3>1. Robustesse aux incertitudes</h3><p>On ne connaît jamais exactement :</p><ul><li>l’aérodynamique réelle,</li><li>le traitement radar exact,</li><li>les latences du matériel.</li></ul><p>Donc l’IA est entraînée dans un environnement
→ plein de bruit,
→ de paramètres aléatoires,
→ de variations extrêmes.</p><h3>2. Une architecture avion adaptée</h3><p>Le Saab Gripen offre :</p><ul><li>séparation stricte entre commandes critiques et tactiques,</li><li>guidage de bas niveau ultra-fiable,</li><li>compute embarqué suffisant.</li></ul><p>Le pilote humain reste au cœur du système.
L’IA ne touche pas aux commandes vitales directes.
Elle gère la stratégie.</p><h3>3. Des boucles de contrôle ultra-stables</h3><p>Pour que l’IA puisse se concentrer sur les décisions haut niveau.</p><h2>✈️ La première démonstration en vol réel</h2><p>L’été dernier, en Suède, Helsing et Saab ont réalisé un test décisif :</p><ul><li>un avion Gripen équipé de Centaur,</li><li>un autre avion piloté par un humain en face,</li><li>environnement réel, menaces réelles, données réelles.</li></ul><p>Pendant le vol, l’IA :</p><ul><li>détecte l’adversaire,</li><li>met à jour sa stratégie,</li><li>manœuvre en anticipant les mouvements ennemis,</li><li>optimise sa position BVR en continu.</li></ul><blockquote><p>Une IA, dans un avion réel, en train de mener un combat aérien moderne.</p></blockquote><p>C’est une première.</p><h2>🧭 Pourquoi c’est plus qu’un autopilote</h2><p>Helsing le répète :</p><blockquote><p>Ce n’est pas un meilleur autopilote.
C’est un grand maître des échecs intégré dans un cockpit.</p></blockquote><p>L’objectif n’est pas de remplacer le pilote.
C’est de lui donner un avantage décisif dans les situations les plus critiques.</p><blockquote><p>Une IA capable d’innover à un rythme de temps de guerre.</p></blockquote><h2>🔥 Conclusion</h2><p>Centaur représente :</p><ul><li>la première IA réellement opérationnelle dans un avion de chasse,</li><li>une démonstration du potentiel du RL pour des décisions en temps réel,</li><li>une avancée stratégique majeure pour les démocraties occidentales.</li></ul><p>Et Helsing recrute.
Beaucoup.</p><h3>🌱 15:10 15:40 | Transparency &amp; AI Carbon Footprint</h3><p>Scaleway + Salesforce explorent le sujet crucial de la sobriété et de la transparence énergétique.</p><h3>⚙️ 15:45 16:00 | Building AI that scales (Ampere)</h3><p>Le futur du compute : CPU ARM, efficacité énergétique, IA pervasives.</p><h3>🤖 16:05 16:25 | From Foundation Models to Real-World Actions</h3><p>Scaleway + Enchanted Tools : comment passer du modèle à l’action physique (robotique).</p><h3>⚡ 16:30 16:50 | Building at the speed of agents</h3><p>VAST Data, Semianalysis et H Company discutent pipelines, data infra, entraînement.</p><h3>🚀 16:55 17:10 | From single agents to agent fleets</h3><p>Dust explore comment piloter des flottes d’agents, pas juste un agent isolé.</p><h3>🔐 17:35 17:55 | AI &amp; Privacy</h3><p>Proton donne une vision forte d’une IA privée et chiffrée essentielle pour l’Europe.</p><h1>📡 Central Room : hardware, pharma, multimodalité, créativité et MCP</h1><h3>14:20 14:50 | Beyond Air Cooling</h3><p>L’avenir du hardware IA : refroidissement, haute densité, nouvelles architectures.</p><h3>15:15 15:45 | AI for Pharma R&amp;D</h3><p>Biolevate + Sanofi : comment l’IA accélère la découverte moléculaire.</p><p>Voici un résumé clair et réutilisable de la session “Pharmaceutique &amp; santé publique” (12–15h15).</p><h2>🎯 Thème de la table ronde</h2><p>Comment l’IA transforme <em>à la fois</em> :</p><ul><li>la surveillance épidémiologique,</li><li>la découverte de nouveaux traitements,</li><li>et la mise sur le marché de médicaments / vaccins,</li></ul><p>dans un secteur ultra-régulé (pharma, santé publique).</p><p>Intervenants :</p><ul><li>Joël Belafont – co-fondateur de BioElevate (ex-bâtisseur de produits tech depuis 15+ ans).</li><li>Antoine de Dorcich – co-fondateur, responsable IA chez BioElevate.</li><li>Cédric Meillet – Sanofi Vaccins, spécialiste épidémiologie &amp; santé publique (ex-OMS).</li><li>Modération : Sophia (BioStream).</li></ul><h2>🧪 Les grandes faiblesses actuelles de la santé publique (Cédric – Sanofi)</h2><ol><li><p>Données trop lentes</p><ul><li>Les systèmes de surveillance épidémiologique classiques sont rigides, basés sur des pipelines propres mais lents.</li><li>Parfois, <em>les journaux télévisés annoncent l’épidémie avant les dashboards officiels</em>.</li></ul></li><li><p>Une seule source de vérité par indicateur</p><ul><li><p>Traditionnellement : un indicateur → une source (ex : labos, hôpitaux).</p></li><li><p>Or aujourd’hui, on pourrait croiser :</p><ul><li>logiciels de cabinets de médecine générale (GP software),</li><li>réseaux sociaux,</li><li>eaux usées,</li><li>labos privés, etc.</li></ul></li><li><p>Exemple : en Allemagne, accéder au logiciel des généralistes permet de suivre 400 000 patients/semaine avec 48 h de retard seulement → quasiment du temps réel.</p></li></ul></li><li><p>Sélection des souches vaccinales encore “à l’ancienne”</p><ul><li><p>Pour la grippe : on reformule 2×/an.</p></li><li><p>Mais la façon de choisir les antigènes à mettre dans le vaccin n’a quasi pas changé depuis 50 ans.</p></li><li><p>Peu ou pas d’exploitation :</p><ul><li>des données historiques massives,</li><li>ni d’IA pour prédire les souches futures.</li></ul></li></ul></li></ol><h2>🤖 Où l’IA apporte le plus de valeur ? (Joël &amp; Antoine – BioElevate)</h2><h3>1. Une techno “convergente”</h3><p>Pour Joël, l’IA utile en santé, ce n’est pas juste “des LLM” :</p><ul><li>modèles classiques de machine learning,</li><li>LLM et transformers,</li><li>analyse de texte, d’images, de signaux capteurs,</li><li>modèles de recherche / RAG,</li><li>agents spécialisés qui combinent plusieurs outils,</li><li>plus l’évolution des sensors et du hardware (inference embarquée, etc.).</li></ul><p>Tout converge pour attaquer un problème complexe par plusieurs canaux en parallèle :
quelles maladies émergent ? quelles souches virales ? quels traitements possibles ?</p><h3>2. L’état réel des LLM aujourd’hui</h3><p>Antoine résume bien la situation :</p><blockquote><p>“On peut attaquer n’importe quel problème complexe avec des LLM si on le découpe en sous-tâches que le modèle sait résoudre.”</p></blockquote><p>Deux limites majeures :</p><ol><li><p>Mémoire &amp; contexte</p><ul><li><p>Un LLM ne peut pas ingérer brut :</p><ul><li>une base de données gigantesque,</li><li>des années de littérature scientifique,</li><li>des millions de documents réglementaires.</li></ul></li><li><p>Il faut sélectionner et structurer l’information en amont.</p></li></ul></li><li><p>Chaînes de raisonnement longues</p><ul><li>Si on laisse le modèle “penser” trop longtemps, il dérive, perd le fil, hallucine ou sort de sa mission.</li></ul></li></ol><p>BioElevate construit donc l’infrastructure autour du modèle pour compenser ces limites.</p><h2>🧱 Innovations clés de BioElevate pour la pharma</h2><h3>1. Compréhension profonde des documents</h3><ul><li><p>Travail très poussé sur :</p><ul><li>la sémantique des documents (où se trouve la connaissance, comment elle est structurée),</li><li>pas seulement “texte brut” mais structure, sections, taxonomie.</li></ul></li></ul><h3>2. Un “nouveau vector store” orienté navigation, pas seulement recherche</h3><ul><li><p>Critique de l’approche standard chunking + simple vecteurs :</p><ul><li><p>le découpage en chunks fait perdre :</p><ul><li>la structure,</li><li>le contexte global,</li><li>les liens entre sections.</li></ul></li><li><p>on force l’IA à ne faire que de la recherche sémantique ponctuelle, ce qui est limité.</p></li></ul></li><li><p>BioElevate propose un “knowledge store” :</p><ul><li><p>orienté navigation de connaissance :</p><ul><li>parcourir les sections,</li><li>suivre une taxonomie,</li><li>explorer un corpus “comme un expert humain”.</li></ul></li><li><p>L’agent peut se déplacer dans le document, pas seulement recevoir 3 chunks choisis.</p></li></ul></li></ul><h3>3. Orchestration agentique &amp; workflows complexes</h3><ul><li><p>Les questions métier sont souvent :
“épidémie en vue ? quelles variantes ? quelles recommandations ?”
→ ce ne sont pas des questions à un seul shot.</p></li><li><p>BioElevate orchestre :</p><ul><li>un workflow complexe → en sous-workflows,</li><li>plusieurs agents spécialisés collaborent,</li><li>chacun appelle ses outils, construit une partie de la carte mentale,</li><li>le tout reste traçable et reproductible → important pour le réglementaire.</li></ul></li></ul><h2>🇫🇷 Projet IOLOS : un vrai cas concret de santé publique</h2><p>Cédric annonce officiellement :</p><ul><li><p>Sanofi, BioElevate, Orange, Impact Healthcare ont été sélectionnés par le cluster IDBO (santé – France 2030) pour le projet IOLOS :</p><ul><li><p>objectif : révolutionner la surveillance des maladies respiratoires en France (grippe, COVID, etc.).</p></li><li><p>approche : multi-sources de données (GP, labos, eaux usées, réseaux, etc.) → un dashboard IA qui:</p><ul><li><p>surveille en temps réel,</p></li><li><p>prévoit les vagues épidémiques/pandémiques,</p></li><li><p>alimente des applications mobiles pour le citoyen :</p><blockquote><p>“Avant de sortir en hiver, tu peux voir ton risque d’attraper la grippe ou le COVID.”</p></blockquote></li></ul></li></ul></li><li><p>Timeline :</p><ul><li>début prévu avant mi-2026, durée 4 ans,</li><li>pilote régional vers 2 ans,</li><li>solution industrielle complète vers 4 ans.</li></ul></li></ul><h2>🧬 IA &amp; découverte de traitements (BioElevate)</h2><p>Joël décrit une autre application, côté R&amp;D thérapeutique :</p><ul><li><p>Ils ont utilisé leurs pipelines pour découvrir de nouveaux traitements sur :</p><ul><li>des maladies rares ou orphelines,</li><li>des domaines comme oncologie, dermatologie, etc.</li></ul></li><li><p>En particulier :</p><ul><li>un candidat traitement en leucémie a passé des premiers tests précliniques.</li></ul></li><li><p>Stratégie : se concentrer sur des maladies non rentables pour les big pharmas (trop rares), et utiliser les agents IA pour explorer l’espace thérapeutique beaucoup plus vite.</p></li></ul><h2>⚙️ Innovations “pragmatiques” : prompts &amp; agents</h2><h3>1. Optimisation automatique de prompts</h3><ul><li><p>BioElevate a publié un papier sur la prompt optimisation :</p><ul><li>sans changer le modèle,</li><li>ils peuvent augmenter l’accuracy jusqu’à +60 % sur certaines tâches,</li><li>parfois mieux qu’un fine-tuning LoRA, sans risque de fuite de données sensibles dans un modèle LoRA.</li></ul></li><li><p>Cette techno sera intégrée au cœur de leur plateforme l’an prochain.</p></li></ul><h3>2. Scaling des agents : promesses et problèmes</h3><p>Joël est très clair :</p><blockquote><p>“Pour 10 innovations que tu poses, tu crées 10 problèmes.”</p></blockquote><ul><li><p>Vision : faire passer une tâche de 1 an de clics pour des humains → à 100 000 agents qui collaborent pendant 1 heure.</p></li><li><p>Mais à chaque palier ×10 :</p><ul><li>on découvre un nouveau bottleneck (infra, orchestration, transactions, monitoring, conformité),</li><li>on l’optimise,</li><li>puis le palier suivant révèle un nouveau goulot d’étranglement.</li></ul></li></ul><h2>📜 Réglementation, traçabilité &amp; confiance</h2><p>Cédric (Sanofi) insiste :</p><ul><li><p>Réalité pharma : régulation lourde (agences, EMA, FDA, etc.).</p></li><li><p>Ce qui est indispensable :</p><ul><li>Traçabilité : pouvoir rejouer le raisonnement, suivre les sources, expliquer le “pourquoi”.</li><li>Reproductibilité : obtenir le même résultat, avec les mêmes entrées.</li><li>Transparence : pas de “boîte noire magique” sans explication.</li></ul></li></ul><p>Sanofi a mis en place une politique “Responsible AI” (co-RAISE) :
un cadre interne où les solutions d’IA doivent respecter ces exigences.</p><p>BioElevate, de son côté, conçoit ses workflows agentiques avec :</p><ul><li>historique complet des étapes de raisonnement,</li><li>sources citées,</li><li>capacité à refaire le même chemin → critique pour être acceptable auprès des régulateurs.</li></ul><h2>💉 Le “gros” problème à 5 milliards de dollars</h2><p>Question “baguette magique” de Sophia à Cédric :</p><blockquote><p>“Si tu pouvais demander une seule chose à BioElevate ?”</p></blockquote><p>Réponse :</p><ul><li><p>Améliorer massivement la sélection des souches de grippe / COVID pour les vaccins.</p><ul><li>Exploiter 50 ans de données non utilisées,</li><li>utiliser l’IA pour prédire quelles souches domineront,</li><li>augmenter nettement l’efficacité des vaccins.</li></ul></li><li><p>Il annonce aussi :</p><ul><li>un workshop prévu avec l’OMS à Genève avant mi-2026,
pour travailler sur l’usage de l’IA dans ce processus de sélection.</li></ul></li></ul><h2>🧬 Maladies rares &amp; médecine de précision</h2><p>Sur la question des maladies très rares, souvent “pas intéressantes” économiquement :</p><ul><li><p>Joël rappelle que l’IA ne “veut” rien, ce sont les humains qui portent le projet.</p></li><li><p>Mais si on industrialise les méthodes de recherche &amp; de design de traitements grâce aux agents :</p><blockquote><p>on peut, à terme, envisager de développer des traitements pour quasiment tout,
y compris des cas ultra-personnalisés (génome spécifique, configuration unique).</p></blockquote></li></ul><p>C’est la vision : médecine de précision à grande échelle, rendue possible par la scalabilité des agents IA.</p><h2>🧠 Message final de Joël : qui peut construire ça ?</h2><p>Sophia lui demande un conseil pour ceux qui veulent se lancer dans l’IA appliquée à des secteurs critiques (santé, défense, etc.) sans être médecin/PhD :</p><ul><li><p>On ne contribue pas parce qu’on est “un génie de l’IA”, mais parce qu’on a :</p><ul><li>une expérience unique,</li><li>un angle de frustration fort sur un problème précis.</li></ul></li><li><p>Les grands labs (ex : Anthropic) recrutent des profils hors IA pure :</p><ul><li>l’enjeu clé, c’est formuler correctement le problème et les contraintes.</li></ul></li><li><p>Si quelque chose te frustre dans le monde réel, tu peux :</p><ul><li>t’approprier les outils IA,</li><li>construire la solution autour de cette frustration.</li></ul></li></ul><blockquote><p>“Il y a l’intelligence artificielle, mais il y a surtout l’intelligence humaine qui va la mettre au service de quelque chose.”</p></blockquote><h3>15:50 16:05 | Zero-shot product taxonomy (Veepee)</h3><p>Un vrai cas d’usage e-commerce européen.</p><p>Voici un récap clair du talk “Multimodal product classification chez VP (Veepee)”.</p><h2>🏬 Contexte : VP (Veepee) et le problème métier</h2><ul><li>VP = unicorn française, fondée en 2001</li><li>5 000 employés, 30 M de membres actifs, activité dans toute l’Europe</li><li>5 millions de produits par an, issus de ~7 000 marques, dans toutes les verticales (sport, jardin, électroménager, etc.)</li></ul><p>Pour chaque produit, il faut :</p><ul><li>fiche technique,</li><li>images,</li><li>et surtout une classification produit correcte (taxonomie interne).</li></ul><h3>Pourquoi la classification est critique ?</h3><p>Parce qu’elle impacte toute la chaîne :</p><ul><li><p>Pricing : mauvaise catégorie → mauvais prix → perte de marge / perte de compétitivité.</p></li><li><p>Finance / Fiscalité : reporting, taxes, budgets → tout repose sur la bonne taxonomie.</p></li><li><p>Logistique :</p><ul><li>ex : un produit classé “T-shirt” alors que c’est un “lave-vaisselle” → catastrophe en entrepôt.</li></ul></li><li><p>Qualité actuelle des données : ~11 % d’erreurs dans le catalogue → difficile de s’en servir pour entraîner un modèle classique.</p></li></ul><p>Ils ont essayé de faire un “vrai” modèle ML pendant 6 ans → échec.</p><h3>Pourquoi c’est dur avec du ML classique ?</h3><ul><li><p>Taxonomie non MECE (non “Mutually Exclusive, Collectively Exhaustive”)</p><ul><li>ex : “T-shirt” VS “Top” → un T-shirt est un top, mais la taxonomie les sépare quand même.</li></ul></li><li><p>Taxonomie qui évolue constamment (nouvelles tendances, nouveaux produits).</p></li><li><p>Imbalance massif entre catégories :</p><ul><li>certaines catégories ont des millions d’items historiques,</li><li>d’autres : 3 produits (ex : “Imprimantes 3D”…).</li></ul></li><li><p>Cold start : une nouvelle catégorie n’a pas assez de données pour l’apprentissage.</p></li><li><p>Et les données historiques sont bruitées (11 % d’erreurs…).</p></li></ul><p>Conclusion : il faut un système zero / few-shot, pas un gros classifieur supervisé.</p><h2>🧠 Étape 1 – Zero-shot avec CLIP (baseline multimodale)</h2><p>Ils utilisent un modèle CLIP (image + texte) en “zero-shot classification”.</p><h3>Principe</h3><ol><li><p>Pour chaque catégorie (≈ 1 500 catégories) :</p><ul><li><p>transformer la catégorie en phrase :</p><blockquote><p>“This product is a T-shirt”, “This product is a dishwasher”, etc.</p></blockquote></li><li><p>embeddings texte → vecteurs de dimension d.</p></li></ul></li><li><p>Pour chaque produit :</p><ul><li>encoder l’image du produit → embedding image.</li><li>calculer la similarité (cosinus, euclidienne, etc.) entre l’image et les 1 500 vecteurs de catégories.</li><li>prendre le Top-1 comme prédiction.</li></ul></li><li><p>Variante avancée :</p><ul><li>ne pas embedder seulement le nom de la catégorie,</li><li>mais aussi les métadonnées / connaissances expertes liées à la catégorie (description métier, règles, etc.).</li></ul></li></ol><h3>Avantages</h3><ul><li>Zero training : pas de fine-tuning, pas de data cleaning massif.</li><li>Très rapide et peu coûteux (embedding + similarités).</li><li>Gère naturellement l’ajout de nouvelles catégories (on les embedde, point).</li></ul><h3>Limites</h3><ul><li>Top-1 accuracy ≈ 58 %
(vs ~89 % pour un humain).</li><li>En Top-15, on monte à ~89 % (on finit par inclure la bonne catégorie quelque part dans la liste).</li><li>→ ça ne suffit pas pour de l’automatique : c’est plutôt une assistance humaine ou un pré-filtrage.</li></ul><h2>🧠 Étape 2 – Ajout du KNN historique (similarité avec les anciens produits)</h2><p>Idée :
comparer le produit non seulement aux catégories, mais aussi aux anciens produits bien labellisés.</p><h3>Pipeline</h3><ol><li><p>Ils identifient 1,5 M de produits historiques bien étiquetés (labels sûrs).</p></li><li><p>Pour un nouveau produit :</p><ul><li>encoder l’image,</li><li>faire un KNN (k plus proches voisins) dans cette base de 1,5 M embeddings,</li><li>récupérer les k produits similaires (ex : top 100).</li></ul></li><li><p>Récupérer les catégories de ces voisins :</p><ul><li>pour ces 100 produits, collecter leurs catégories,</li><li>en extraire un Top-30 de catégories les plus fréquentes / pertinentes.</li></ul></li><li><p>Combiner :</p><ul><li>Top-30 du CLIP “catégories”</li></ul><ul><li>Top-30 du KNN “produits similaires”
→ fusion (par ex. via un LRF / vote pondéré).</li></ul></li></ol><p>Résultat :</p><ul><li>Sur le Top-15 final, la probabilité que la bonne catégorie soit présente dépasse la performance humaine.</li></ul><h3>Pourquoi c’est bien ?</h3><ul><li><p>On introduit un biais historique volontaire :</p><ul><li>le modèle “imite” ce que les équipes font depuis des années,</li><li>et colle au “business logic” réel de VP.</li></ul></li><li><p>Le coût reste très faible (embeddings + KNN sur un index vectoriel).</p></li></ul><h2>🧠 Étape 3 – Ajout d’un LLM multimodal pour trancher le Top-1</h2><p>Là, on rentre dans le vrai génératif multimodal.</p><p>On part du constat :</p><ul><li>en Top-15, le bon label est là ~96 % du temps (après CLIP + KNN).</li><li>il manque juste un “cerveau” pour choisir le bon parmi ces 15 candidats.</li></ul><h3>Entrées pour le LLM multimodal</h3><p>Pour chaque produit :</p><ol><li><p>Les 15 catégories candidates (issues de l’étape précédente).</p></li><li><p>L’image du produit.</p></li><li><p>La fiche technique / texte (titre, description, attributs…).</p></li><li><p>Le label book :</p><ul><li><p>un document texte en langage humain :</p><ul><li>expliquant ce que couvre chaque catégorie,</li><li>les règles métier (“on met X ici, sauf si Y”, etc.),</li><li>exactement ce qu’on donnerait comme consigne à un humain.</li></ul></li></ul></li></ol><h3>Ce que fait le LLM</h3><ul><li><p>C’est un LLM multimodal (image + texte).</p></li><li><p>Il reçoit tout le contexte (produit + 15 catégories + règles métiers).</p></li><li><p>Il doit :</p><ul><li>expliquer son raisonnement,</li><li>sélectionner une seule catégorie finale parmi les 15.</li></ul></li></ul><p>Sortie :</p><ul><li><p>un JSON structuré contenant :</p><ul><li>la catégorie choisie,</li><li>éventuellement le raisonnement.</li></ul></li></ul><h3>Résultat</h3><ul><li>Top-1 accuracy ≈ 94 %,
donc supérieure à l’humain (~89 %).</li></ul><p>Et le tout :</p><ul><li><p>sans fine-tuning lourd sur un LLM,</p></li><li><p>en s’appuyant sur :</p><ul><li>embeddings d’image,</li><li>embeddings de textes,</li><li>LLM multimodal off-the-shelf (open weights possible),</li><li><ul><li>la connaissance métier encapsulée dans le label book.</li></ul></li></ul></li></ul><h2>🧾 Propriétés intéressantes de cette approche</h2><ul><li><p>Zero / few-shot de bout en bout</p><ul><li>on ne dépend pas d’énormes datasets propres par catégorie.</li><li>solution robuste au cold-start :
il suffit de créer une nouvelle catégorie, un label book, et on peut la proposer dans le Top-15.</li></ul></li><li><p>Adaptable à d’autres modalités :</p><ul><li><p>actuellement : image + texte,</p></li><li><p>mais on peut imaginer ajouter :</p><ul><li>métadonnées,</li><li>signaux numériques,</li><li>etc.</li></ul></li></ul></li><li><p>Coût maîtrisé &amp; scalable :</p><ul><li>embeddings = très bon marché,</li><li>LLM utilisé seulement sur le top 15, pas sur tout le catalogue brut,</li><li>donc exploitable sur 5 M de produits / an.</li></ul></li><li><p>ROI élevé :</p><ul><li>réduction des erreurs de classification →
impact immédiat sur pricing, logistique, finance, expérience client.</li></ul></li></ul><h2>🧩 En résumé (pattern réutilisable)</h2><p>Le schéma général que tu peux réappliquer ailleurs :</p><ol><li><p>Multimodal embedding (CLIP / similaire) pour faire du zero-shot.</p></li><li><p>Rappel d’historique via KNN sur des données propres, pour injecter les biais &amp; règles métier implicites.</p></li><li><p>LLM multimodal pour :</p><ul><li>lire produit + candidats + règles métiers,</li><li>produire une décision structurée (JSON) + raisonnement.</li></ul></li></ol><p>→ Sans gros training supervisé, tu obtiens :</p><ul><li>une précision &gt; humain,</li><li>un système souple, scalable, peu coûteux,</li><li>capable d’absorber de nouvelles catégories très vite.</li></ul><h3>16:10 16:40 | Video AI pipelines</h3><p>AIVE, XXII, Molia : du edge inference → aux pipelines génératifs vidéo.</p><p>Voici un résumé structuré du talk “Video AI – de la vidéo aux données” (14h–16h10).</p><h2>👥 Les intervenants &amp; leurs produits</h2><ul><li><p>Modérateur : Paul Moshkovich – cofondateur de Modia (lab IA externalisé pour entreprises).</p></li><li><p>Olivier / AVE – <em>Artificial Agents for Video Experiments</em></p><ul><li><p>Plateforme d’automatisation de production vidéo pour :</p><ul><li>marques, agences, médias, réseaux sociaux.</li></ul></li><li><p>À partir d’un spot TV, d’un film ou d’une émission :</p><ul><li>résume, reformate, localise, adapte par audience / réseau,
le tout <em>avec validation humaine</em>.</li></ul></li><li><p>Tech maison : MGT – Multimodal Generative Technology.</p></li></ul></li><li><p>Dan / TwentyTwo (22)</p><ul><li><p>Société de 10 ans, spécialisée dans :</p><ul><li>analyse vidéo en temps réel (vidéosurveillance, retail, etc.).</li></ul></li><li><p>Ne stocke jamais les images :</p><ul><li>transforme directement le flux en données structurées (objets, comportements, temps passé, trajectoires…).</li></ul></li><li><p>Alimentent ensuite d’autres modèles / dashboards / systèmes opérationnels.</p></li></ul></li></ul><h2>🎬 Vision commune : traiter la vidéo comme donnée, pas comme pixels</h2><p>Les deux boîtes partagent la même philosophie :</p><blockquote><p>La vidéo = une source de données multimodales (image, audio, temporalité, contexte), pas seulement une suite de pixels.</p></blockquote><h3>Chez AVE</h3><ul><li><p>Ils décomposent la créativité :</p><ul><li>Côté visible : la vidéo que l’on voit.</li><li>Côté machine : un ensemble de données structurées décrivant la vidéo.</li></ul></li><li><p>Ils ont développé des dizaines de modèles IA propriétaires (plus des modèles open source) qui détectent :</p><ul><li>personnes, émotions, cadrage, objets, logo, discours, mouvement, narration, branding…</li></ul></li><li><p>Tout est transformé en “video-to-data”, puis :</p><ul><li>utilisé pour résumer, reformater, adapter un contenu à différents usages (TV, TikTok, Facebook, etc.).</li></ul></li><li><p>Ensuite, un moteur génétique génère automatiquement des milliers de variantes vidéo (ex : 50 000 montages possibles d’un spot Nespresso) et :</p><ul><li>un “creative score” choisit la meilleure version selon le canal (TikTok ≠ Facebook).</li></ul></li></ul><h3>Chez TwentyTwo (22)</h3><ul><li><p>Ils définissent des règles :</p><ul><li>ex : “un objet de type <em>humain</em> entre dans telle zone”,
“combien de temps reste-t-il dans cette zone”,
“comportement X détecté ou non”.</li></ul></li><li><p>Le système extrait :</p><ul><li>type d’objet (humain, véhicule, etc.),</li><li>trajectoires,</li><li>temps passé,</li><li>comportements,</li><li>re-identification non biométrique (mêmes individus entre caméras)…</li></ul></li><li><p>Tout est stocké comme données structurées (type, position, temps, évènement), directement exploitables :</p><ul><li>dans des dashboards,</li><li>dans des systèmes opérationnels (alertes temps réel, automatisation).</li></ul></li></ul><h2>🧠 Multimodalité : image + son + texte + temps</h2><p>Les deux insistent : la multimodalité est indispensable.</p><h3>Pourquoi ?</h3><ul><li><p>Comme pour un humain, on a besoin de plusieurs signaux pour comprendre le contexte :</p><ul><li>image seule,</li><li>son / voix,</li><li>texte (sous-titres, scripts),</li><li>temporalité (ce qui vient <em>avant</em> / <em>après</em> une scène),</li><li>position dans l’image (centre vs coin), mouvements, etc.</li></ul></li><li><p>Le croisement de ces signaux permet :</p><ul><li>meilleure compréhension des émotions, du rôle des plans, des scènes clés,</li><li>meilleure détection de comportements côté 22 (retail, sécurité, analytics).</li></ul></li></ul><h3>Exemples concrets</h3><ul><li><p>AVE :</p><ul><li><p>Certaines pubs / films sont sans dialogue → il faut s’appuyer sur :</p><ul><li>expressions faciales,</li><li>mouvement,</li><li>type de plan (gros plan, plan large),</li><li>rythme,</li><li>cliffhanger, moments clés…</li></ul></li><li><p>Leur MGT combine plusieurs modèles :</p><ul><li>ex : “gros plan + visage + émotion forte” → scène clé / moment émotionnel.</li></ul></li></ul></li><li><p>22 :</p><ul><li><p>Utilise multimodal + VLM (vision-language model) pour :</p><ul><li>permettre à l’utilisateur de poser des questions en langage naturel sur la vidéo
(ex : “est-ce que la personne porte un casque ?”),</li><li>et recevoir des réponses basées sur leurs données vidéo → texte.</li></ul></li></ul></li></ul><h2>📉 Data scarcity &amp; données synthétiques</h2><h3>Problèmes de base</h3><ul><li><p>Il est difficile d’obtenir assez de données réelles pour tout couvrir :</p><ul><li>contraintes GDPR / privacy,</li><li>scénarios rares (évènements peu fréquents),</li><li>multiples configurations de caméras / lumières / angles, etc.</li></ul></li><li><p>On ne peut pas “filmer tout et n’importe quoi” pour entraîner un modèle.</p></li></ul><h3>Approche de TwentyTwo (22)</h3><ul><li><p>Historiquement :</p><ul><li>génération de données 3D synthétiques (environnements de retail, caméras, lumières, occlusions).</li><li>À l’époque (2018), le rendu 3D n’était pas assez réaliste.</li></ul></li><li><p>Aujourd’hui :</p><ul><li><p>ils utilisent un mix :</p><ul><li>données réelles (issues de partenariats clients ou environnements loués),</li><li>données synthétiques générées avec les récents modèles de GenAI vidéo.</li></ul></li><li><p>L’entraînement peut utiliser réel + synthétique,
mais la validation des modèles se fait uniquement sur données réelles.</p></li></ul></li></ul><h3>Approche d’AVE</h3><ul><li><p>Philosophie différente :</p><ul><li>ils ne “fine-tunent” pas leurs modèles sur les vidéos clients.</li><li>MGT est basé sur une approche meta-learning / combinaison de modèles.</li></ul></li><li><p>Conséquences :</p><ul><li>pas de ré-entraînement au fur et à mesure des uploads clients,</li><li>pas de fuite de données vers l’extérieur (pas d’API externes),</li><li>conformité forte pour les clients B2B (marques, agences, médias).</li></ul></li><li><p>Leur promesse :</p><ul><li>tu uploades une vidéo → pas de phase de setup / training, tu produis de la valeur tout de suite.</li></ul></li></ul><h2>🛡️ Guardrails, hallucinations &amp; qualité des prédictions</h2><h3>AVE</h3><ul><li><p>Dans la pub / l’entertainment, la tolérance à l’erreur est quasi nulle :</p><ul><li>pas de personnages avec trois bras,</li><li>pas de glitch visibles,</li><li>pas de montages incohérents.</li></ul></li><li><p>Leur techno est décrite comme déterministe :</p><ul><li>le pipeline (détection + règles + génération + sélection) est conçu pour éviter les hallucinations,</li><li>ils ne “laissent pas un LLM inventer du contenu visuel” librement.</li></ul></li><li><p>Ils insistent sur :</p><ul><li><p>pixel perfect,</p></li><li><p>contrôle créatif,</p></li><li><p>feedback humain :</p><ul><li>l’utilisateur peut éditer ce que l’IA propose,</li><li>corriger / affiner (boucle de correction).</li></ul></li></ul></li></ul><h3>TwentyTwo (22)</h3><ul><li><p>Eux reconnaissent : oui, il y a des hallucinations.</p><ul><li>surtout côté modèles génériques (VLM) ou reconnaissance d’objets dans des cas limites.</li></ul></li><li><p>Mais :</p><ul><li>ils ne voient jamais la vidéo côté serveur (on-premise chez le client),</li><li>donc ils ne peuvent pas “corriger” manuellement cas par cas.</li></ul></li><li><p>Stratégies :</p><ul><li><p>ajustement des seuils selon le contexte (distance caméra, lumière, angle…),</p></li><li><p>fine-tuning ciblé sur certains cas d’usage,</p></li><li><p>transparence avec le client :</p><ul><li>ils communiquent sur les taux de performance,</li><li>donnent des recommandations (position caméra, pixel density, etc.).</li></ul></li></ul></li><li><p>Taux d’erreur :</p><ul><li>dépend du cas d’usage, mais tant que la masse de données globale est cohérente,
les erreurs ponctuelles sont acceptables pour des use cases analytics.</li></ul></li></ul><h2>🧩 Points clés à retenir</h2><ol><li><p>Même philosophie, use cases opposés :</p><ul><li>AVE : post-production / adaptation créative (pub, entertainment).</li><li>22 : analyse temps réel / environnement physique (retail, flux, comportement).</li></ul></li><li><p>La vidéo est traitée comme un flux multimodal de données structurables,
pas juste comme une “image animée”.</p></li><li><p>Multimodalité = clé pour :</p><ul><li>comprendre contexte, émotions, intentions,</li><li>offrir des interfaces en langage naturel (poser une question au système sur ce qui se passe dans la vidéo),</li><li>améliorer robustesse et précision.</li></ul></li><li><p>Data scarcity ≠ showstopper, si :</p><ul><li>on combine données synthétiques, réelles, et meta-learning / composition de modèles,</li><li>on conçoit des systèmes qui ne dépendent pas d’énormes datasets clients pour fonctionner.</li></ul></li><li><p>Guardrails &amp; hallucinations dépendent du métier :</p><ul><li>publicité / vidéo marketing → exigence de perfection visuelle → pipeline plus déterministe.</li><li>analytics / retail → légère marge d’erreur acceptable si le signal global est fiable.</li></ul></li></ol><h3>17:10 17:25 | A deep dive into MCP &amp; ChatGPT apps</h3><p>Un talk clé : MCP, la nouvelle révolution des apps autonomes.
Particulièrement intéressant pour les développeurs européens.</p><h3>17:50 18:05 | AI at Spotify</h3><p>Comment Spotify repense ses stratégies grâce à l’IA “everywhere”.</p><h1>☕ Founders Café : business cases, edge AI, RL, industrie, durabilité</h1><p>Une track plus intimiste mais ultra-technique :</p><ul><li>12:05 12:35 | AIVE : Next-gen video transcreation</li><li>12:40 13:10 | OCR-powered menu inventory</li><li>13:15 13:30 | Real-time AI: 100x faster inference (Kog)</li><li>13:35 13:50 | Measuring ROI of AI adoption</li><li>13:55 14:10 | Reinforcement Learning &amp; PCB routing</li><li>14:15 14:30 | Automotive Foundation Models</li><li>14:35 15:05 | Sustainable AI scaling (Fujitsu)</li><li>15:10 15:40 | Desktop → Supercomputer: AI workflows</li><li>16:10 16:40 | Build the audio agent</li><li>17:05 17:35 | Computer-using agents (leadgen)</li><li>17:40 18:10 | Tabular Foundation Models (Neuralk-AI)</li></ul><p>Un mélange rare d’infrastructure, produits, cas d’usage réels, régulations, optimisation énergétique et agents IA.</p><h1>📌 Ce que révèle l’agenda 2025</h1><h3>1. L’ère des agents autonomes est amorcée</h3><p>Les talks sur les agents, l’autonomie, l’orchestration, la productivité et MCP sont partout.</p><h3>2. L’Europe veut imposer une IA responsable et efficiente</h3><p>Sobriété énergétique, transparence, souveraineté et régulation sont omniprésentes.</p><h3>3. L’industrie rattrape voire dépasse la recherche appliquée</h3><p>Pharma, automobile, e-commerce, robotique : on n’est plus dans la démo, mais dans le déploiement massif.</p><h3>4. Le hardware redevient un sujet stratégique</h3><p>Air cooling, edge, ARM, densité, supercompute : l’Europe veut des alternatives au duopole GPU US/Asie.</p><h3>5. La multimodalité s’impose dans tous les usages</h3><p>Texte → image, voix → produit, vidéo → actions, tableau → insights.</p><h1>🎤 Conclusion : ai-PULSE confirme le virage européen de l’IA</h1><p>Avec un programme dense, international et orienté action, ai-PULSE 2025 marque une étape clé.
L’Europe ne se contente plus d’analyser l’IA : elle construit, elle optimise, elle déploie.</p><p>Pour ceux qui veulent comprendre où va l’IA en 2026 agents autonomes, edge, multimodalité, efficacité énergétique, MCP c’est clairement le rendez-vous incontournable.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/ia-pulse</link><guid>https://blog.darkwood.com/article/ia-pulse</guid><enclosure url="http://darkwood.com/media/articles/69409d8a04193447942248.jpg" /></item><item><title>🏛️ Open Source Experience 2025: an ecosystem that is organizing itself, asserting itself and accelerating</title><pubDate>Fri, 12 Dec 2025 14:55:43 +0000</pubDate><description><![CDATA[Each edition of Open Source Experience acts as a revealer: that of an open ecosystem which is no longer just a counter-model to proprietary software giants, but a structuring force for European competitiveness, sovereign innovation and the digital transform...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/693c33cf85d5d676915168.png" /></p><p>Each edition of Open Source Experience acts as a revealer: that of an open ecosystem which is no longer just a counter-model to proprietary software giants, but a structuring force for European competitiveness, sovereign innovation and the digital transformation of organizations.</p><p>The 2025 edition, organized on December 10 and 11 at the Cité des Sciences, confirms a fundamental trend: open source is no longer a technical choice among others, it has become a strategic infrastructure, a proven economic model, and a major lever for autonomy in the face of digital dependencies.</p><p>In this article, I summarize the key trends, weak signals and lessons that seem to me to be major for understanding the evolution of free software in Europe.</p><p><img src="/blog/images/articles/2025-12-11-opensource-experience/G701MhJW4AAKPKI.jpeg" alt="G701MhJW4AAKPKI.jpeg" /></p><p>#1. Open Source as an instrument of sovereignty</p><p>From the opening plenary session, the tone was set: free software is no longer a technical issue, but a geopolitical one. The interventions of Cristina Caffarra (EuroStack), Stefane Fermigier (APELL), and Laurent Tréluyer (CNAF) reiterated an obvious point: dependence on American platforms is no longer sustainable.</p><h3>Key points:</h3><ul><li>Europe must regain control of its digital infrastructure. * Free software is the most credible foundation for building sustainable alternatives. * Initiatives like EuroStack, APELL, OpenInfra, and the future IPCEI Cloud (€3 billion investment) demonstrate unprecedented political will.</li></ul><p>This is a changing era: open source is moving from the status of &quot;best practice&quot; to the status of strategic necessity.</p><p>#2. The explosion of sovereign stacks: cloud, workplace, IAM, communication</p><p>This edition reveals a massive movement: the reconstruction of a complete European digital stack.</p><h3>Among the key structural elements visible in the program:</h3><ul><li>Proxmox VE as an open alternative to VMware * OpenNebula, OpenStack, and Kubernetes for a federated European cloud * BlueMind, Nextcloud, CryptPad, and eXo Platform to replace Microsoft 365 * Keycloak, LDAP, and LemonLDAP::NG for IAM * Zimbra/Beezim, XiVO, Linphone, and Matrix/Element for sovereign communication</li></ul><p>Each of these building blocks demonstrates the same trend: 👉 <em>to definitively decouple collaborative practices from dependence on GAFAM.</em></p><p>The future European workplace is already here: modular, interoperable, and designed around open standards.</p><p>#3. Open source AI is scaling up</p><p>AI plays a phenomenal role in the 2025 edition, but an open, controllable, auditable, interoperable AI.</p><p>Among the most memorable sessions:</p><ul><li>vLLM on Kubernetes (France Travail): industrialization of sovereign AI architectures * MCP (Model Context Protocol) applied to the cloud: AI assistants managing the infrastructure * Shapash: open-source explainability for responsible AI * Decentralized GenAI: a more modular vision, beyond closed models * Datafari + RAG: enterprise search engines leveraging generative AI * Nextcloud + AI for a smart and sovereign workplace</li></ul><p>Open source AI is no longer an experimental domain: it is becoming a production infrastructure.</p><p>#4. Cybersecurity: Maturity Increase</p><p>European regulatory constraints (CRA, NIS2, AI Act) act as an accelerator.</p><p>Several conferences illustrate this maturity:</p><ul><li>TLA+ to prove the security of distributed systems * OSS-Fuzz, large-scale fuzzing * VulnScout.io to manage vulnerabilities via SBOM * Zero Trust revisited by open source * The massive return to self-hosting of secure emails (DKIM/SPF/DMARC…)</li></ul><p>👉 Open source is emerging as the most suitable environment for controlling the chain of trust.</p><p>#5. Open Source Business Models: Clarity, Structure, and Industrialization</p><p>With nearly a dozen conferences on this theme, OSXP 2025 confirms that the free software economy is no longer a vague model.</p><p>Key trends:</p><ul><li>Open-source companies are raising funds faster (Serena VC data). * Projects are adopting consistent hybrid “open core + services” models. * Contributions are becoming more standardized (e.g., PrestaShop and its calls for contributions). * Open Source Program Offices (OSPOs) are becoming the norm in large public organizations. * Europe is investing heavily (e.g., IPCEI Cloud, NGI, cascade funding).</li></ul><p>Free software is becoming a professional, funded, and structured playing field.</p><p>#6. Engineering and developer experience: open source at the heart of the modern platform</p><p>Many talks reveal a clear direction:</p><ul><li>Backstage.io for Internal Developer Platforms * Open VSX to break free from vendor lock-in around VS Code * Cristal: modularized, multi-source editor (XWiki, GitHub, Nextcloud…) * Standardized Helm charts for AI (vLLM) * Inner/open source design systems</li></ul><p>This edition shows that modern software engineering relies on an open source tool infrastructure, where each layer is replaceable and transparent.</p><p>#7. An industry that finally talks to itself</p><p>What stands out about OSXP 2025, far beyond the tools, is convergence:</p><ul><li>open source publishers * government agencies * large corporations * SMEs * researchers * communities * public policies</li></ul><p>The trade show is becoming a strategic marketplace where the future digital autonomy of the continent is being built.</p><h1>🔥 Conclusion: OSXP 2025 confirms a historic turning point</h1><p>Open source is no longer the alternative.</p><p>It has become the foundation upon which Europe hopes to rebuild its digital infrastructure:</p><ul><li>sovereign * sustainable * interoperable * transparent * economically viable</li></ul><p>The technologies presented demonstrate a level of maturity rarely seen. The political conferences reveal a newfound commitment. The industrial projects prove that it is possible.</p><p>The overall impression? 👉 We are entering the decade where open source is becoming the norm.</p><p>And Darkwood will continue to tell, analyze and experiment with this transformation in tools, methods, infrastructures, and uses.</p><p><img src="/blog/images/articles/2025-12-11-opensource-experience/G701MhLXkAEhdTw.jpeg" alt="G701MhLXkAEhdTw.jpeg" /></p>
]]></content:encoded><link>https://blog.darkwood.com/article/open-source-experience-2025-an-ecosystem-that-is-organizing-itself-asserting-itself-and-accelerating</link><guid>https://blog.darkwood.com/article/open-source-experience-2025-an-ecosystem-that-is-organizing-itself-asserting-itself-and-accelerating</guid><enclosure url="http://darkwood.com/media/articles/693c33cf85d5d676915168.png" /></item><item><title>⭐️ Meetup AFUP Paris Décembre 2025</title><pubDate>Thu, 18 Dec 2025 23:32:23 +0000</pubDate><description><![CDATA[
Le mardi 16 décembre 2025, l’antenne AFUP Paris organisait son dernier meetup de l’année dans les locaux d’Algolia, au cœur du 8ᵉ arrondissement. Une soirée placée sous le signe de la simplicité architecturale et de la performance, avec deux conférences co...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69448f080a291719322473.png" /></p><p><img src="/blog/images/articles/2025-12-16-afup-agolia/IMG_4123.jpg" alt="IMG_4123.jpg" /></p><p>Le mardi 16 décembre 2025, l’antenne AFUP Paris organisait son dernier meetup de l’année dans les locaux d’Algolia, au cœur du 8ᵉ arrondissement. Une soirée placée sous le signe de la simplicité architecturale et de la performance, avec deux conférences complémentaires : l’une centrée sur un framework PHP minimaliste, l’autre sur les enjeux concrets du cache dans des applications à fort trafic.</p><h2>Un rendez-vous communautaire au cœur de l’écosystème PHP</h2><p>Comme à son habitude, l’AFUP a réuni une communauté variée de développeurs et développeuses PHP : profils juniors, confirmés, architectes, freelances et salariés, venus échanger autour de pratiques terrain.
L’événement, gratuit et ouvert à toutes et tous, a permis d’illustrer des problématiques très actuelles : choisir le bon niveau d’abstraction et tenir la charge quand le succès arrive plus vite que prévu.</p><p>Voici une version rédigée et structurée du contenu de l’article pour la présentation d’ouverture du meetup, fidèle au discours de Thomas, mais reformulée pour un article de blog clair, fluide et professionnel.</p><h2>Introduction du meetup : actualités de l’AFUP et vie de la communauté</h2><p><em>Par Thomas Durion.</em></p><p>Pour ouvrir ce dernier meetup AFUP Paris de l’année, Thomas D. a commencé par rappeler le rôle central de l’AFUP et partager les principales actualités de l’association, avant de présenter le programme de la soirée.</p><h3>L’AFUP, pilier historique de l’écosystème PHP</h3><p>Créée en 2001, l’AFUP (Association Française des Utilisateurs de PHP) œuvre depuis plus de vingt ans à la promotion de PHP et de son écosystème.
L’association anime aujourd’hui une quinzaine d’antennes locales à travers toute la France, permettant aux membres de participer à des événements même lorsqu’ils sont en déplacement ou en vacances une manière conviviale de découvrir d’autres communautés locales.</p><p>À Paris, l’antenne organise un meetup par mois, hors période estivale, avec une ligne éditoriale volontairement large : PHP bien sûr, mais aussi bases de données, DevOps, agilité, architecture, et même front-end. Ces rencontres se prolongent systématiquement par un moment informel autour d’un apéritif, favorisant les échanges entre participants.</p><h3>Une communauté ouverte et inclusive</h3><p>Thomas a rappelé un point essentiel de l’ADN AFUP : tout le monde a quelque chose à partager, quel que soit son niveau d’expérience.
L’association recherche en permanence :</p><ul><li>des speakers, débutants ou confirmés,</li><li>des lieux pour accueillir les meetups,</li><li>des sponsors pour soutenir l’organisation (nourriture, boissons, logistique).</li></ul><p>Pour accompagner celles et ceux qui souhaitent se lancer, l’AFUP propose plusieurs programmes de mentorat gratuits :</p><ul><li>mentorat PHP,</li><li>mentorat pour le public speaking, destiné aux personnes qui souhaitent apprendre à présenter un sujet en conférence ou en meetup.</li></ul><h2>Les prochains rendez-vous AFUP</h2><p>Plusieurs dates importantes ont été annoncées :</p><h3>📅 Prochain meetup AFUP Paris</h3><ul><li><p>8 janvier</p></li><li><p>Chez Believe, secteur Paris-Nord / Saint-Ouen</p></li><li><p>Introduction par Sophie Bopuy sur PHP chez Believe</p></li><li><p>Deux talks au programme :</p><ul><li>intelligence artificielle</li><li>choix et conception d’architectures</li></ul></li></ul><h3>🍻 Le Super Apéro AFUP</h3><ul><li>11 mars</li><li>Événement national, organisé simultanément dans toutes les antennes AFUP</li><li>Les détails seront communiqués ultérieurement
👉 Pour rester informé : suivre l’antenne AFUP Paris sur Meetup et LinkedIn</li></ul><p>Un Linktree est également disponible, regroupant :</p><ul><li>les liens vers les réseaux,</li><li>un sondage permettant aux membres de proposer des thèmes ou formats de talks.</li></ul><h2>AFUP Day 2026 : une journée de conférences</h2><p>Thomas a également évoqué l’AFUP Day, prévu le 22 mai, à :</p><ul><li>Paris</li><li>Bordeaux</li><li>Lille</li><li>Lyon</li></ul><p>Il s’agit d’une journée complète de conférences, avec un line-up déjà finalisé, qui sera dévoilé début janvier.
Les dernières places à 65 € HT sont encore disponibles avant un changement de tarif. L’événement recherche également des sponsors, et un dossier dédié est disponible pour les entreprises intéressées.</p><h2>Actualités PHP et standards</h2><p>Côté technique, plusieurs points ont été mentionnés :</p><ul><li><p>Versions PHP :
La cible recommandée est PHP 8.5, avec une tolérance pour PHP 8.4.
La page officielle de support PHP, avec son code couleur, reste un excellent outil pour sensibiliser les décideurs.</p></li><li><p>PSR Response Interrupt :
Une proposition de standard concernant les réponses HTTP est actuellement ouverte à la public review. Les contributions sont bienvenues, notamment pour les mainteneurs de frameworks ou de bibliothèques.</p></li><li><p>Certification PHP :
La Zend PHP Certification (ZCE) a été relancée par Perforce. Une certification exigeante, parfois débattue sur son utilité, mais qui reste un exercice intéressant pour approfondir ses connaissances.</p></li></ul><h2>Présentation de la soirée et remerciements</h2><p>La soirée s’est ensuite orientée vers le programme technique :</p><ul><li>“Slim, le framework léger” par Thierry Leriche-Dessirier</li><li>“Donne-moi du cache” par Axel Venet</li></ul><p>Thomas a encouragé les participants à remplir le sondage AFUP afin d’orienter les futurs talks, puis a remercié Algolia pour l’accueil et la prise en charge de l’apéritif.</p><p>Un représentant d’Algolia a ensuite brièvement présenté l’entreprise :
une plateforme de recherche privée et ultra-rapide, intégrable via API, avec des clients PHP, Symfony et Laravel, et a rappelé que les locaux sont ouverts à l’accueil d’autres communautés tech parisiennes.</p><h2>Une soirée placée sous le signe du partage</h2><p>Entre annonces communautaires, actualités techniques et conférences de fond, cette introduction a parfaitement posé le cadre :
une communauté ouverte, tournée vers le partage, la montée en compétences et l’échange de pratiques, dans une ambiance conviviale et accessible.</p><h2>Slim : un framework PHP léger et assumé</h2><p><em>Présentation par Thierry Leriche-Dessirier</em></p><p>Thierry Leriche-Dessirier a ouvert son intervention par un retour d’expérience personnel : lorsqu’il a commencé à faire du PHP, l’écosystème des frameworks lui paraissait à la fois foisonnant et déroutant. Comme beaucoup à l’époque, il a d’abord fait “ce qu’il fallait faire” : écrire son propre framework, adapté à ses besoins immédiats, sans forcément se soucier de l’existant ni des évolutions futures.</p><p>Avec le temps, l’arrivée de frameworks devenus incontournables Symfony, puis plus tard Laravel a profondément structuré l’écosystème. Thierry explique avoir tenté de s’intéresser à Symfony il y a une dizaine d’années, mais que, compte tenu de son niveau PHP de l’époque, l’approche lui a semblé trop complexe. C’est dans ce contexte qu’il a cherché une alternative plus simple, plus directe, et qu’il a découvert Slim.</p><p>Contrairement à ce que l’on pourrait penser, Slim n’est pas un nouvel acteur : le projet existe depuis 2010, ce qui en fait un outil mature, stable et éprouvé, loin des effets de mode.</p><h2>Slim, c’est quoi exactement ?</h2><p>Le message central du talk est clair : Slim est un micro-framework au sens strict.
Pour Thierry, Slim est même “presque uniquement” un routeur et c’est précisément ce qui fait sa force.</p><ul><li>Slim mappe des routes vers des handlers.</li><li>Il propose une architecture légère, extensible via des middlewares.</li><li>Il s’intègre naturellement dans l’écosystème PSR, en particulier PSR-7 pour la gestion des requêtes et réponses HTTP.</li></ul><p>Cette sobriété volontaire a deux conséquences majeures :</p><ol><li>Une courbe d’apprentissage courte : on en fait rapidement le tour.</li><li>Une grande fiabilité : comme Slim fait peu de choses, il a eu le temps de les faire correctement, de manière performante et prévisible.</li></ol><h2>Présentation du speaker et cas d’usage réel</h2><p>Thierry se décrit comme un profil “multi-casquettes” (développement, conception, rédaction…), travaillant sur plusieurs langages. Il revendique également une posture intéressante : malgré son expérience, il continue de se considérer comme débutant en PHP, et invite explicitement le public à challenger ses choix ou à corriger ses approximations.</p><p>Le talk n’a pas vocation à être exhaustif. Thierry précise qu’il va surtout présenter sa manière personnelle d’utiliser Slim, celle qu’il juge la plus naturelle pour démarrer et structurer un projet.</p><p>Cette approche est illustrée par un cas réel : Profile4 (👉 <a href="https://profil4.com">https://profil4.com</a>), une application orientée communication interpersonnelle et analyse comportementale, dont la partie web repose sur Slim.
À cette occasion, un code promo “AFUP” permettait aux participants du meetup de bénéficier d’une réduction sur les tests DISC proposés par la plateforme.</p><h2>Installer Slim : minimalisme, mais standards</h2><p>L’installation se fait classiquement via Composer, avec l’ajout des dépendances nécessaires autour de PSR-7, puisque Slim s’appuie sur ces abstractions pour manipuler les requêtes et réponses HTTP de manière standardisée.</p><p>L’approche est volontairement pragmatique :
on part d’un point d’entrée minimal, puis on enrichit l’application uniquement lorsque le besoin se fait sentir.</p><h2>Le cœur de Slim : définir des routes</h2><p>Le “Hello World” Slim correspond exactement à ce que l’on attend d’un micro-framework :</p><ul><li>création de l’application via <code>AppFactory</code></li><li>déclaration d’une route (<code>GET</code>, <code>POST</code>, etc.)</li><li>écriture du contenu dans la réponse</li><li>démarrage explicite de l’application via <code>run()</code></li></ul><p>Thierry insiste sur un point important : <code>run()</code> ne déclenche l’exécution qu’à la toute fin, ce qui rend l’architecture plus souple et évite toute initialisation prématurée.</p><p>Slim supporte nativement :</p><ul><li>des routes complexes,</li><li>des paramètres d’URL (<code>{name}</code>),</li><li>la nomination des routes, essentielle pour éviter les URLs codées en dur, notamment lors des redirections.</li></ul><h2>Structurer l’application : bootstrap, routes et middlewares</h2><p>Même si Slim permet techniquement d’écrire toute l’application dans un seul fichier, cette approche ne tient pas dès que le projet dépasse le stade du prototype.</p><p>Thierry propose une organisation simple et efficace :</p><ul><li><code>index.php</code> comme point d’entrée minimal</li><li>un fichier <code>boot.php</code> pour l’initialisation</li><li>un fichier dédié aux routes</li><li>un fichier dédié aux middlewares</li><li>un espace dédié au container pour les dépendances</li></ul><p>L’objectif est de conserver Slim comme une colonne vertébrale légère, tout en structurant le projet de façon saine et évolutive.</p><h2>Actions et contrôleurs : garder des handlers lisibles</h2><p>Pour éviter un empilement de closures, Thierry distingue deux patterns.</p><h3>Actions</h3><p>Une Action est une classe simple, généralement mono-responsabilité, exposant une méthode <code>__invoke()</code> appelée automatiquement par Slim.
Ce pattern est idéal pour les pages simples (home, FAQ, pages statiques).</p><h3>Contrôleurs</h3><p>Dès que plusieurs interactions sont nécessaires (formulaire, validation, redirections…), un contrôleur devient plus adapté :</p><ul><li><code>getLogin()</code> pour afficher le formulaire</li><li><code>postLogin()</code> pour traiter la soumission</li></ul><p>Le mapping se fait explicitement dans la route.
Thierry recommande notamment de factoriser des patterns courants comme le Post / Redirect dans ces contrôleurs.</p><h2>Groupes de routes et limite connue : le slash final</h2><p>Slim permet de créer des groupes de routes (par exemple <code>/user/*</code>) afin d’appliquer des comportements communs comme des middlewares.</p><p>Thierry souligne toutefois une friction connue : la gestion équivalente de <code>/user</code> et <code>/user/</code> n’est pas triviale. En pratique, il lui arrive de déclarer la route en double. Il invite la communauté à partager une solution plus élégante si elle existe aujourd’hui.</p><h2>Le container : injection propre et lazy-loading</h2><p>Dès que l’on souhaite logger, rendre des templates ou sécuriser l’application, le container devient central.</p><p>Thierry montre comment y déclarer un logger (par exemple Monolog), injectable ensuite dans :</p><ul><li>les actions,</li><li>les contrôleurs,</li><li>les middlewares.</li></ul><p>Les services sont instanciés à la demande, évitant de construire inutilement toutes les dépendances à chaque requête un problème qu’il avait rencontré avec ses anciens frameworks “maison”.</p><h2>Les middlewares : le modèle de l’« oignon »</h2><p>Slim est particulièrement à l’aise avec les middlewares.
Thierry les décrit comme un oignon :</p><ul><li>les middlewares s’empilent autour du cœur (l’application),</li><li>le dernier ajouté est le premier exécuté,</li><li>après l’exécution de l’application, on “ressort” dans l’ordre inverse.</li></ul><p>Il illustre plusieurs cas concrets :</p><ul><li>middleware de log “before” pour valider la configuration,</li><li>middleware global pour enrichir les réponses HTML (headers, sécurité),</li><li>middleware d’authentification appliqué à un groupe de routes, avec redirection vers une route nommée (<code>login</code>).</li></ul><h2>Templates : Twig comme couche de rendu</h2><p>Slim n’impose aucun moteur de templates, mais s’intègre facilement avec plusieurs solutions.</p><p>Thierry présente Twig comme choix personnel :</p><ul><li>enregistrement du moteur et du dossier de templates dans le container,</li><li>ajout du middleware de rendu,</li><li>rendu des vues depuis les actions avec passage explicite des variables.</li></ul><p>Il recommande également de centraliser l’injection des variables communes (utilisateur, permissions, contexte global) via héritage ou middleware, plutôt que de les répéter dans chaque action.</p><h2>Conclusion : Slim fait peu… mais le fait bien</h2><p>Le talk se conclut par un constat cohérent avec la philosophie de Slim :</p><ul><li>Slim est stable et mature, et n’évolue pas de manière agressive car il est déjà au bout de ce qu’on attend d’un routeur.</li><li>Il est compatible avec les versions modernes de PHP (y compris PHP 8.5).</li><li>Il ne gère volontairement ni ORM, ni migrations : à vous de composer votre stack.</li></ul><p>Thierry nuance néanmoins : en 2025, certains avantages historiques de Slim sont moins exclusifs. Les frameworks full-stack notamment Symfony ont beaucoup progressé sur la modularisation et les approches “light”.</p><p>Pour autant, lorsqu’on a un besoin clair routing, middlewares, injection propre, rendu simple Slim reste un choix direct, lisible et efficace.</p><h3>Ressources et informations complémentaires</h3><ul><li>Slides LinkedIn :
<a href="https://www.linkedin.com/posts/thierryler_slim-activity-7406987757400637440-lqyu/">https://www.linkedin.com/posts/thierryler_slim-activity-7406987757400637440-lqyu/</a></li><li>Slides SlideShare :
<a href="https://fr.slideshare.net/slideshow/presentation-du-micro-framework-slim-a-l-afup-paris-dec-2025/284450607">https://fr.slideshare.net/slideshow/presentation-du-micro-framework-slim-a-l-afup-paris-dec-2025/284450607</a></li><li>Article <em>Programmez!</em> (approche plus approfondie) :
<a href="https://fr.slideshare.net/slideshow/a-la-decouverte-du-micro-framework-slim-4/284319183">https://fr.slideshare.net/slideshow/a-la-decouverte-du-micro-framework-slim-4/284319183</a></li><li>Posts PHP 8.5 (et article à venir dans le numéro hiver de <em>Programmez!</em>) :
<a href="https://www.linkedin.com/posts/thierryler_%F0%9D%90%8B%F0%9D%90%9E%F0%9D%90%AC-%F0%9D%90%A7%F0%9D%90%A8%F0%9D%90%AE%F0%9D%90%AF%F0%9D%90%9E%F0%9D%90%9A%F0%9D%90%AE%F0%9D%90%AD%F0%9D%90%9E%F0%9D%90%AC-%F0%9D%90%9D%F0%9D%90%9E-%F0%9D%90%8F%F0%9D%90%87%F0%9D%90%8F-activity-7404814079187382272-oMrt">https://www.linkedin.com/posts/thierryler_%F0%9D%90%8B%F0%9D%90%9E%F0%9D%90%AC-%F0%9D%90%A7%F0%9D%90%A8%F0%9D%90%AE%F0%9D%90%AF%F0%9D%90%9E%F0%9D%90%9A%F0%9D%90%AE%F0%9D%90%AD%F0%9D%90%9E%F0%9D%90%AC-%F0%9D%90%9D%F0%9D%90%9E-%F0%9D%90%8F%F0%9D%90%87%F0%9D%90%8F-activity-7404814079187382272-oMrt</a></li></ul><h2>“Donne-moi du cache” : quand la performance devient critique</h2><p><em>Présentation par Axel Venet</em></p><p>La seconde conférence de la soirée a pris la forme d’un récit pédagogique : l’aventure de “Brice of Paris”, entrepreneur passionné de glisse… mais installé à Paris. Surf et neige étant compliqués à monétiser sur place, Brice lance une activité de location de planches de paddle sur la Seine. Au départ, le trafic est faible. Puis la situation change brutalement : <em>succès inattendu</em>, afflux massif de visiteurs… et une question inévitable :</p><blockquote><p>Est-ce que le site va tenir la charge ?</p></blockquote><p>Pour répondre, Axel propose un chemin en plusieurs étapes, du plus bas niveau (PHP) au plus haut (HTTP), puis une conclusion essentielle : le cache n’est pas un “truc à activer”, c’est une démarche.</p><h3>Le scénario : “Brice of Paris” et un site qui explose</h3><p>Brice demande à un ami de lui développer un site “comme tous les clients” :</p><ul><li>accessible, responsive,</li><li>performant et SEO-friendly,</li><li>pas cher,</li><li>et livré vite.</li></ul><p>Le site existe : pages produits, prix, promotions… et surtout quelques calculs métier (ex : prix ajusté selon l’état des planches, réductions, etc.). Tant que le trafic est faible, tout va bien.</p><p>Mais quand “Paris devient une station balnéaire” (clin d’œil narratif), la charge grimpe. Et c’est exactement là que les problèmes apparaissent : latence, requêtes lourdes, ressources limitées, et parfois des temps de réponse qui se dégradent de façon spectaculaire.</p><h3>Le terrain de jeu : un benchmark local, mais réaliste</h3><p>Axel a construit une démo testable en local, pour simuler une montée en charge de manière reproductible :</p><ul><li>Docker pour isoler l’environnement</li><li>Caddy (web server)</li><li>PHP-FPM (choix volontairement classique)</li><li>PostgreSQL</li><li>Symfony 7.4, PHP 8.4</li><li>Doctrine (ORM)</li><li>K6 pour les tests de charge (script en JavaScript)</li><li>Prometheus + Grafana pour visualiser les métriques</li></ul><p>Point important : pour rendre les résultats parlants, le container PHP-FPM est volontairement limité à 1 CPU et 512 MB RAM. Une contrainte qui met immédiatement en évidence les limites… et l’effet des optimisations.</p><h3>Niveau 1 : le cache “côté PHP” (OPcache, JIT, APCu, Realpath, Composer)</h3><p>Axel commence par un rappel utile : avant même d’écrire une seule ligne de cache applicatif, PHP dispose déjà de plusieurs mécanismes.</p><h2>OPcache : le levier principal</h2><p>OPcache compile le PHP en opcode, évitant de reparser et recompiler à chaque requête. C’est souvent l’optimisation la plus rentable… à condition qu’elle soit bien configurée.</p><p>Deux fonctionnalités clés sont mises en avant :</p><ul><li>Preloading : charger au démarrage un ensemble de scripts/classes en mémoire (Symfony fournit un fichier de preload en prod).</li><li>JIT (Just-In-Time) : compilation à la volée (souvent désactivée par défaut), utile dans certains scénarios mais à évaluer.</li></ul><p>Axel insiste sur un point pratique : OPcache est excellent en prod, mais peut être pénible en dev si certaines options empêchent la détection des changements de fichiers (ex : désactiver la validation par timestamp).</p><h2>APCu : une mémoire vive accessible au code</h2><p>APCu fournit un store clé/valeur en RAM, très rapide. Contrairement à OPcache, il ne fait rien “tout seul” : il est utile si ton code/framework/bundle l’exploite.</p><h2>Realpath cache</h2><p>Cache interne à PHP qui accélère la résolution de chemins (utile dans des traitements fichiers intensifs).</p><h2>Composer : optimiser l’autoload</h2><p>Composer peut générer une classmap optimisée, et même utiliser APCu pour accélérer l’autoload. Certaines options (“authoritative classmap”) peuvent être très performantes, mais attention aux classes générées dynamiquement selon les projets.</p><h3>Niveau 2 : le cache applicatif (PSR-6/PSR-16, adapters, warmup, tags)</h3><p>Axel enchaîne sur le cache au niveau “application”, c’est-à-dire ce que l’équipe met explicitement en place.</p><h2>Standards : PSR-6 vs PSR-16</h2><ul><li>PSR-6 : notion de <em>cache pool</em> + <em>cache items</em> (souvent rencontré via Symfony).</li><li>PSR-16 : interface plus simple “clé/valeur”.</li></ul><p>Ces standards ne sont pas ennemis : des adaptateurs permettent l’interopérabilité.</p><h2>Où stocker ?</h2><p>Même avec une API standard, il faut un stockage :</p><ul><li>Redis</li><li>APCu</li><li>filesystem</li><li>base de données</li><li>structures en mémoire PHP (selon cas)</li></ul><p>Le choix dépend surtout des contraintes (latence, volumétrie, distribution, coûts).</p><h2>Warmers / Clearers : préchauffer plutôt que subir le “premier hit”</h2><p>Axel rappelle un point sous-estimé : les apps “chauffent” souvent au premier utilisateur. Symfony propose un mécanisme pour :</p><ul><li>nettoyer proprement certains caches lors d’un <code>cache:clear</code>,</li><li>pré-remplir certains caches lors d’un warmup (éviter que le premier visiteur subisse le temps de calcul complet).</li></ul><h2>Tags : invalider par groupe</h2><p>Le cache “intelligent” se joue souvent sur l’invalidation. Les tags permettent de regrouper des entrées cohérentes :</p><ul><li>ex : toutes les promotions</li><li>ex : tout ce qui dépend d’un produit</li><li>ex : un fragment partagé par plusieurs pages</li></ul><p>Et donc d’invalider “en bloc” quand une modification survient.</p><h3>Observer avant d’optimiser : profiler + métriques</h3><p>Une partie très concrète du talk : mesurer, pas deviner.</p><ul><li>Symfony Profiler permet de voir les reads/writes cache, les pools utilisés, les hits/miss.</li><li>Avec <code>Stopwatch</code>, on peut instrumenter des étapes internes (ex : temps de récupération Doctrine, temps de formatage des données).</li></ul><p>Le premier test de charge, dans un contexte peu optimisé (et même lancé en dev), montre un résultat typique :</p><ul><li>une moyenne “pas honteuse”</li><li>mais des p95/p99 catastrophiques (des requêtes qui montent à plusieurs secondes)</li><li>et un objectif de latence non atteint (ex : “95% &lt; 500ms” très loin du compte)</li></ul><p>Ce point est important : une application peut sembler “fluide” à la main… et s’effondrer sous contrainte.</p><h3>Doctrine : metadata, query cache, result cache… et second-level cache</h3><p>Axel consacre ensuite un passage à Doctrine, sujet vaste et souvent mal maîtrisé dans ses subtilités.</p><h2>Les caches Doctrine “classiques”</h2><ul><li>metadata cache : mapping entités → colonnes/relations</li><li>query cache : DQL → SQL</li><li>result cache : résultat d’une requête (à activer explicitement)</li></ul><p>Le result cache est intéressant mais piège classique : si la requête contient des paramètres “instables” (ex : <code>new DateTime()</code>), la clé interne peut varier et conduire à un cache qui grossit de façon inattendue.</p><p>Axel partage un retour terrain très parlant : en préparant le talk, il a dû déterrer une vieille issue et diagnostiquer un cas où une clé semblait “identique”, mais où Doctrine construisait en réalité des clés internes différentes ce qui provoquait des écritures répétées et une croissance non désirée.</p><h2>Second-level cache</h2><p>Différent du result cache : il cache les entités et leurs associations, avec une configuration par régions. Puissant, mais la stratégie d’invalidation peut devenir complexe : prudence sur les TTL trop élevés tant que le comportement exact n’est pas parfaitement maîtrisé et testé.</p><h3>Niveau 3 : le cache HTTP (navigateur, proxy, CDN)</h3><p>Après le cache “dans l’app”, Axel rappelle une évidence souvent oubliée :</p><blockquote><p>Si la requête atteint ton serveur, même un hit cache consomme des ressources.</p></blockquote><p>Le cache HTTP permet de stopper la requête avant l’application.</p><h2>Deux grandes familles</h2><ul><li>Cache navigateur : assets, mais aussi pages entières selon contexte</li><li>Cache partagé : proxy/CDN (Varnish, Cloudflare…), capable de servir du HTML figé à très haute cadence</li></ul><p>Avec <code>Cache-Control</code>, on contrôle les directives :</p><ul><li>expiration (<code>max-age</code>)</li><li>revalidation (<code>must-revalidate</code>, <code>no-cache</code>)</li><li>stockage (<code>no-store</code>)</li><li>public/privé (attention aux pages personnalisées)</li></ul><p>Axel glisse une précision utile : <code>no-cache</code> ne veut pas dire “ne cache pas”, mais “revalide”. Pour interdire le stockage, c’est <code>no-store</code>.</p><h2>Fragments et pages composées</h2><p>Pour les pages mixtes (parties communes + parties personnalisées), Axel évoque des techniques de fragmentation :</p><ul><li>ESI (Edge Side Includes)</li><li>SSI</li><li>h-include (chargement côté client via JS)</li></ul><p>Objectif : cacher agressivement ce qui est mutualisable, sans exposer des données personnalisées à un cache partagé.</p><h3>Le vrai sujet : la stratégie (expiration, purge, coûts, risques)</h3><p>La conclusion du talk est probablement la plus importante : le cache devient vite une usine à gaz si on le pousse sans méthode.</p><p>Axel partage un retour d’expérience en contexte média : à force de tags hyper granulaires (tag global + tag par entité), l’invalidation devient lourde, fragile, et coûteuse. La solution la plus robuste adoptée finalement : TTL courts + expiration plutôt que purge permanente.</p><p>Il mentionne aussi des problèmes réels qu’on rencontre à grande échelle :</p><ul><li>“cache stampede” : 100k requêtes arrivent au moment où le cache expire, et toutes recomputent en même temps</li><li>arbitrage mémoire vs disque</li><li>pertinence : <em>tout ne mérite pas d’être caché</em></li></ul><p>D’où la phrase de synthèse proposée :</p><blockquote><p>Trouver une bonne ration entre besoin, coûts et risques.</p></blockquote><p>Et un cycle pragmatique :</p><ol><li>monitorer (mesures réelles)</li><li>analyser (profiler, tests de charge)</li><li>cibler (route critique business)</li><li>planifier (petits incréments, objectifs réalistes)</li><li>déployer</li><li>mesurer l’impact, recommencer</li></ol><h2>Résultat : un gain massif… sur une machine contrainte</h2><p>Avec les optimisations activées (OPcache/config prod, caches Doctrine, tuning Symfony, etc.), la démo montre un bond spectaculaire sur la charge supportée : sur la même machine limitée, la capacité monte à plusieurs centaines de requêtes/s, avec une nette amélioration des latences.</p><p>Le message final est clair :
le cache peut multiplier la performance… mais uniquement si on mesure, si on choisit le bon niveau, et si on garde une stratégie simple.</p><h2>Algolia, un cadre propice aux échanges techniques</h2><p>L’événement s’est tenu chez Algolia, acteur reconnu de la recherche et de l’indexation en temps réel. Leur positionnement, centré sur la vitesse, la pertinence et la scalabilité, faisait écho direct aux thématiques abordées durant la soirée.</p><p>Au-delà des conférences, le lieu a favorisé les échanges informels autour d’un verre, prolongeant les discussions sur les choix technologiques, les retours d’expérience et les tendances actuelles du développement PHP.</p><h2>Conclusion</h2><p>Ce meetup de clôture 2025 a parfaitement illustré deux réalités du développement moderne :</p><ul><li>tous les projets n’ont pas besoin d’un framework lourd,</li><li>la performance ne s’improvise pas, elle se conçoit.</li></ul><p>Entre minimalisme assumé et optimisation pragmatique, cette soirée AFUP Paris a rappelé l’importance de choisir les bons outils au bon moment, tout en cultivant une réflexion collective sur la qualité et la durabilité des applications.</p><p>Un rendez-vous de plus qui confirme la vitalité de la communauté PHP parisienne.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/meetup-afup-paris-decembre-2025</link><guid>https://blog.darkwood.com/article/meetup-afup-paris-decembre-2025</guid><enclosure url="http://darkwood.com/media/articles/69448f080a291719322473.png" /></item><item><title>🎄Christmas Offer – Automation with Flow in PHP</title><pubDate>Wed, 24 Dec 2025 12:56:33 +0000</pubDate><description><![CDATA[Christmas Offer – Automation with Flow in PHP
For the holiday season, Darkwood is offering a special Christmas deal on its Automation with Flow training in PHP.
This training is aimed at PHP developers who want to go beyond classic architectures, structure...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/694be3020f94c607581960.png" /></p><h1>Christmas Offer – Automation with Flow in PHP</h1><p>For the holiday season, Darkwood is offering a special Christmas deal on its Automation with Flow training in PHP.</p><p>This training is aimed at PHP developers who want to go beyond classic architectures, structure their applications around explicit pipelines and adopt principles from functional programming to gain readability, reliability and maintainability.</p><h2>Why Flow?</h2><p>Modern programming increasingly relies on mastering data flows. Flow (formerly <em>Railway-Flow-Based-Programming</em>) is an approach inspired by <em>Railway Oriented Programming</em>, where processes are chained together in the form of clear and deterministic pipelines.</p><p>Each step explicitly transforms the data, with error handling integrated into the flow itself. This approach facilitates:</p><ul><li>understanding complex processes, * separation of responsibilities, * reuse of components, * reduction of side effects.</li></ul><p>Flow is particularly suited to systems where stability, predictability and robustness are key criteria.</p><h2>Functional Programming Applied in PHP</h2><p>The training explores the integration of functional programming principles into the PHP ecosystem:</p><ul><li>pure functions, * immutability, * higher-order functions, * composition and declarative pipelines.</li></ul><p>These concepts allow for the design of more predictable and less error-prone applications, while remaining compatible with the constraints and real-world uses of PHP in production.</p><h2>Recursion and Y-Combinator in PHP</h2><p>PHP does not inherently facilitate functional recursion, especially in the context of anonymous functions. This course introduces the Y Combinator, a concept from lambda calculus, which allows for the definition of anonymous recursive functions.</p><p>This approach paves the way for more expressive and reusable code structures, particularly for:</p><ul><li>complex recursive processing, * dynamic pipelines, * advanced iterative transformations.</li></ul><h2>Chunk computing and performance</h2><p>Chunk computing involves breaking down large processes into smaller segments to optimize resource usage.</p><p>Applied to PHP and combined with Flow, this model allows:</p><ul><li>improved memory management, * more responsive processing, * more stable execution on large volumes of data.</li></ul><p>This is a particularly relevant approach for automation, massive imports, or intensive transformation pipelines.</p><h2>Lambda Interpreter and <em>code as data</em> approach</h2><p>The course also offers the implementation of a Lambda interpreter in PHP, inspired by Church's lambda calculus.</p><p>This interpreter allows you to:</p><ul><li>manipulate functional expressions in the form of strings, * dynamically evaluate transformations, * experiment with currified combinators and calls.</li></ul><p>Integrated into Flow, this tool offers a new perspective: functions become entities that can be manipulated, tested and composed dynamically, bringing the architecture closer to a <em>code as data</em> model.</p><h2>A training program focused on sustainable architecture</h2><p>This training is not limited to isolated examples. It aims to transmit a methodology and a way of thinking about data flows, transformation, performance and maintainability in modern PHP applications.</p><p>It is aimed at developers who wish to:</p><ul><li>structuring complex systems, * improving the quality of existing code, * exploring advanced concepts while remaining pragmatic.</li></ul><h2>🎄 Christmas Special Offer</h2><p>As part of the holiday season, Darkwood is offering an exceptional deal:</p><ul><li>€69 * One-time payment (no subscription) * Offer valid until December 31st inclusive</li></ul><p>👉 Access the training: <a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php?p=pri_AZzJ_7623">https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php?p=pri_AZzJ_7623</a></p><h3>About Darkwood</h3><p>Darkwood supports developers and organizations in designing sustainable software architectures based on clear, measurable, and controlled principles.</p><p>The objective: to understand the technical foundations for building robust, scalable and truly maintainable systems over time.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/christmas-offer-automation-with-flow-in-php</link><guid>https://blog.darkwood.com/article/christmas-offer-automation-with-flow-in-php</guid><enclosure url="http://darkwood.com/media/articles/694be3020f94c607581960.png" /></item><item><title>⭐️ Reach Legend rank with the Bubule Aggro Paladin deck</title><pubDate>Fri, 26 Dec 2025 13:11:40 +0000</pubDate><description><![CDATA[
Reaching Legend level in Hearthstone during the holidays can quickly become time-consuming. However, some strategies allow you to grind efficiently without spending hours on it. In this article, I present a &amp;quot;Bubble&amp;quot; Aggro Paladin deck, designed f...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/694e898d0c5a1082847849.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/a9p8QI7pock?si=AFT06IfcdJO2K27n" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Reaching Legend level in Hearthstone during the holidays can quickly become time-consuming. However, some strategies allow you to grind efficiently without spending hours on it. In this article, I present a &quot;Bubble&quot; Aggro Paladin deck, designed for fast games, constant pressure, and maximum accessibility in terms of crafting.</p><h2>🎯 Deck Objective</h2><p>The Bubule Paladin is an aggressive, board-oriented deck with a simple objective:</p><ul><li>Take the board early * Maintain pressure with divine shields and healing * Snowball with progressive buffs * Finish the game before the opponent stabilizes</li></ul><p>This is a perfectly suited deck:</p><ul><li>on the ladder * in short sessions * with a steady climb to Diamond/Legend</li></ul><h2>🧠 Philosophy of play</h2><p>The deck rests on three pillars:</p><h3>1️⃣ Permanent presence on the board</h3><p>All cards cost 4 mana or less, which allows you to:</p><ul><li>Play multiple cards per turn * Repose quickly after clearing * Force the opponent to trade rather than develop their game plan</li></ul><h3>2️⃣ “Bubble” effect: resilience and sustain</h3><p>The name <em>Bubule</em> comes from the deck's ability to make the board difficult to clear:</p><ul><li>Increased health points * Divine shields * Effects triggered at the end of the turn</li></ul><p>The opponent can deal with one creature… but rarely the entire board.</p><h3>3️⃣ Delayed Buffs and Key Turn Preparation</h3><p>Some maps require you to plan ahead:</p><ul><li>We prepare a board * We force unfavorable trades * We trigger the buff at the right time</li></ul><p>It's a simple deck to learn, but it rewards reading the tempo.</p><h2>🔑 Key cards in the deck</h2><h3>🟢 Yesterloc</h3><p>A key component of the deck:</p><ul><li>Increases overall board survivability * Forces opponents to deal quickly * Excellent synergy with tokens</li></ul><h3>🟢 Hatching Ceremony</h3><p>Central map of the “bubble” plan:</p><ul><li>Delayed buff (+2/+2) * Requires preparation from the previous turn * Transforms a harmless board into a win condition</li></ul><h3>🟢 Zilliax (customizable)</h3><p>The deck's only legendary figure:</p><ul><li>Provides sustain * Tempo * and additional damage</li></ul><p>Adapt according to your style (more aggressive or more defensive).</p><h2>📊 Match-ups observed</h2><p>During the games played:</p><ul><li>✅ Hunter: very good matchup if the board is contested early * ⚠️ OTK/Mid Warlock: requires speed, without overcommit * ⚠️ Lich King/Mid Death Knight: lethality management and calculation are essential * ❌ Heavily healed and control-oriented decks: more challenging in the long run</li></ul><p>The deck shines especially against slow lists or those poorly equipped to handle a wide board.</p><h2>💸 Cost and accessibility</h2><p>This is one of the great advantages of the Bubule Paladin:</p><ul><li>Mostly common * A few rare/epic ones * Only one legendary one (Zilliax)</li></ul><p>👉 Very accessible deck, ideal for:</p><ul><li>New players * Game feedback * Secondary accounts</li></ul><h2>📋 Deck Code</h2><pre><code>AAECAZ8FAtSeBsekBg7JoASe1ASU9QWV9QXeugaf4Qbt5gbI/walhQfXlwe8mgeNnQeErQeKsQcAAQPzswbHpAb2swbHpAbo3gbHpAYAAA==
</code></pre><p>👉 To be copied directly into Hearthstone.</p><h2>👀 Sources</h2><p>Original deck from Woodchuck FR in <a href="https://www.youtube.com/watch?v=MgXIkbmPtW4">this Youtube Video</a></p><h2>🏁 Conclusion</h2><p>The Aggro Paladin Bubule deck is:</p><ul><li>simple * fast * economical * efficient for ladders</li></ul><p>Perfect for enjoying the holidays, playing game after game, and aiming for legend without frustration.</p><p>Happy grinding, and happy holidays on Hearthstone 🎄</p>
]]></content:encoded><link>https://blog.darkwood.com/article/reach-legend-rank-with-the-bubule-aggro-paladin-deck</link><guid>https://blog.darkwood.com/article/reach-legend-rank-with-the-bubule-aggro-paladin-deck</guid><enclosure url="http://darkwood.com/media/articles/694e898d0c5a1082847849.jpg" /></item><item><title>⭐️ Rise to Legend with the Warrior Quest (Enter the Lost City)</title><pubDate>Wed, 31 Dec 2025 15:35:52 +0000</pubDate><description><![CDATA[
In this article, I present a Quest Warrior deck that is very present in the current Hearthstone meta, which I use to grind the ladder to Legend.
It&#039;s a slow, defensive deck, sometimes frustrating for the opponent to play, but extremely stable if your objec...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69554316c1edf564390427.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/mjuFZwDTHY4?si=dY_jtk_R62YjkI2p" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>In this article, I present a Quest Warrior deck that is very present in the current Hearthstone meta, which I use to grind the ladder to Legend.</p><p>It's a slow, defensive deck, sometimes frustrating for the opponent to play, but extremely stable if your objective is clear: survive, stall, then win by attrition.</p><h2>🧭 The heart of the deck: <em>Enter the Lost City</em></h2><p>The entire strategy revolves around the quest:</p><blockquote><p>Enter the Lost City &gt; 🎯 <em>Survive for 10 turns</em> &gt; 🏆 <em>Reward: a card that generates massive value</em></p></blockquote><p>The goal is not to win quickly, but to hold out long enough to turn the game in your favor thanks to a structural advantage.</p><h2>🛡️ Overall Game Plan</h2><p>The Warrior Quest is played in several very distinct phases:</p><h3>Early game: survival above all</h3><ul><li>Build up armor * Draw wisely * Never panic under pressure</li></ul><p>Every life point and every card counts.</p><h3>Mid-game: stall and control</h3><ul><li>Use of removals (Brawl, targeted clears) * Management of large boards * Destruction of locations (very important in the current meta)</li></ul><p>👉 Demolish Renovator is a key card here, especially against decks that rely on Elise or repeated rentals.</p><h3>Late game: value and locking in</h3><p>Once the quest is completed:</p><ul><li>You generate more resources than your opponent * You force unfavorable trades * You often win without ending the game &quot;violently&quot;</li></ul><p>It's a deck that exhausts the other player.</p><h2>🃏 Key cards and important choices</h2><h3>🧱 Armor Accumulation</h3><p>The deck relies on numerous cards that allow you to:</p><ul><li>Gain armor * Draw cards simultaneously * Buy time for several consecutive turns</li></ul><p>This is what allows you to get through turns 4-5, which are often critical against aggro.</p><h3>⚙️ Zilliax (Lifesteal version)</h3><p>Zilliax is played here in the following version:</p><ul><li>Divine Shield * Lifesteal * Summon a Copy</li></ul><p>An essential tool against aggressive decks to raise life points and regain control.</p><h3>🔥 Ragnaros (replacement)</h3><p>Some key legendary cards (like Elise) may be missing depending on your collection.</p><p>👉 In this case, Ragnaros remains a very good replacement for:</p><ul><li>Apply pressure * Force responses * Create immediate threat</li></ul><h3>🐉 Ysera &amp; late game</h3><p>Ysera allows:</p><ul><li>To increase maximum mana * To secure the late game * To compete with other control decks</li></ul><p>In some matchups, games can even reach up to 20 mana crystals.</p><h2>⚔️ Match-ups: what works (and what doesn't)</h2><h3>👍 Good matchups</h3><ul><li>Aggro decks * Fast Paladin (if well timed) * Mid-range Shaman (with good board control)</li></ul><h3>⚠️ Tough matchups</h3><ul><li>Mage (especially certain combo variants) * Mid/late game Warlock * Decks capable of quick OTKs</li></ul><p>👉 These matchups require excellent mulligan management and sometimes… a little bit of luck.</p><h2>📈 Ladder &amp; mental</h2><p>Between Diamond 5 and Legend, the pressure is clearly increasing:</p><ul><li>More tryharding * Fewer opponent mistakes * Longer games</li></ul><p>The good news: ✅ once you reach a milestone, you're secure ✅ the deck allows for steady progress, without constant tilt</p><h2>🌲 Darkwood Conclusion</h2><p>The Quest Warrior deck isn't flashy. It's slow, methodical, sometimes thankless… but incredibly effective.</p><p>If your goal is:</p><ul><li>Reaching Legend * Understanding the meta * Playing a deck that rewards discipline</li></ul><p>Then this deck is clearly made for you.</p><h2>🧾 Full Deck List – Quest Warrior 2.0</h2><p>Class: Warrior Format: Standard Year: Year of the Raptor Game: Hearthstone</p><h3>📜 Deck code (to be copied directly into the game)</h3><pre><code class="language-text">AAECAQcO0Z4GgJ8GhaAGx6QGjr8GquoGqfUGpIUHg4oH7o8HtpQH1JcH25cHhJ0HCIigBImgBI7UBIegBrDiBuqnB/yvB4+xBwABA/WzBsekBvezBsekBujeBsekBgAA
</code></pre><p>👉 How to use it: Copy the code → open Hearthstone → Collection → New deck → the deck is created automatically.</p><h2>Sources</h2><p>This article was inspired from the video from <a href="https://www.youtube.com/watch?v=EJCID03TQII">Woodchuck FR</a></p><h3>🃏 Map Details</h3><h4>🔑 Quest</h4><ul><li>1x (1) Enter the Lost City</li></ul><h4>🛡️ Defense / Armor / Pickaxe</h4><ul><li>2x (1) Shield Slam * 2x (2) Safety Goggles * 2x (2) Shield Block * 1x (3) All You Can Eat * 1x (3) Bulwark of Azzinoth</li></ul><h4>🧨 Board Management</h4><ul><li>2x (2) Precursory Strike * 1x (3) Demolition Renovator <em>(key against rentals)</em> * 2x (5) Brawl * 2x (5) Hostile Invader</li></ul><h4>🧠 Tempo / Utility</h4><ul><li>1x (2) Dirty Rat * 1x (2) Daydreaming Pixie * 2x (5) For Glory! * 1x (6) Bob the Bartender</li></ul><h4>🐉 Finishers &amp; late game</h4><ul><li>1x (8) Ragnaros the Firelord * 1x (8) The Great Dracorex * 1x (9) Botface * 1x (9) Ysera, Emerald Aspect * 1x (125) The Ceaseless Expanse</li></ul><h4>🤖 Zilliax Deluxe 3000 (configuration)</h4><ul><li><p>Divine Shield * Lifesteal * Summon a Copy * Modules:</p><ul><li>Twin Module * Perfect Module</li></ul></li></ul><p>➡️ Extremely strong against aggro, allows you to stabilize poorly started games.</p><h2>🎯 Mulligan – simple rules</h2><h3>Always keep</h3><ul><li>✅ Enter the Lost City * ✅ Shield Block * ✅ Safety Goggles * ✅ Shield Slam <em>(if you have armor)</em></li></ul><h3>Against aggro</h3><ul><li>✅ Hostile Invader * ✅ Precursory Strike * ❌ Late game cards (Ysera, Ragnaros…)</li></ul><h3>Counter control / midrange</h3><ul><li>✅ Card Pick * ✅ Mana Haste * ✅ Demolition Renovator <em>(if locations are likely)</em></li></ul><h2>🌲 Note Darkwood</h2><p>This deck is:</p><ul><li>❌ expensive in terms of dust * ❌ unspectacular * ❌ mentally demanding</li></ul><p>But in exchange:</p><ul><li>✅ Extremely stable * ✅ Very strong in long ladders * ✅ Excellent for tilt-free grinding Legend</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/rise-to-legend-with-the-warrior-quest-enter-the-lost-city</link><guid>https://blog.darkwood.com/article/rise-to-legend-with-the-warrior-quest-enter-the-lost-city</guid><enclosure url="http://darkwood.com/media/articles/69554316c1edf564390427.jpg" /></item><item><title>📝 IT Governance: Regaining Control Without Slowing Down Innovation</title><pubDate>Sun, 11 Jan 2026 22:12:33 +0000</pubDate><description><![CDATA[
Introduction — The problem is (almost never) technical
If you&#039;re a developer, you&#039;ve probably already experienced this:

Technical decisions made too late * Tool choices questioned after delivery * Priorities changing without explanation * Safety rules imp...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69642051ce15d694046677.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/tlwYy0JsamY?si=fAz6PUl-r_jlVyWm" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Introduction — The problem is (almost never) technical</h2><p>If you're a developer, you've probably already experienced this:</p><ul><li>Technical decisions made <strong>too late</strong> * Tool choices questioned <strong>after delivery</strong> * Priorities changing without explanation * Safety rules imposed “from above”</li></ul><p>And often, this is called:</p><blockquote><p>“an organizational problem” &gt; “a business problem” &gt; “a management problem”</p></blockquote><p>In reality, it's almost always an <strong>IT governance problem</strong>.</p><p>#1. IT Governance, Explained Simply</p><p>Let's forget about complex definitions.</p><p>IT governance is about clearly answering a simple question: Who decides what, when, and on what basis, regarding IT?</p><p>This includes, for example:</p><ul><li>Technology selection * Project prioritization * Performance/security/cost trade-offs * Acceptance (or rejection) of technical debt</li></ul><p>👉 <strong>Important</strong>: IT governance <strong>doesn't do the work</strong>. It <strong>organizes decisions</strong> around the work.</p><p>#2. IT Governance ≠ IT Management ≠ Development</p><p>This is a very common misconception, especially on the technical side.</p><p>| Level | Role | | ----------------------- | ---------------------------------- | | <strong>IT Governance</strong> | Decide <em>what</em> to do and <em>why</em> | | <strong>IT Management</strong> | Organize <em>how</em> to do it | | <strong>Development / Ops</strong> | Do |</p><p>Concrete example:</p><ul><li>❌ “The developer chooses the CI tool alone for the entire company” * ❌ “Management imposes a tool without understanding the constraints” * ✅ “Governance defines the criteria, the team chooses”</li></ul><p>👉 Good governance <strong>protects technical teams</strong> instead of constraining them.</p><p>#3. Why IT governance is essential (even for developers)</p><h3>3.1 Strategic Alignment (No Bullshit)</h3><p>Without clear governance:</p><ul><li>We optimize locally * We degrade globally</li></ul><p>With clear governance:</p><ul><li>The technical choices make sense. * The trade-offs are deliberate.</li></ul><h3>3.2 Creating value (not just delivering code)</h3><p>Delivering quickly ≠ delivering usefully.</p><p>Governance helps to address:</p><ul><li>Is this project truly worth the effort? * Should we build, buy, or abandon it? * Is it a prototype or a long-term foundation?</li></ul><h3>3.3 Risk Management (without paranoia)</h3><p>Security, compliance, technical debt…</p><p>Without governance:</p><ul><li>vague rules * decisions made under pressure</li></ul><p>With governance:</p><ul><li>Known risks * Explicit decisions * Clear responsibilities</li></ul><h3>3.4 Steering and Visibility</h3><p>Not to spy on people, but to:</p><ul><li>Understand where the energy goes * Know what's blocking it * Improve the system, don't blame people</li></ul><p>#4. The pillars of effective IT governance</p><h3>1️⃣ Explicit Decisions</h3><p>Who decides?</p><ul><li>The team? * The product? * Management? * A committee?</li></ul><p>👉 The important thing is not <em>who</em>, but that it is <strong>clear</strong>.</p><h3>2️⃣ Responsibilities assumed</h3><p>Every decision must have:</p><ul><li>a person in charge * a defined scope * a known impact</li></ul><h3>3️⃣ Simple Processes</h3><p>No need for a heavy framework.</p><p>A good process is:</p><ul><li>understandable * reproducible * improvable</li></ul><h3>4️⃣ Useful Indicators</h3><p>A good KPI is used to:</p><ul><li>decide * adjust * learn</li></ul><p>Not to look pretty in a slide.</p><h3>5️⃣ Feedback Loop</h3><p>A rigid governance structure quickly becomes toxic.</p><p>It's necessary :</p><ul><li>observe * adjust * correct</li></ul><h2>5. Concrete example (very detailed)</h2><h3>Situation without governance</h3><ul><li>Each team chooses its own tools * Proliferation of stacks * Unmanageable maintenance * Tensions between teams</li></ul><h3>Situation with light governance</h3><ul><li>Technical criteria defined together * Freedom <strong>within a framework</strong> * Traceable decisions * Fewer conflicts</li></ul><p>👉 Result: <strong>fewer pointless debates, more useful code.</strong></p><p>#6. Common mistakes to avoid</p><ul><li>Copying a &quot;turnkey&quot; framework (COBIT, ITIL, etc.) * Creating too many committees * Making decisions without the teams * Measuring without ever adjusting</li></ul><p>Frameworks like those supported by ISACA or AXELOS are <strong>tools</strong>, not magic solutions.</p><p>#7. Modern IT Governance (2026)</p><p>A governance model adapted to technical teams is:</p><ul><li><strong>lightweight</strong> * <strong>scalable</strong> * <strong>agile/product compatible</strong> * <strong>decision-oriented</strong>, not procedure-driven</li></ul><p>👉 It serves to <strong>smooth</strong>, not to slow down.</p><h2>Conclusion — Good governance ≠ less freedom</h2><p>IT governance is not a necessary evil. It is a <strong>tool for clarity</strong>.</p><p>For developers, good governance is key:</p><ul><li>Avoids absurd decisions * Protects good work * Makes innovation sustainable</li></ul><p>Less chaos, more meaning.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/it-governance-regaining-control-without-slowing-down-innovation</link><guid>https://blog.darkwood.com/article/it-governance-regaining-control-without-slowing-down-innovation</guid><enclosure url="http://darkwood.com/media/articles/69642051ce15d694046677.jpg" /></item><item><title>🔊 DJ Matyo Live – UK Hardcore / Happy Hardcore (January 2026)</title><pubDate>Tue, 13 Jan 2026 08:15:44 +0000</pubDate><description><![CDATA[
UK Hardcore and Happy Hardcore are not simply subgenres of electronic music. They constitute a sonic culture, founded on speed, melodic euphoria, and a direct link between musical energy and mental state. The DJ Matyo – Live UK Hardcore / Happy Hardcore (J...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6965ff30dd376116831476.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/h2vdCwHPaVE?si=aKPo_5bUstsjpmMp" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p><strong>UK Hardcore</strong> and <strong>Happy Hardcore</strong> are not simply subgenres of electronic music. They constitute a <strong>sonic culture</strong>, founded on speed, melodic euphoria, and a direct link between musical energy and mental state. The <strong>DJ Matyo – Live UK Hardcore / Happy Hardcore (January 2026)</strong> mix follows this logic: offering a <strong>continuous progression</strong>, conceived as a flow, rather than a series of independent tracks.</p><h2>An opening tribute: Bass-D</h2><p>The set opens with a tribute to <strong>Bass-D</strong>, a historical figure in the hardcore scene, who passed away earlier this year. The choice of the track <strong>Bass-D &amp; King Matthew feat. XD – <em>Like A Dream</em></strong> is not insignificant: it embodies a period when hardcore retained a strong <strong>emotional dimension</strong>, while also embracing high tempos.</p><p>This introduction sets a clear framework: the mix does not seek technical one-upmanship, but a <strong>narrative continuity</strong>, where each track extends the intention of the previous one.</p><h2>A deliberately hybrid construction</h2><p>The tracklist spans several aesthetic styles:</p><ul><li>Modern and uptempo Frenchcore * Eurodance and reworked pop bootlegs * Old-school hardcore references * Unapologetic remixes of mainstream tracks</li></ul><p>Artists like <strong>S3RL</strong>, <strong>Mr Bassmeister</strong>, <strong>Masta</strong>, <strong>Sghenny</strong>, <strong>Jiyagi</strong>, <strong>RDMA</strong> or <strong>Alpha Corp.</strong> illustrate this hybridization, where the boundary between underground culture and collective memory is deliberately blurred.</p><p>This diversity is not a stylistic effect: it serves a <strong>logic of tension and release</strong>, essential in high BPM music.</p><h2>The mix as a flow space</h2><p>In this set, the mix is designed as a <strong>flow space</strong>:</p><ul><li>Few abrupt breaks * Quick but clear transitions * A gradual build-up of intensity * A more structured hardstyle/hardcore-oriented ending</li></ul><p>This type of construction allows for active listening, but also functions as <strong>functional support</strong>: sport, concentration, intensive work or performance.</p><h2>A Darkwood Approach</h2><p>At Darkwood, music is approached as a <strong>system</strong>: an arrangement of constraints (tempo, energy, cultural references) producing a specific state in the listener.</p><p>This mix is part of this approach: to document, assemble and transmit a <strong>form of sonic knowledge</strong>, inherited from the rave, adapted to contemporary uses.</p><p>🎧 Mix by <strong>DJ Matyo</strong> 📅 January 2026 📺 Available on YouTube (full tracklist in description)</p>
]]></content:encoded><link>https://blog.darkwood.com/article/dj-matyo-live-uk-hardcore-happy-hardcore-january-2026</link><guid>https://blog.darkwood.com/article/dj-matyo-live-uk-hardcore-happy-hardcore-january-2026</guid><enclosure url="http://darkwood.com/media/articles/6965ff30dd376116831476.jpg" /></item><item><title>♾️ Infinity Discard Damage</title><pubDate>Sat, 17 Jan 2026 09:36:02 +0000</pubDate><description><![CDATA[
In Hearthstone, OTK decks rarely rely on a single card. Instead, they exploit systemic interactions, often unforeseen, between costs, global effects, and damage redirections.
The Infinity Discard Damage deck is an excellent example of this type of build: a...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/696b582015c12795592075.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/M3DxYKjkfKI?si=q9Fb44mgBJbSBbQn" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>In Hearthstone, OTK decks rarely rely on a single card. Instead, they exploit systemic interactions, often unforeseen, between costs, global effects, and damage redirections.</p><p>The Infinity Discard Damage deck is an excellent example of this type of build: a deterministic OTK, based on an artificial infinite value, transformed into global damage, then redirected to the opposing hero.</p><h2>General Principle</h2><p>The deck's objective is to create a card with infinite cost, then force its discard to trigger a damage effect proportional to that cost. This damage, applied to the board, is then redirected to the opponent's hero, resulting in an immediate one-turn kill (OTK), regardless of their health.</p><p>This mechanism is based on four key cards:</p><ul><li>Soulbound Ashtongue * Treachery * Acolyte of Infinity * Wing Welding</li></ul><h2>The building blocks of the system</h2><h3>1. Soulbound Ashtongue – Damage Redirection</h3><p>Soulbound Ashtongue introduces a simple but fundamental rule:</p><p>Each point of damage inflicted on the minion is also inflicted on its hero.</p><p>This card does not generate damage on its own, but acts as a consequence multiplier. It transforms any untargeted source of damage into direct lethal pressure.</p><h3>2. Treachery – Inversion of Ownership</h3><p>Treachery allows you to give an allied minion to the opponent.</p><p>In this deck, its role is strictly functional:</p><ul><li>Soulbound Ashtongue must belong to the opponent at the time of activation. * Damage dealt to the opponent's board will then be redirected to their hero, not yours.</li></ul><p>Without Treachery, the combo would be self-destructive.</p><h3>3. Acolyte of Infinity – Creating Infinite Value</h3><p>Acolyte of Infinity modifies a random card from your hand:</p><p>Its cost becomes INFINITE.</p><p>This point is crucial: the deck does not seek to inflict high damage, but to break the game's value scale.</p><p>From the moment a card has an infinite cost:</p><ul><li>Any cost-dependent mechanic becomes unbounded * The game no longer has a numerical cap on associated damage</li></ul><p>This is an injection of infinity into a finite system.</p><h3>4. Wing Welding – Cost-to-Damage Conversion</h3><p>Wing Welding applies the final transformation:</p><p>Discard the highest-cost card. Deal damage equal to its cost to ALL minions.</p><p>In a normal context, it's a board control spell. In this deck, it's a math converter:</p><pre><code>Infinite cost → infinite damage → entire board
</code></pre><p>If Soulbound Ashtongue is present on the opposing side, this damage is redirected entirely to the hero.</p><h2>Combo execution order</h2><p>The complete combo follows a strict sequence:</p><ol><li>Play Soulbound Ashtongue 2. Give the minion to the opponent with Treachery 3. Play Acolyte of Infinity to create a card with infinite cost 4. Cast Wing Welding 5. Discard the infinite card → infinite damage → OTK</li></ol><p>Note:</p><ul><li>The card made infinite by the Acolyte is random. * The deck therefore accepts a degree of variance, compensated by a strong card draw capacity.</li></ul><h2>Deck Architecture</h2><p>The rest of the list is built to serve the combo, without any detours:</p><h3>Pick and Acceleration</h3><ul><li>Kobold Librarian * Fracking * Free Admission * Sketch Artist</li></ul><p>Objective: to see the deck as quickly as possible.</p><h3>Stabilization and control</h3><ul><li>Scroll * Darkbomb * Drain Soul</li></ul><p>Allows you to survive against aggressive decks while maintaining flexible turns.</p><h3>Cost Reduction</h3><p>Emperor Thaurissan</p><p>Optional but critical in certain parts to make the combo playable earlier or under pressure.</p><h2>Why this deck works in Wild</h2><p>The Wild format allows:</p><ul><li>Aggressive draw engines * Unbounded cost effects * Outdated interactions not designed to coexist</li></ul><p>Infinity Discard Damage exploits precisely these vulnerabilities:</p><ul><li>No coded damage limit * No ceiling check * No native protection against infinite values</li></ul><p>The deck does not win through pressure, but through the logical collapse of the system.</p><h2>Decklist – Infinity Discard Damage (Warlock Wild)</h2><pre><code>AAEBAf0GAtYR474DDq0Q58sCxcwC8tACld4D56AEgLUEpuoE0/oFhJ4Go6AGmrMGhJkHyrIHAAA=
</code></pre><h2>👀 Sources</h2><p>Check the original video from <a href="https://www.youtube.com/watch?v=x-WWeVn5EP8">MarkMcKz</a></p><h2>Conclusion</h2><p>Infinity Discard Damage isn't simply an OTK deck. It's a demonstration of emergent design, where:</p><ul><li>an abstract value (the cost) * becomes a physical value (the damage) * then a direct victory condition</li></ul><p>This type of deck is a reminder that Hearthstone, despite its apparent simplicity, remains a programmable system, capable of producing extreme behaviors when its rules are combined without safeguards.</p><p>A clean OTK. Mathematically absurd. And perfectly functional.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/infinity-discard-damage</link><guid>https://blog.darkwood.com/article/infinity-discard-damage</guid><enclosure url="http://darkwood.com/media/articles/696b582015c12795592075.jpg" /></item><item><title>⚙️ Fosdem 2026: Signals From the Open Source Frontline</title><pubDate>Sun, 01 Feb 2026 18:46:15 +0000</pubDate><description><![CDATA[

FOSDEM 2026 marked my first on-site participation in the event, limited to the Saturday sessions. What immediately stands out is the scale: dozens of parallel tracks, hundreds of talks, and a constant need to make trade-offs. It becomes clear very quickly...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/697f9f777672c240014243.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/lxgISpFEMSM?si=Njo3Td4W1u6AMeOd" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4396.jpg" alt="IMG_4396.jpg" /></p><p>FOSDEM 2026 marked my first on-site participation in the event, limited to the Saturday sessions. What immediately stands out is the scale: dozens of parallel tracks, hundreds of talks, and a constant need to make trade-offs. It becomes clear very quickly that FOSDEM cannot be approached casually—without preparation, the sheer density of content turns into noise.</p><p>Spending a single day on site was enough to understand that the real challenge is not access to information, but selection. Choosing which rooms to prioritize, which talks to follow live versus asynchronously, and when to rely on the conference’s chat infrastructure becomes part of the experience. This article reflects that first-day perspective, combining direct observations with technical signals extracted from the sessions attended.</p><h3>1. Opening Keynote and Digital Sovereignty</h3><p>The opening keynote at <a href="https://fosdem.org/2026">FOSDEM 2026</a> framed digital sovereignty. A central concept introduced was <strong>&quot;FOSS in times of war, scarcity and (adversarial) AI&quot;</strong> or <strong>&quot;strategic computer rental&quot;</strong> describing the industry’s gradual shift toward cloud first strategies that optimize convenience at the cost of autonomy. This model reinforces structural dependencies on proprietary platforms, exposing users and organizations to unilateral changes, service shutdowns, or policy driven constraints.</p><p>From a systemic perspective, the <strong>software supply chain</strong> emerged as a primary attack surface. With an average European company depending on <strong>tens of thousands of software components</strong>, modern infrastructure increasingly resembles a Jenga tower: stable until a single, often invisible, block is removed. Incidents such as the XZ backdoor and similar long term infiltration strategies illustrate how supply chain weaknesses are exploited asymmetrically over time.</p><p>Rather than proposing regulation first responses, the keynote emphasized <strong>organizational structure</strong> as a core technical issue. In particular, <strong>steward owned organizations</strong> with explicit public interest missions were presented as a structural alternative to venture capital driven models, where short term exit incentives often conflict with long term infrastructure integrity.</p><h3>2. Scale, Density, and the Need for Preparation</h3><p>FOSDEM 2026 brought together <strong>more than 8,000 participants</strong>, with <strong>over 1,000 lectures across 65 devrooms</strong>, making it one of the densest open source technical gatherings in Europe. This was a first time attendance, limited to the <strong>first day only</strong>, which was sufficient to highlight a recurring constraint: FOSDEM cannot be approached opportunistically.</p><p>The sheer volume of parallel sessions makes real time decision making ineffective. Value extraction requires <strong>pre event preparation</strong>, including identifying specific tracks, speakers, and technical domains in advance. Without this, the conference quickly becomes an exercise in context switching rather than focused learning.</p><p>This density is mirrored in FOSDEM’s digital layer. The official chat platform, running on <strong>Matrix/Element</strong> and accessible via <a href="https://chat.fosdem.org">chat.fosdem.org</a>, extends discussions beyond physical rooms. It acts as a coordination layer for last minute changes, technical follow ups, and asynchronous exchanges an essential complement when physical attendance alone is insufficient.</p><h3>3. Tooling Evolution Over Hype</h3><p>Several sessions confirmed a broader trend: meaningful innovation in open source currently happens in <strong>foundational tooling</strong>, not in product layer novelty.</p><p><strong>Git v3</strong> discussions focused on extreme scale constraints, such as repositories with tens of millions of references. The adoption of the <strong>reftable backend</strong> enables atomic updates and consistent reference views, addressing long standing filesystem limitations. Explorations around <strong>content defined chunking</strong> for large objects also point toward reintegrating capabilities previously offloaded to external systems like Git LFS.</p><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4399.jpg" alt="Git" /></p><p>Similarly, <strong>Webview</strong> sessions emphasized <strong>portability and behavioral specification</strong> over new abstractions. Engineers are increasingly documenting platform divergences particularly between Android and iOS to define stable baselines for embedded web content. The interest in the <strong>Servo engine</strong> reflects a desire for decoupled, performance oriented components that are not tied to monolithic OS engines.</p><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4401.jpg" alt="Webview" /></p><p>In both cases, the emphasis is on <strong>maintenance, predictability, and scale</strong>, not disruption.</p><h3>4. Applied Systems Under Real World Constraints</h3><p>The <strong>Botronics</strong> presentation illustrated what applied engineering looks like when theory meets physical constraints. Designing a <strong>consumer grade autonomous golf trolley</strong> with a target price around <strong>€5,000</strong> forces constant trade offs between capability, reliability, and cost.</p><p>Key technical decisions were driven by operational reality:</p><ul><li>Migrating to <strong>Zenoh</strong> for shared memory communication reduced CPU usage by approximately <strong>10%</strong>, improving thermal and energy efficiency.</li><li><strong>Balena</strong> was adopted for OTA updates to avoid the operational complexity of maintaining custom Yocto based images across a device fleet.</li><li>Operating in uncontrolled outdoor environments shifted the focus toward <strong>robust localization and computer vision based obstacle detection</strong>, deliberately avoiding costly sensor stacks like LiDAR.</li></ul><p>This was not a talk about innovation for its own sake, but about <strong>engineering discipline under constraint</strong>.</p><h3>5. Direct Feedback Loops: The Joplin Case</h3><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4402.jpg" alt="Joplin stand" /></p><p>One of the structural strengths of FOSDEM remains direct access to maintainers. Conversations with <a href="https://www.linkedin.com/in/laurentcozic/"><strong>Laurent Cozic</strong></a>, creator of <a href="https://joplinapp.org"><strong>Joplin</strong></a>, and <a href="https://www.linkedin.com/in/greg-lagarde-7a8440158/"><strong>Greg Lagarde</strong></a>, Marketing Lead at Joplin, provided concrete insight into the evolution of the project particularly the [<strong>open source Joplin web application</strong>](https://github.com/joplin/web app), currently in beta.</p><p>These exchanges enable feedback that goes beyond issue trackers, especially around synchronization models, cross platform consistency, and real world usage patterns. This aligns with prior Darkwood articles documenting Joplin as a daily knowledge management tool, including:</p><ul><li><a href="https://blog.darkwood.com/fr/article/joplin"><em>Introduction to Joplin</em></a></li><li><a href="https://blog.darkwood.com/index.php/fr/article/automatise-la-creation-de-notes-dans-joplin-1"><em>Automating note creation in Joplin</em></a></li></ul><p>The interaction reinforced Joplin’s positioning as a <strong>sovereign personal knowledge system</strong>, where control over data, formats, and workflows remains central. You can have an overview on the <a href="https://www.youtube.com/@joplinapp">Youtube channel</a>.</p><h3>6. Automation, AI, and the Toolchain Mindset</h3><p>AI discussions at FOSDEM were notably pragmatic. Rather than framing AI as a cognitive replacement, several conversations echoed the keynote’s warning about <strong>delegating thinking itself</strong>, sometimes described as a path toward &quot;digital dementia.&quot;</p><p>Instead, attention focused on <strong>AI as infrastructure augmentation</strong>:</p><ul><li>Using plugins such as <a href="https://joplinapp.org/plugins/plugin/joplin.plugin.alondmnt.jarvis/"><strong>Jarvis</strong></a> for contextual assistance within notes</li><li>Exploring <a href="https://github.com/alondmnt/joplin-mcp"><strong>MCP based integrations</strong></a> to connect note systems with local or self hosted language models</li><li>Keeping AI workloads <strong>local, containerized, and auditable</strong>, avoiding opaque SaaS dependencies</li></ul><p>In this framing, AI is treated as a <strong>janitorial layer</strong> handling repetitive or structural tasks rather than as an authoritative source of truth.</p><h3>7. Ecosystem, Campus, and Physical Reality</h3><p>The presence of foundational distributions <strong>Ubuntu, Debian, Nix</strong> at FOSDEM highlights the layered nature of the open source ecosystem. These projects form the substrate upon which higher level innovation depends.</p><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4390.jpg" alt="Ubuntu" /><img src="/blog/images/articles/2026-01-fosdem/IMG_4391.jpg" alt="Nix" /></p><p>The <strong>Université Libre de Bruxelles (ULB) Solbosch campus</strong>, located roughly <strong>30 minutes from Brussels city center</strong> via metro and bus, provides a fitting physical counterpart to this layered structure: large, decentralized, and occasionally challenging to navigate. Its scale reinforces the need for intentional movement both physically and intellectually through the event.</p><p>Beyond talks and stands, FOSDEM also functions as a convergence point for informal, in person encounters. These unstructured exchanges often surface governance concerns, long term project directions, and ecosystem tensions that rarely appear in formal presentations.</p><p><img src="/blog/images/articles/2026-01-fosdem/IMG_4393.jpg" alt="ULB" /></p><h3>Conclusion</h3><p>FOSDEM 2026 confirms a broader shift within open source: away from fragmented innovation and toward <strong>integrated, resilient, and sovereign infrastructures</strong>. The most critical work today happens in areas that are often considered unglamorous tooling, maintenance, governance, and dependency management.</p><p>Extracting value from such an ecosystem requires <strong>preparation, selectivity, and ecosystem literacy</strong>. FOSDEM does not reward passive consumption. It rewards those who approach it as a system to be navigated, not an event to be attended.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/fosdem-2026-signals-from-the-open-source-frontline-1</link><guid>https://blog.darkwood.com/article/fosdem-2026-signals-from-the-open-source-frontline-1</guid><enclosure url="http://darkwood.com/media/articles/697f9f777672c240014243.jpg" /></item><item><title>🚨 Darkwood IaExceptionBundle — When errors start explaining themselves</title><pubDate>Sun, 08 Feb 2026 22:40:14 +0000</pubDate><description><![CDATA[
Errors are not the problem. Silence is.
Every backend developer knows HTTP 500 errors. They happen. They are inevitable. And when they occur, the system usually does what it has done for decades:

Crash. Log. Move on.

But what if an error could do more th...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/698910e3d0a4d761490836.png" /></p><p><img src="https://blog.darkwood.com/blog/images/articles/2026-02-08-darkwood-ia-exception-bundle/error-page-screenshot.png" alt="error-page-screenshot.png" /></p><p>Errors are not the problem. <strong>Silence is.</strong></p><p>Every backend developer knows HTTP 500 errors. They happen. They are inevitable. And when they occur, the system usually does what it has done for decades:</p><blockquote><p>Crash. Log. Move on.</p></blockquote><p>But what if an error could do more than fail?
What if it could <strong>explain itself</strong>?</p><p>That’s the origin of <strong>Darkwood IaExceptionBundle</strong>: a Symfony bundle that augments HTTP 500 errors with AI-generated explanation, probable causes, and suggested fixes, built on top of <a href="https://ai.symfony.com"><strong>Symfony AI</strong></a></p><h2>🧭 The observation</h2><p>Modern frameworks are excellent at:</p><ul><li>throwing precise exceptions</li><li>producing stack traces</li><li>exporting logs to observability platforms</li></ul><p>Yet the responsibility of <em>understanding</em> an error is still delegated to humans.</p><p>The system knows:</p><ul><li>which exception was thrown</li><li>where it happened</li><li>under which conditions</li></ul><p>But it remains silent. The developer must reconstruct meaning from fragments.</p><h2>🧠 A simple idea</h2><p>Instead of asking:</p><blockquote><p><em>How do we fix errors automatically?</em></p></blockquote><p>We asked something more modest:</p><blockquote><p><strong>What if the system could explain what just happened — in human terms?</strong></p></blockquote><p>Not to replace debugging tools.
Not to repair anything.
Just to <strong>formulate hypotheses</strong> faster.</p><h2>⚙️ Why Symfony?</h2><p>Symfony is uniquely positioned for this kind of experiment:</p><ul><li>a single, well-defined runtime</li><li>an explicit <code>kernel.exception</code> extension point</li><li>a culture of opt-in bundles</li><li>and now, a first-class integration point via <a href="https://ai.symfony.com"><strong>Symfony AI</strong></a></li></ul><p>This is not a “core framework feature” — and it shouldn’t be.
It must stay <strong>opt-in, bounded, reversible</strong>.</p><h2>🧩 What the bundle does (and does not do)</h2><h3>✅ What it does</h3><p>On HTTP 500, the bundle can generate:</p><ul><li>a clear English explanation of the exception</li><li>probable causes</li><li>suggested fixes / next steps</li><li>a confidence score</li><li>an error ID for correlation</li></ul><h3>❌ What it does not do</h3><ul><li>It does <strong>not</strong> fix bugs.</li><li>It does <strong>not</strong> replace Sentry/logs.</li><li>It does <strong>not</strong> claim certainty.</li><li>It does <strong>not</strong> run unless enabled.</li></ul><p>It’s an assistant, not an authority.</p><h2>🔐 Safety first (non-negotiable)</h2><p>Errors can contain sensitive details. That’s why the bundle is designed to be safe-by-default:</p><ul><li>It never sends headers, cookies, env vars, or request payloads to the model</li><li>Stack traces are excluded by default (dev-only opt-in)</li><li>If the AI fails or times out: Symfony’s default 500 handling runs as usual (fail-safe)</li><li>The response status remains <strong>500</strong>; only the body is augmented</li></ul><h2>📦 Install &amp; use it in an existing Symfony project</h2><h3>Requirements</h3><ul><li>PHP 8.2+</li><li>Symfony 6.4+ also compatible with 7.x / 8.x</li><li>A configured <strong>symfony/ai-bundle</strong> platform + agent</li></ul><h3>1) Install the bundle</h3><pre><code class="language-bash">composer require darkwood/ia-exception-bundle
</code></pre><h3>2) Register the bundle (if needed)</h3><p>If Symfony Flex doesn’t auto-register it, add it to <code>config/bundles.php</code>:</p><pre><code class="language-php">return [
    // ...
    Darkwood\IaExceptionBundle\DarkwoodIaExceptionBundle::class =&gt; ['all' =&gt; true],
];
</code></pre><h3>3) Configure Symfony AI</h3><p>Example OpenAI configuration:</p><pre><code class="language-yaml"># config/packages/ai.yaml
ai:
  platform:
    openai:
      api_key: '%env(OPENAI_API_KEY)%'
  agent:
    default:
      model: 'gpt-4o-mini'
</code></pre><h3>4) Enable and configure the bundle</h3><pre><code class="language-yaml"># config/packages/darkwood_ia_exception.yaml
darkwood_ia_exception:
  enabled: true
  only_status_codes: [500]
  agent: 'ai.agent.default'
  timeout_ms: 800
  cache_ttl: 600
  cache: 'cache.app'
  include_trace: false
</code></pre><h3>5) Enforce the timeout properly</h3><p>To guarantee the timeout at the HTTP layer, configure a scoped HTTP client for your AI platform:</p><pre><code class="language-yaml"># config/packages/ai.yaml
framework:
  http_client:
    scoped_clients:
      ai.timeout_client:
        base_uri: 'https://api.openai.com'
        timeout: 0.8

ai:
  platform:
    openai:
      api_key: '%env(OPENAI_API_KEY)%'
      http_client: 'ai.timeout_client'
</code></pre><h2>🧾 Output formats</h2><h3>JSON (for APIs)</h3><p>If the request includes <code>Accept: application/json</code>, the bundle returns structured JSON like:</p><pre><code class="language-json">{
  &quot;error_id&quot;: &quot;a1b2c3d4e5f6g7h8&quot;,
  &quot;english_exception&quot;: &quot;The database connection failed or a required table is missing.&quot;,
  &quot;probable_causes&quot;: [&quot;...&quot;],
  &quot;suggested_fixes&quot;: [&quot;...&quot;],
  &quot;confidence&quot;: 0.85
}
</code></pre><h3>HTML (default)</h3><p>Otherwise it renders an HTML page showing:</p><ul><li>Error ID</li><li>AI explanation</li><li>causes &amp; suggested next steps</li><li>confidence score</li><li>original exception class/message</li><li>a disclaimer that results are hypothese</li></ul><h2>🧠 Final thought</h2><p>We’ve spent years making systems more resilient.
We’ve improved logs, dashboards, alerts.</p><p>Maybe the next step is simpler:</p><blockquote><p><strong>Make systems better at explaining themselves.</strong></p></blockquote><p>Not to replace developers — but to help them think faster, with better context.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-iaexceptionbundle-when-errors-start-explaining-themselves</link><guid>https://blog.darkwood.com/article/darkwood-iaexceptionbundle-when-errors-start-explaining-themselves</guid><enclosure url="http://darkwood.com/media/articles/698910e3d0a4d761490836.png" /></item><item><title>🧑‍💻 Coder vs Vibe coder</title><pubDate>Wed, 11 Feb 2026 08:35:10 +0000</pubDate><description><![CDATA[For a long time, the distinction between a good developer and a mediocre one was based on classic criteria: code readability, architecture, performance, and testing. These criteria remain valid. But they are no longer sufficient to describe what is emerging...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/698c40023912c920886466.jpg" /></p><p>For a long time, the distinction between a good developer and a mediocre one was based on classic criteria: code readability, architecture, performance, and testing. These criteria remain valid. But they are no longer sufficient to describe what is emerging.</p><p>With the arrival of tools like Cursor, another posture becomes visible: that of the <strong>vibe coder</strong>.</p><p>This isn't a new profession. Nor is it &quot;coding with AI.&quot; It's a <strong>shift in the center of gravity</strong>.</p><h2>The coder: code as an entry point</h2><p>The “traditional” coder works in an environment where:</p><ul><li>Files are central * The directory tree is the map of the territory * The IDE is a precision instrument</li></ul><p>The logic is as follows:</p><p>The problem is understood → the code is written → the result emerges</p><p>In this position:</p><ul><li>The code is the source of truth. * The tool (IDE, AI, terminal) is an <strong>accelerator</strong>. * The intention is translated <em>manually</em> into structure.</li></ul><p>This approach is robust, deterministic, and effective for well-defined problems. It remains indispensable.</p><h2>The Vibe Coder: Intention as the Entry Point</h2><p>With AI-enhanced FDI, another stance emerges.</p><p>In Cursor, a simple detail becomes revealing: the fact of placing <strong>the AI ​​agent on the left</strong> and <strong>the files on the right</strong>.</p><p><img src="https://darkwood.com/blog/images/articles/2026-02-11-coder-vs-vibecoder/before.png" alt="Before" /></p><p><img src="https://darkwood.com/blog/images/articles/2026-02-11-coder-vs-vibecoder/after.png" alt="After" /></p><p>This change is not cosmetic.</p><p>It represents an inversion:</p><ul><li>The main interface becomes <strong>conversational</strong> * Files become a <strong>projection</strong> * Code is no longer the starting point, but the result</li></ul><p>The reasoning becomes:</p><p>I express an intention → I validate a direction → the code aligns</p><h2>What really changes</h2><p>The difference does not lie in:</p><ul><li>the language * the framework * the syntax</li></ul><p>It lies in <strong>what guides the action</strong>.</p><p>The vibe coder doesn't &quot;let go&quot; of the technique. He <strong>deliberately delays it</strong>.</p><p>The code becomes a consequence, not a proof.</p><p>In a vibe-based approach:</p><ul><li>Competence is no longer proven by code complexity * It is proven by the <strong>consistency of the result</strong> * The code is disposable, rewritable, adjustable</li></ul><p>What matters:</p><ul><li>Clarity of intent * Speed ​​of convergence * Ability to correct course without excessive attachment to implementation</li></ul><p>Code ceases to be a sacred artifact. It becomes a <strong>medium of materialization</strong>.</p><h2>Cursor is not the cause, it is the revealer</h2><p>Important: Cursor does not create vibe coding.</p><p>It makes it <strong>visible</strong>.</p><p>He explains:</p><ul><li>a persistent memory of context * a continuity of intention * a space where thought precedes structure</li></ul><p>The change in layout (agent on the left, files on the right) acts as a cognitive trigger:</p><blockquote><p>It is no longer the code that guides thought, &gt; it is thought that guides the code.</p></blockquote><h2>The coder and the vibe coder are not opposed</h2><p>They are not competitors. They are <strong>complementary</strong>.</p><ul><li>The encoder excels at stabilization * The vibe encoder excels at exploration * One solidifies * The other orients</li></ul><p>In complex systems, both are necessary. But ignoring the emergence of vibe coding means missing a major shift: the one where <strong>intention becomes the primary primitive of development</strong>.</p><h2>Conclusion</h2><p>The Vibe Encoder does not replace the encoder. It simply shifts the center of gravity.</p><ul><li>From code to intent * From implementation to experience * From tool to cognitive flow</li></ul><p>Code remains essential. It is simply no longer the starting point.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/coder-vs-vibe-coder</link><guid>https://blog.darkwood.com/article/coder-vs-vibe-coder</guid><enclosure url="http://darkwood.com/media/articles/698c40023912c920886466.jpg" /></item><item><title>🤖 Making Darkwood Agent-Ready</title><pubDate>Thu, 12 Feb 2026 07:39:19 +0000</pubDate><description><![CDATA[Websites are no longer consumed only by humans.
They are parsed, summarized, classified and reasoned about by AI agents.
Search engines were the first wave.
LLM-powered agents are the second.
Recently, I decided to audit darkwood.com and apply concrete impr...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/698d83a7a18a1473752651.jpg" /></p><p>Websites are no longer consumed only by humans.</p><p>They are parsed, summarized, classified and reasoned about by AI agents.</p><p>Search engines were the first wave.
LLM-powered agents are the second.</p><p>Recently, I decided to audit <strong>darkwood.com</strong> and apply concrete improvements to make it more understandable and more explicit for AI systems.</p><p>This article documents what changed and why.</p><h2>Why Optimize for AI Agents?</h2><p>Traditional SEO focuses on ranking signals.</p><p>AI agents operate differently.</p><p>They:</p><ul><li>Parse structure</li><li>Extract intent</li><li>Follow links as decision paths</li><li>Classify page types</li><li>Evaluate confidence</li></ul><p>If your website is ambiguous, an agent’s understanding becomes probabilistic and fragile.</p><p>The objective was simple:</p><blockquote><p>Reduce ambiguity. Increase explicitness.</p></blockquote><h2>Initial Observation: Homepage Ambiguity</h2><p>Darkwood historically combines multiple dimensions:</p><ul><li>A technical blog</li><li>Personal projects</li><li>A game/community space</li></ul><p>For humans, this ecosystem makes sense.</p><p>For AI systems landing on the homepage, however, the dominant visual signals (login, play, chat, rank) can bias interpretation toward a gaming portal rather than a technical knowledge hub.</p><p>This is not “wrong”.
But it is imprecise.</p><p>Precision matters when agents decide how to classify and reuse information.</p><h1>Step 1 — Adding <code>llms.txt</code></h1><p>The first improvement was introducing a root-level <code>llms.txt</code> file.</p><p>This file acts as a lightweight guidance layer for AI systems.</p><p>It explicitly defines:</p><ul><li>What Darkwood is</li><li>Where high-signal content lives</li><li>What agents are allowed to do</li><li>What they should avoid</li><li>Suggested crawl behavior</li></ul><p>Instead of forcing agents to infer structure through exploration, we provide a minimal contract.</p><p>Example excerpt:</p><pre><code>## Primary entry points (recommended)
- Blog: https://blog.darkwood.com/
- Profile: https://hello.darkwood.com/

## What to avoid
- Do not attempt login/register
- Do not submit forms
- Avoid aggressive crawling
</code></pre><p>This small addition significantly reduces ambiguity and prevents unintended interaction with dynamic or authenticated areas.</p><p>It also makes the blog immediately discoverable as the primary high-value content surface.</p><h1>Step 2 — Implementing Structured Data (JSON-LD)</h1><p>The most important content type on Darkwood is the blog article.</p><p>To make this explicit, each article page now exposes a <code>BlogPosting</code> Schema.org JSON-LD block.</p><p>This includes:</p><ul><li><code>headline</code></li><li><code>description</code></li><li><code>datePublished</code></li><li><code>dateModified</code></li><li><code>inLanguage</code></li><li><code>author</code></li><li><code>publisher</code></li><li><code>mainEntityOfPage</code> (canonical URL)</li></ul><p>Example:</p><pre><code class="language-json">{
  &quot;@context&quot;: &quot;https://schema.org&quot;,
  &quot;@type&quot;: &quot;BlogPosting&quot;,
  &quot;headline&quot;: &quot;Making Darkwood Agent-Ready&quot;,
  &quot;datePublished&quot;: &quot;2026-02-12T00:00:00+01:00&quot;,
  &quot;inLanguage&quot;: &quot;en&quot;,
  &quot;author&quot;: {
    &quot;@type&quot;: &quot;Person&quot;,
    &quot;name&quot;: &quot;Mathieu Ledru&quot;,
    &quot;url&quot;: &quot;https://hello.darkwood.com/&quot;
  },
  &quot;publisher&quot;: {
    &quot;@type&quot;: &quot;Organization&quot;,
    &quot;name&quot;: &quot;Darkwood&quot;,
    &quot;url&quot;: &quot;https://darkwood.com/&quot;
  }
}
</code></pre><p>Why this matters:</p><ul><li>Agents no longer need to guess page type</li><li>Publication metadata becomes reliable</li><li>Canonical alignment is explicit</li><li>Language context is clear</li></ul><p>Structured data increases confidence in automated reasoning systems.</p><p>It reduces interpretative entropy.</p><h1>What Changed Technically</h1><p>The implementation required:</p><ul><li>Adding a static <code>llms.txt</code> file at the domain root</li><li>Ensuring correct <code>text/plain</code> delivery</li><li>Injecting JSON-LD in article templates</li><li>Aligning canonical URLs</li><li>Standardizing ISO-8601 date formatting</li></ul><p>No new dependencies were introduced.
No UI changes were required.</p><p>The modifications are minimal, but structural.</p><h1>Why This Matters</h1><p>Optimizing for AI agents is not about chasing trends.</p><p>It is about:</p><ul><li>Declaring intent clearly</li><li>Reducing ambiguity</li><li>Making content machine-interpretable</li><li>Explicitly defining boundaries</li></ul><p>Websites are becoming part of larger automated ecosystems.</p><p>Clarity is no longer optional.</p><h2>Sources</h2><p>Here is the source article I came to this : <a href="https://guillaume.id/blog/optimize-your-website-for-ai-agents/">guillaume.id</a></p><h1>Implementation Details</h1><p>You can review the exact implementation in the corresponding pull request:</p><p>👉 <a href="https://github.com/darkwood-com/darkwood-com/pull/106">https://github.com/darkwood-com/darkwood-com/pull/106</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/making-darkwood-agent-ready-2</link><guid>https://blog.darkwood.com/article/making-darkwood-agent-ready-2</guid><enclosure url="http://darkwood.com/media/articles/698d83a7a18a1473752651.jpg" /></item><item><title>🤖 Parallel AI Development with Cursor and Git Worktrees</title><pubDate>Sun, 15 Feb 2026 22:10:46 +0000</pubDate><description><![CDATA[
In this article, I want to show a concrete example of how to parallelize development using Cursor, Git worktrees, and a real Symfony bundle:
👉 https://github.com/darkwood-com/ia-exception-bundle
The goal is simple: improve the bundle by working on two inde...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69924513e1264865424979.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/_myV7KBwcDo?si=3-iVt2zwU_CsYOsf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>In this article, I want to show a concrete example of how to parallelize development using <strong>Cursor</strong>, <strong>Git worktrees</strong>, and a real Symfony bundle:</p><p>👉 <a href="https://github.com/darkwood-com/ia-exception-bundle">https://github.com/darkwood-com/ia-exception-bundle</a></p><p>The goal is simple: improve the bundle by working on two independent features at the same time without conflicts using AI agents.</p><h1>Context</h1><p>I’m currently working on a Symfony bundle called:</p><p><strong>Darkwood IA Exception Bundle</strong>
Repository: <a href="https://github.com/darkwood-com/ia-exception-bundle">https://github.com/darkwood-com/ia-exception-bundle</a></p><p>Its purpose is to enhance Symfony exceptions using AI:
when a <code>500</code> occurs, the bundle analyzes the exception and generates structured diagnostics (probable causes, suggested fixes, confidence score, etc.).</p><p>However, while working on it locally, I identified two improvements.</p><h2>🟥 Issue 1 Improve the error icon</h2><p>The current icon is a standard Bootstrap “danger” icon.
It works, but it does not visually communicate that the exception is AI-augmented.</p><p>The idea:
Replace it with a more appropriate <strong>AI-themed danger icon</strong>.</p><h2>🟦 Issue 2 Render AI analysis asynchronously</h2><p>Currently:</p><ol><li>An exception occurs.</li><li>The AI call is triggered.</li><li>The HTTP response waits for the AI.</li><li>The full page is rendered only once the AI finishes.</li></ol><p>This introduces latency.</p><p>Instead, we want:</p><ul><li>Immediate exception rendering.</li><li>AI analysis loaded asynchronously.</li><li>The page updated once the AI response arrives.</li></ul><p>For this, we use <strong>Symfony UX</strong>.</p><h1>The Challenge</h1><p>How can we work on both issues in parallel using Cursor without creating file conflicts?</p><p>The answer comes from an idea popularized in recent articles about AI coding agents:</p><blockquote><p>Use Git worktrees for context isolation.</p></blockquote><h1>Git Worktrees Quick Reminder</h1><p>A Git worktree allows you to create a new working directory attached to the same repository.</p><p>It’s not a full clone.</p><p>It shares the Git history but lives in a separate physical directory.</p><p>Example:</p><pre><code class="language-bash">git worktree add ../feature-ai-icon feature/ai-icon
git worktree add ../feature-async-render feature/async-render
</code></pre><p>Now you have:</p><ul><li>Main repo</li><li>Worktree A → Feature 1</li><li>Worktree B → Feature 2</li></ul><p>Each can evolve independently.</p><p>No file conflicts.
No context pollution.</p><h1>Why This Matters for AI Agents</h1><p>With Cursor, you can assign an AI agent to each worktree.</p><p>Agent 1 works only inside:</p><pre><code>feature/ai-icon
</code></pre><p>Agent 2 works only inside:</p><pre><code>feature/async-render
</code></pre><p>Each agent operates in isolation.</p><p>This is what we call:</p><blockquote><p>Context isolation</p></blockquote><p>And it’s essential when parallelizing AI-driven development.</p><h1>Practical Implementation</h1><h2>Step 1 Create Two Worktrees</h2><p>I manually created two worktrees corresponding to the two issues.</p><p>Then, for each worktree, I:</p><ul><li>Opened it in Cursor</li><li>Pasted the GitHub issue description</li><li>Let the AI agent implement the feature</li></ul><h2>Step 2 Async Exception Rendering</h2><p>For the asynchronous feature, the AI implemented:</p><ul><li>A dedicated route loader</li><li>An <code>IAExceptionController</code></li><li>A context storage system</li><li>A service for deferred AI analysis</li><li>Conditional behavior when async mode is enabled</li></ul><p>Now the workflow is:</p><ol><li>Exception renders instantly.</li><li>Symfony UX loads AI analysis asynchronously.</li><li>The page updates dynamically once the AI response arrives.</li></ol><p>This significantly improves perceived performance.</p><h2>Step 3 Icon Improvement</h2><p>In the second worktree, the agent:</p><ul><li>Replaced the Bootstrap danger icon</li><li>Introduced a cleaner AI-themed SVG</li><li>Maintained layout compatibility</li><li>Preserved Bootstrap styling</li></ul><p>This was completely independent from the async feature.</p><p>No overlapping code.</p><h1>Switching Between Features</h1><p>Because these are worktrees, switching context is easy.</p><p>In my local Darkwood app:</p><ul><li>The bundle is normally loaded via Composer.</li><li>I temporarily linked the bundle to the corresponding worktree.</li><li>Cleared cache.</li><li>Triggered a controlled exception.</li></ul><p>Then I could test each feature independently.</p><p>Switching from Feature A to Feature B required only:</p><ul><li>Switching the symbolic link</li><li>Clearing cache</li><li>Refreshing</li></ul><p>No merge.
No rebase.
No conflicts.</p><h1>What We Achieved</h1><p>We now have:</p><ul><li>Two independent pull requests</li><li>Two isolated AI agents</li><li>No file conflicts</li><li>Clean separation of concerns</li></ul><p>These changes were released in:</p><p>👉 <strong>v1.0.2</strong><a href="https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2">https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2</a></p><p>This release introduces:</p><ul><li>UI improvements for AI exception rendering</li><li>Asynchronous AI analysis loading</li><li>Improved architectural separation for future enhancements</li></ul><h1>When Does This Break?</h1><p>Parallel development works best when issues are:</p><ul><li>Clearly separated</li><li>Targeting different layers</li><li>Not modifying the same files</li></ul><p>If two issues modify:</p><ul><li>The same service</li><li>The same Twig template</li><li>The same controller</li></ul><p>You will face merge conflicts later.</p><p>Parallel AI development requires <strong>proper task decomposition</strong>.</p><h1>Production Considerations</h1><p>If you push multiple branches:</p><ul><li>You may face port conflicts locally.</li><li>Preview environments may require configuration.</li><li>Async features may require context persistence.</li></ul><p>These are manageable but must be considered.</p><h1>Why This Is Powerful</h1><p>The real value is not the AI model.</p><p>It’s:</p><ul><li>Isolation</li><li>Orchestration</li><li>Context control</li></ul><p>Git worktrees allow us to scale AI coding sessions without chaos.</p><h1>Conclusion</h1><p>Parallel AI development is not about running more models.</p><p>It’s about isolating context properly.</p><p>With:</p><ul><li>Git worktrees</li><li>Cursor agents</li><li>Symfony UX</li><li>Clean issue decomposition</li></ul><p>You can safely evolve complex systems without stepping on your own changes.</p><h1>References</h1><ul><li><p>Repository IA Exception Bundle
<a href="https://github.com/darkwood-com/ia-exception-bundle">https://github.com/darkwood-com/ia-exception-bundle</a></p></li><li><p>Release v1.0.2
<a href="https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2">https://github.com/darkwood-com/ia-exception-bundle/releases/tag/v1.0.2</a></p></li><li><p>Git Worktrees for Parallel AI Coding Agents Upsun
<a href="https://devcenter.upsun.com/posts/git-worktrees-for-parallel-ai-coding-agents/">https://devcenter.upsun.com/posts/git-worktrees-for-parallel-ai-coding-agents/</a></p></li><li><p>Git Worktrees: The Power Behind Cursor’s Parallel Agents DEV.to
<a href="https://dev.to/arifszn/git-worktrees-the-power-behind-cursors-parallel-agents-19j1">https://dev.to/arifszn/git-worktrees-the-power-behind-cursors-parallel-agents-19j1</a></p></li><li><p>Cursor Documentation Worktrees Configuration
<a href="https://cursor.com/fr/docs/configuration/worktrees">https://cursor.com/fr/docs/configuration/worktrees</a></p></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/parallel-ai-development-with-cursor-and-git-worktrees</link><guid>https://blog.darkwood.com/article/parallel-ai-development-with-cursor-and-git-worktrees</guid><enclosure url="http://darkwood.com/media/articles/69924513e1264865424979.jpg" /></item><item><title>⚔️ Discovering the Hearthstone Cataclysm expansion</title><pubDate>Fri, 20 Feb 2026 21:41:54 +0000</pubDate><description><![CDATA[
The new destructive era arrives on March 17, 2026
The inn is about to be shaken like never before. The Cataclysm expansion is inspired by an alternate version of the World of Warcraft universe, where Deathwing was never defeated and reigns supreme over Aze...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/6998d7438174b858297439.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/-tEJPFT-7us?si=JC480o7ASK379OWO" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p><em>The new destructive era arrives on <strong>March 17, 2026</strong></em></p><p>The inn is about to be shaken like never before. The <strong>Cataclysm</strong> expansion is inspired by an alternate version of the <em>World of Warcraft</em> universe, where <strong>Deathwing was never defeated</strong> and reigns supreme over Azeroth.</p><h2>🌋 A dark plot: the threat of Deathwing</h2><p>At the end of <em>Beyond the Timeways</em>, Chromie accidentally triggers a nightmarish timeline in which <strong>Deathwing triumphs and invades Azeroth</strong> with his six terrifying colossal lieutenants.</p><p>In <em>Cataclysm</em>:</p><p>The sky is glowing red.
Azeroth must defend itself once again</p><ul><li>The heroes and heroines must rally the <strong>Dragonflights</strong></li><li>New cards and mechanics are here to tip the scales</li></ul><h2>💥 New Hero Card: <strong>Deathwing the Worldbreaker</strong></h2><p>One of the major new features of <em>Cataclysm</em> is <strong>the first playable Hero card, Deathwing, in Hearthstone</strong>:</p><ul><li>By playing it, your hero transforms into <strong>Deathwing the Worldbreaker</strong></li><li>His <strong>War Cry</strong> allows you to <strong>choose a Cataclysm</strong></li><li>You can trigger different destructive actions depending on your choices and resources</li><li>The more you use the <strong>Summon</strong> keyword before playing it, the more Cataclysms you can trigger simultaneously</li></ul><h2>🧱 Key Mechanics of Cataclysm</h2><h3>🔹 Summons</h3><p>This keyword is at the heart of the extension:</p><p>Playing a minion with Summon summons a <strong>colossus soldier</strong> onto the board
The more you use Summon, the more powerful your colossal servant becomes.</p><ul><li>Summoning also empowers <strong>Deathwing the Worldbreaker</strong> to trigger more Cataclysms</li></ul><h3>🔹 Return of the <em>Colossal</em> Servants</h3><ul><li>Giants that occupy <strong>several spaces on the board</strong></li><li>They are accompanied by appendages (arms, heads) which have their own effects</li><li>A <strong>new colossal legendary</strong> is available for each class loyal to Deathwing (e.g., Ragnaros the Greatfire for warriors)</li></ul><h3>🔹 Split</h3><p>This innovative keyword affects certain defense-type cards of the Dragonflights:</p><ul><li>When you draw a <strong>Split</strong> card, it splits into two pieces</li><li>These pieces are placed <strong>at the ends of your hand</strong></li><li>If you combine them by playing cards together, they recombine to trigger <strong>two effects for the price of one</strong></li></ul><h3>🌀 Other innovative effects</h3><p><em>Cataclysm</em> also adds cards that allow you to:</p><ul><li><strong>Target specific cards in your hand</strong></li><li>Manipulating the hand for tactical purposes</li><li>Strengthen your deck for more dynamic strategies</li></ul><h2>🛡️ Draconic Flights as reinforcements</h2><p>To counter Deathwing's power:</p><p>🌟 The <strong>mage, priest, druid, hunter, paladin</strong> classes benefit from a new <strong>legendary dragon aspect</strong>.
For example, the hunter obtains <strong>Black Dragonflight Ebyssian</strong>, capable of transforming into a powerful dragon.</p><h2>🎁 Free rewards and events</h2><p>Blizzard has planned a host of rewards to prepare you for your adventure:</p><h3>🎉 Before the release:</h3><ul><li><strong>Free packs</strong> to be won during Twitch streams</li><li>Temporary access to the maps for the expansions <em>In the Heart of the Emerald Dream</em> and <em>The Lost City of Un'Goro</em> from <strong>March 10th until the release of Cataclysm</strong></li><li>Legendary card <strong>Blackhorn Warlord</strong> offered as a login bonus</li><li>Twitch Drops up to <strong>multiple free packs</strong></li><li>Rewards for in-game events (quests, waves, achievements)</li></ul><h3>📅 During and after the launch:</h3><ul><li>Free colossal legendary card in the <strong>tavern reward track</strong></li><li>Weekly rewards for logging in (packs, signature cards)</li><li>Rewards related to launch event quests</li><li>Special card back if you complete certain achievements in Tavern Brawl</li></ul><p>👉 In short: <strong>lots of free content to collect without spending a penny</strong> if you play regularly.</p><h2>📆 Important Calendar</h2><p>🗓️ <strong>March 10-17</strong>: <em>Pre-launch Tavern Brawl</em> – try out the Deathwing card and earn rewards
🗓️ <strong>March 17, 2026</strong>: Launch of the <em>Cataclysm</em> expansion
📆 From <strong>March 10th until launch</strong>: Temporary access to cards from older expansions to test decks</p><h2>💡 In summary: what's changing?</h2><p><em>Cataclysm</em> delivers an <strong>intense alternate history</strong></p><ul><li>Deathwing is <strong>playable and destructive</strong></li><li>Powerful keywords: <strong>Convocation, Split</strong></li><li>Return of the <strong>colossal servants</strong></li><li>Lots of <strong>free rewards</strong></li><li>More <strong>tactical and strategic</strong> gameplay</li></ul><p>💬 <strong>My Darkwood review</strong>:
This expansion promises a richer tactical experience, with decks that reward planning and hand management. It also offers numerous free opportunities for free-to-play players.</p><p>References:</p><ul><li><a href="https://hearthstone.blizzard.com/fr-fr/expansions-adventures/cataclysm">https://hearthstone.blizzard.com/fr-fr/expansions-adventures/cataclysm</a> &quot;Cataclysm&quot;</li><li><a href="https://hearthstone.blizzard.com/fr-fr/news/24245219/aile-de-mort-contre-attaque-dans-cataclysme-la-nouvelle-extension-de-hearthstone">https://hearthstone.blizzard.com/fr-fr/news/24245219/aile-de-mort-contre-attaque-dans-cataclysme-la-nouvelle-extension-de-hearthstone</a> &quot;Deathwing Strikes Back in CATACLYSM, the new Hearthstone expansion - Hearthstone&quot;</li><li><a href="https://hearthstone.blizzard.com/fr-fr/news/24242864/votre-guide-pour-decouvrir-les-cartes-de-cataclysme-et-obtenir-des-recompenses-gratuites">https://hearthstone.blizzard.com/fr-fr/news/24242864/votre-guide-pour-decouvrir-les-cartes-de-cataclysme-et-obtenir-des-recompenses-gratuites</a> &quot;Your guide to discovering CATACLYSM cards and getting free rewards - Hearthstone&quot;</li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/discovering-the-hearthstone-cataclysm-expansion</link><guid>https://blog.darkwood.com/article/discovering-the-hearthstone-cataclysm-expansion</guid><enclosure url="http://darkwood.com/media/articles/6998d7438174b858297439.jpg" /></item><item><title>🚀 I&#039;m building a dictation engine in PHP (Flow + Symfony + Whisper.cpp)</title><pubDate>Sun, 22 Feb 2026 20:39:35 +0000</pubDate><description><![CDATA[
Building a dictation engine in 2026 is trivial.
Building a clean architecture around a dictation engine is more interesting.
This article presents Flowvox, an MVP of an audio transcription engine developed in PHP, based on:

Symfony
Symfony Messenger
Flow:...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/699b856ef332c842142834.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/JUVqrE78AkY?si=3bf3hFfe3_xxrPlM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Building a dictation engine in 2026 is trivial.</p><p>Building a clean architecture around a dictation engine is more interesting.</p><p>This article presents <strong>Flowvox</strong>, an MVP of an audio transcription engine developed in PHP, based on:</p><ul><li>Symfony</li><li>Symfony Messenger</li><li>Flow: <a href="https://flow.darkwood.com">in-house orchestrator</a></li><li>ffmpeg</li><li>whisper.cpp</li></ul><p>The source code is available as open source:
👉 <strong><a href="https://github.com/darkwood-com/flowvox">https://github.com/darkwood-com/flowvox</a></strong></p><p>The goal wasn't simply to use Whisper.
The goal was to properly structure the pipeline.</p><h2>The problem: transcription is only one step</h2><p>A minimal voice engine can be summarized as follows:</p><pre><code>Audio → Texte
</code></pre><p>But in a real-world system, several constraints emerge:</p><ul><li>Start/stop activation</li><li>Finalizing the audio file</li><li>Recorder state management</li><li>Orchestration of the stages</li><li>Extension to post-processing (summary, LLM, analysis)</li></ul><p>The question then becomes:</p><p>How to model a clean, scalable and controlled audio pipeline?</p><h2>Technical Stack</h2><p>The MVP is based on:</p><ul><li><strong>PHP 8+</strong></li><li><strong>Symfony</strong></li><li><strong>Symfony Messenger</strong></li><li><strong>Flow</strong> (orchestrator)</li><li><strong>ffmpeg</strong> (local audio capture)</li><li><strong>whisper.cpp</strong> (local open source transcription)</li></ul><p>No remote API.
No cloud service.
100% local transcription.</p><h2>General Architecture</h2><p>The architecture is organized into three flows:</p><pre><code>InputProvider → Recorder → Transcribe
</code></pre><p>Each step is isolated and responsible for a specific role.</p><h2>InputProviderFlow</h2><p>Responsibility :</p><ul><li>Listen for the commands <code>voice:start</code> and <code>voice:stop</code></li><li>Issue a <code>VoiceControlEvent</code></li></ul><p>CLI commands trigger messages via Symfony Messenger.</p><p>The worker, in the background, receives these events and injects them into Flow.</p><p>This decoupling allows:</p><ul><li>Granular control</li><li>Multi-session management</li><li>A clear separation of responsibilities</li></ul><h2>RecorderFlow</h2><p>Responsibility :</p><ul><li>Controlling a <code>VoiceRecorder</code> instance</li><li>Manage the lifecycle of an <code>ffmpeg</code> process</li></ul><p>The <code>VoiceRecorder</code> encapsulates a system process launched via:</p><pre><code class="language-php">Symfony\Component\Process\Process
</code></pre><p>Central problem:</p><p>How can I properly manage start/stop without corrupting the audio file?</p><p>Three states are explicitly modeled:</p><ul><li><code>idle</code></li><li><code>recording</code></li><li><code>stopping</code></li></ul><p>During a <code>stop</code>, a <code>SIGINT</code> is sent to <code>ffmpeg</code> in order to properly finalize the WAV header.</p><p>The <code>stopping</code> state prevents:</p><ul><li>The double-start</li><li>Competing conflicts</li><li>Incomplete files</li></ul><p>The process is controlled, not endured.</p><h2>TranscribeFlow</h2><p>Responsibility :</p><ul><li>Receive a finalized WAV file</li><li>Launch whisper.cpp</li><li>Produce a transcribed text</li></ul><p>Whisper is run locally via CLI.</p><p>The MVP remains intentionally simple:</p><ul><li>No streaming</li><li>No real-time chunking</li><li>A synchronous transcription</li></ul><p>The goal is to validate the integration and orchestration.</p><h2>Worker and orchestration</h2><p>The engine operates via a Symfony worker:</p><pre><code class="language-bash">php bin/console voice:worker
</code></pre><p>This worker:</p><ol><li>Flow Instantiation</li><li>Record the flows</li><li>Listen to Symfony Messenger</li><li>Orders the execution of the steps</li></ol><p>Available commands:</p><pre><code class="language-bash">voice:start
voice:stop
voice:worker-list
</code></pre><p>The complete feed becomes:</p><pre><code>voice:start
→ Recorder démarre
→ voice:stop
→ Recorder finalise
→ TranscribeFlow s’exécute
→ Texte produit
</code></pre><p>Without an external global state.</p><h2>Why Flow?</h2><p>Flow allows:</p><ul><li>A pipeline-oriented architecture</li><li>Input Processing strategies (IP Strategy)</li><li>Explicit event management</li><li>A clear separation between orchestration and business logic</li></ul><p>The system is not coupled with Whisper.</p><p>Whisper is an implementation.
Flow is the structure.</p><h2>What the MVP approves</h2><ul><li>Proper management of a system process</li><li>Explicit modeling of states</li><li>Event orchestration</li><li>Pipeline scalability</li></ul><p>This is not a product.</p><p>It's an architectural foundation.</p><h2>Possible Developments</h2><p>The next natural iterations:</p><ul><li>Streaming by audio chunk</li><li>Parallel transcription</li><li>Post-processing LLM</li><li>Integration desktop</li><li>Mobile support</li><li>Multi-model batching</li></ul><p>But these changes do not alter the core:</p><p>A clear architecture.
A masterful orchestration.
An expandable pipeline.</p><h2>Source code</h2><p>The open source repository is available here:</p><p>👉 <strong><a href="https://github.com/darkwood-com/flowvox">https://github.com/darkwood-com/flowvox</a></strong></p><p>Contributions, suggestions and feedback are welcome.</p><h2>Sources</h2><p>This article was based from <a href="https://guillaume.id/blog/how-i-got-superwhisper-quality-voice-typing-on-linux/">guillaume.id</a> blog post.</p><h2>Conclusion</h2><p>Building a voice engine in PHP is simple.</p><p>Building a clean architecture around a voice engine is more interesting.</p><p>Flowvox validates a principle:</p><p>Transcription is only one component.
The orchestration is the true structure.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/i-m-building-a-dictation-engine-in-php-flow-symfony-whisper-cpp</link><guid>https://blog.darkwood.com/article/i-m-building-a-dictation-engine-in-php-flow-symfony-whisper-cpp</guid><enclosure url="http://darkwood.com/media/articles/699b856ef332c842142834.png" /></item><item><title>🚀 Building a PHP MCP App to Publish Darkwood Articles</title><pubDate>Sun, 01 Mar 2026 18:42:29 +0000</pubDate><description><![CDATA[
Large language models are already good at generating text. What is still missing, in many projects, is a clean way to turn that text generation into a real workflow: draft something, review it, correct it, publish it, and expose the whole thing in a way th...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69a48acf1c7b0357611166.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/wCXWYcztKTw?si=4srpt2lf6Wz_JJVC" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Large language models are already good at generating text. What is still missing, in many projects, is a clean way to turn that text generation into a real workflow: draft something, review it, correct it, publish it, and expose the whole thing in a way that feels native inside an AI client.</p><p>That is exactly where MCP Apps become interesting.</p><p>In this project, the goal was not to build &quot;yet another chatbot integration&quot;. The goal was to build a <strong>real MCP App in PHP</strong> that can help publish a Darkwood blog article through a small editorial workflow:</p><ol><li>generate a draft,</li><li>review or correct it,</li><li>publish it,</li><li>and, if needed, loop back before publishing.</li></ol><p>The result is a PHP MCP server that can run over <strong>stdio</strong> or <strong>HTTP</strong>, expose tools, expose UI resources, and be packaged as a <strong>Claude Desktop extension</strong>.</p><h2>Why MCP Apps matter</h2><p>A classic MCP server can expose tools and resources. That is already useful: an LLM can call a tool, get structured output, and continue reasoning.</p><p>But MCP Apps add something more practical: they let a tool bring its own <strong>embedded UI</strong>.</p><p>That changes the interaction model quite a bit.</p><p>Instead of returning only text, a tool can now open a dedicated interface inside the host. That interface can display input state, show results, guide the user through a flow, and trigger additional tool calls. In other words, the tool stops being just a remote function and starts behaving more like a focused application surface.</p><p>For an editorial workflow, that is a much better fit than plain text alone.</p><p>Generating a draft is not the hard part. The hard part is managing the transition between &quot;here is a generated text&quot; and &quot;this content is ready to publish&quot;. That is where an MCP App UI helps: it gives structure to the process.</p><h2>The Darkwood use case</h2><p>The concrete use case here is simple to explain.</p><p>This MCP App is used to support the publication of a blog post on Darkwood.</p><p>The workflow starts with a first step, <strong>GenerateDraft</strong>, which produces an initial draft from a topic or context.</p><p>Then comes the second step, <strong>PublishDraft</strong>, which handles the publication path. If the draft is not good enough yet, the flow does not have to end there. It can go back through a correction or revision step before attempting publication again.</p><p>That loop matters.</p><p>A publication workflow is rarely linear in practice. A first draft can be too rough, too generic, too long, or simply not aligned with the editorial intent. So the MCP App is designed around a realistic idea: publishing is the destination, but iteration is part of the path.</p><h2>One MCP server, several ways to use it</h2><p>A useful aspect of this project is that the same MCP logic is reused across several runtime modes.</p><p>The server can be used:</p><ul><li>over <strong>stdio</strong>, typically for local integrations and Claude Desktop packaging,</li><li>over <strong>HTTP</strong>, for browser-based hosts or local MCP endpoints,</li><li>through <strong>Symfony server</strong>, when you want a more standard HTTP setup around <code>public/index.php</code>,</li><li>through a <strong>Claude Desktop extension</strong>, packaged as <code>.mcpb</code>,</li><li>and, in all of those cases, as an <strong>MCP App-enabled tool</strong> when the host supports embedded UI.</li></ul><p>That is important architecturally: the business logic is not tied to one client or one transport. The transport changes, the orchestration model changes a bit, but the MCP surface remains the same.</p><h2>Architecture</h2><p>The easiest way to understand the project is to separate it into four roles: the host, the PHP MCP server, the MCP App UI, and the orchestration layer.</p><h3>The big picture</h3><p>At a high level, the system works like this:</p><p><img src="/blog/images/articles/2026-03-01-building-a-php-mcp-app-to-publish-darkwood-articles/schema-architecture.png" alt="schema-architecture" /></p><ul><li>an <strong>MCP host</strong> connects to the PHP server,</li><li>the host discovers the available tools and resources,</li><li>the host calls a tool such as <code>GenerateDraft</code> or <code>PublishDraft</code>,</li><li>if the tool declares a UI resource, the host also loads the corresponding MCP App view,</li><li>the UI and the host talk to each other through JSON-RPC over <code>postMessage</code>,</li><li>and the host forwards tool calls back to the PHP server.</li></ul><p>This is the key idea: the UI does not talk directly to the server. The host sits in the middle and acts as the bridge.</p><p>That separation is useful because it keeps the UI portable across compatible hosts while preserving a clean MCP contract on the server side.</p><h3>Transports</h3><p>The project supports two main transports.</p><h4>Stdio</h4><p>In stdio mode, the host starts the PHP server as a subprocess and communicates through <code>STDIN</code> and <code>STDOUT</code>.</p><p>This is the natural fit for <strong>Claude Desktop extensions</strong>. The host launches the server, sends JSON-RPC messages through standard input, and reads responses from standard output.</p><p>This mode is simple, local, and efficient when the client is responsible for process management.</p><h4>HTTP</h4><p>In HTTP mode, the server exposes an MCP endpoint such as <code>POST /mcp</code>.</p><p>That mode is useful for browser-oriented hosts, local testing, or any setup where an HTTP boundary is more convenient than a child process.</p><p>In this project, HTTP can be served in two ways:</p><ul><li>through a dedicated long-lived process such as the flow worker,</li><li>or through a more traditional web entry point such as <code>public/index.php</code>.</li></ul><h3>Messaging</h3><p>Once connected, the host and the server communicate with <strong>JSON-RPC 2.0</strong>.</p><p>That means the interaction model stays clean and explicit:</p><ul><li>the host sends requests,</li><li>the server returns responses,</li><li>notifications can be exchanged when no response is expected.</li></ul><p>This is true whether the transport is stdio or HTTP. The transport changes, but the protocol contract stays the same.</p><p>On top of that, when MCP Apps are involved, the UI communicates with the host through another JSON-RPC channel, this time over <code>postMessage</code>.</p><p>So there are really two communication layers:</p><ul><li><strong>host ↔ server</strong> through MCP,</li><li><strong>UI ↔ host</strong> through the MCP Apps bridge.</li></ul><p>That split is what makes embedded UI possible without coupling the front-end directly to the PHP runtime.</p><h3>Lifecycle</h3><p>A typical interaction goes through a few predictable steps.</p><p>First, the host initializes the connection and discovers the server capabilities.</p><p>Then it lists tools and resources.</p><p>When the user triggers a tool, the host calls the tool on the server. If that tool is associated with a UI resource, the host also reads the corresponding <code>ui://...</code> resource and renders it in a sandboxed iframe.</p><p>At that point, the MCP App becomes interactive. It can receive the tool input, display the tool result, and initiate follow-up actions through the host.</p><p>In the Darkwood workflow, that means the user or assistant can move from draft generation to publication, and possibly back into a correction loop, without leaving the MCP interaction model.</p><h3>What runs where</h3><p>The <strong>PHP MCP server</strong> owns the protocol surface:</p><ul><li><code>initialize</code></li><li><code>tools/list</code></li><li><code>tools/call</code></li><li><code>resources/list</code></li><li><code>resources/read</code></li></ul><p>The <strong>MCP App UI</strong> owns the interactive experience.</p><p>The <strong>host</strong> owns transport, rendering, and bridging between the UI and the server.</p><p>The <strong>Flow</strong> layer owns workflow orchestration when orchestration is needed.</p><p>That last point matters because editorial flows often involve more than one action and more than one state transition.</p><h2>Stdio, HTTP, and Symfony server are not the same thing</h2><p>Even if the business logic stays the same, the runtime model is not identical across modes.</p><p>With <strong>stdio</strong> and with a long-lived <strong>HTTP</strong> worker, you can think in terms of a persistent process. That opens the door to async capabilities, event loops, and continuous orchestration in the same runtime.</p><p>With <strong>Symfony server</strong>, the model is more classic. Each request is handled in a synchronous HTTP cycle. That is usually simpler operationally, but it means orchestration should be understood differently: the HTTP layer stays sync, while the workflow logic is delegated to <strong>Flow</strong> or to external coordination.</p><p>That distinction is worth making explicitly, because &quot;supports HTTP&quot; does not automatically mean &quot;supports the same execution model everywhere&quot;.</p><h2>Why this design works well for publishing workflows</h2><p>A blog publication flow sits in an awkward space.</p><p>It is not a single function call. But it is also not a full back-office application. It needs just enough structure to manage state and decisions, while staying lightweight enough to be triggered from an AI conversation.</p><p>That is exactly why MCP Apps are a good fit here.</p><p>The tool interface gives the model an actionable surface. The UI gives the human or the client a controlled workflow view. And the Flow orchestration gives the backend a place to manage multi-step transitions.</p><p>This combination is strong because each layer stays focused:</p><ul><li>the model decides when to use the tool,</li><li>the tool exposes the workflow,</li><li>the UI makes the workflow visible,</li><li>the backend executes it cleanly.</li></ul><h2>Using the MCP App in Claude</h2><p>One practical outcome of the project is that the same MCP server can be packaged as a <strong>Claude Desktop extension</strong>.</p><p>That means the project is not only a local prototype or a browser demo. It can actually be installed in Claude and used as a proper tool integration.</p><p>In that setup:</p><ul><li>the extension manifest defines how Claude launches the server,</li><li>the server runs through <strong>stdio</strong>,</li><li>Claude acts as the MCP host,</li><li>and the MCP App becomes available as a tool inside the client.</li></ul><p>This is a good example of why keeping transports separate from business logic matters. The same PHP MCP server can serve local development, HTTP-based experimentation, and Claude Desktop usage without rewriting the core behavior.</p><h2>From demo to real editorial tooling</h2><p>What makes this project interesting is not the existence of yet another draft generator.</p><p>It is the fact that the project already defines a reusable shape for editorial tooling:</p><ul><li>a tool to produce a draft,</li><li>a tool to publish,</li><li>a place to handle revisions,</li><li>a UI layer to support the interaction,</li><li>and a transport-agnostic MCP server underneath.</li></ul><p>That is a much more durable foundation than a one-off prompt chain.</p><p>Once that structure exists, improving the workflow becomes much easier. You can refine generation quality, enrich publication metadata, add validation, or plug into a real CMS. The contract between the host, the UI, and the server remains stable.</p><h2>Opensource</h2><p>The full project is available as an open-source repository on GitHub</p><p><a href="https://github.com/darkwood-com/darkwood-publish-article-mcp-apps">https://github.com/darkwood-com/darkwood-publish-article-mcp-apps</a></p><h2>Sources</h2><p>This article was based from <a href="https://www.linkedin.com/in/fzaninotto/">Francois Zaninotto</a> linkedin post.</p><h2>Conclusion</h2><p>This project shows that MCP Apps are not only about exposing tools to an LLM. They are about exposing <strong>usable workflows</strong>.</p><p>In the Darkwood case, the interesting part is not that PHP can talk MCP. The interesting part is that a PHP MCP server can now act as the backend of a small editorial application, available inside an AI client, with both tool semantics and embedded UI.</p><p>That moves the integration from &quot;the model can call a function&quot; to &quot;the model can participate in a controlled publishing workflow&quot;.</p><p>And that is a much more useful place to be.</p><p><strong>Sources</strong><a href="https://apps.extensions.modelcontextprotocol.io/api/documents/Quickstart.html">MCP Apps Quickstart</a><br /><a href="/Users/math/Sites/darkwood/darkwood-publish-article-mcp-apps/README.md">README.md</a><br /><a href="/Users/math/Sites/darkwood/darkwood-publish-article-mcp-apps/docs/php-mcp-apps-mvp-architecture.md">php-mcp-apps-mvp-architecture.md</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/building-a-php-mcp-app-to-publish-darkwood-articles</link><guid>https://blog.darkwood.com/article/building-a-php-mcp-app-to-publish-darkwood-articles</guid><enclosure url="http://darkwood.com/media/articles/69a48acf1c7b0357611166.png" /></item><item><title>👾 Darkwood: Building an API-First Tactical Game</title><pubDate>Sat, 07 Mar 2026 18:42:42 +0000</pubDate><description><![CDATA[
Darkwood is now playable entirely via API.
There is no dedicated UI.
No frontend required.
No graphical client.
You interact with the game through HTTP.
What “API-First” Actually Means
In Darkwood, the game loop is simple and explicit:

GET /api/darkwood/s...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69acf94561c3d512031768.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/ty1Ylnznaeo?si=kJM5fdq9pLUGSTjG" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Darkwood is now playable entirely via API.</p><p>There is no dedicated UI.
No frontend required.
No graphical client.</p><p>You interact with the game through HTTP.</p><h2>What “API-First” Actually Means</h2><p>In Darkwood, the game loop is simple and explicit:</p><ol><li><code>GET /api/darkwood/state</code> → observe the current situation</li><li>Interpret the JSON response</li><li><code>POST /api/darkwood/action</code> → decide what to do</li><li>Receive the updated state</li><li>Repeat</li></ol><p>The game behaves as a state machine over HTTP.</p><p>Every response includes:</p><ul><li><code>state</code> — where you are (main, combat, info, shop, etc.)</li><li><code>mode</code> — sub-phase (in fight, victory, death, etc.)</li><li><code>data</code> — contextual details (life, enemy, stats, combat session)</li></ul><p>Your client — whether it’s curl, a CLI tool, a script, or an AI agent — reads the state and decides the next action.</p><p>There is no hidden UI logic.</p><p>The protocol is the game.</p><h2>Two Layers of Access</h2><p>Darkwood separates access into two layers:</p><h3>1️⃣ API Access</h3><p>Every request must include:</p><pre><code>X-API-Key: &lt;your-key&gt;
</code></pre><p>The API key controls:</p><ul><li>Whether you can call the API</li><li>Whether you are part of Beta Season 0</li><li>Whether you have premium access</li><li>Your daily action quota (for free keys)</li></ul><h3>2️⃣ Player Identity</h3><p>To play as a specific character (persistent progression, combat, stats), you authenticate with:</p><pre><code>Authorization: Bearer &lt;jwt-token&gt;
</code></pre><p>The JWT identifies the player account.
The API key controls access and monetization.</p><p>They are separate by design.</p><p>Full documentation is available on GitHub:
<a href="https://github.com/darkwood-com/darkwood-com/blob/main/docs/">https://github.com/darkwood-com/darkwood-com/blob/main/docs/</a></p><h2>Free vs Premium</h2><p>Darkwood currently runs as <strong>Beta Season 0</strong>.</p><p>Two types of keys exist:</p><h3>🎟 Beta Access (Free)</h3><ul><li>Personal API key</li><li>Limited daily actions</li><li>Access to the current playable state</li><li>No archive access</li></ul><h3>💎 Founder Premium</h3><ul><li>Personal API key</li><li>Unlimited daily actions</li><li>Access to archived puzzle snapshots</li><li>Early supporter status</li></ul><p>Archives are read-only snapshots of past playable states.
They expose historical game states without modifying live gameplay.</p><h2>Limited Founder Release</h2><p>To keep this launch controlled:</p><ul><li><strong>5 Beta Access keys</strong></li><li><strong>5 Founder Premium keys</strong></li></ul><p>That’s it.</p><p>This is not a large-scale launch.
It’s a focused release to validate the model.</p><p>Sales are handled through Bonzai:</p><ul><li><p>Beta Access (Free):
<a href="https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free">https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free</a></p></li><li><p>Founder Premium:
<a href="https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium">https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium</a></p></li></ul><p>Each key is personal.
Keys can be rotated if needed.</p><h2>Why No UI?</h2><p>Because the interface is optional.</p><p>You can play Darkwood with:</p><ul><li>curl</li><li>Postman</li><li>a custom CLI</li><li>a small web client</li><li>a script</li><li>an AI agent</li></ul><p>The API defines the game contract.</p><p>The client is just an interpreter.</p><h2>Beta Season 0</h2><p>Gameplay logic remains untouched.</p><p>The focus of this phase is:</p><ul><li>API stability</li><li>Clean monetization model (API-key only)</li><li>Deterministic state flow</li><li>Documentation clarity</li></ul><p>No overengineering.
No unnecessary features.</p><p>Just a tactical game exposed as a protocol.</p><p>Darkwood is not just a backend project.</p><p>It is a game that lives entirely over HTTP.</p><p>And Beta Season 0 is now live.</p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game</link><guid>https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game</guid><enclosure url="http://darkwood.com/media/articles/69acf94561c3d512031768.png" /></item><item><title>🎨 Darkwood v1.0.4 - Introducing Design V4</title><pubDate>Mon, 16 Mar 2026 07:46:05 +0000</pubDate><description><![CDATA[Darkwood v1.0.4 is now live.
This release introduces Design V4, the fourth major visual iteration of Darkwood.
For new readers, there are two different versioning ideas here:

v1.0.4 is the software release
Design V4 is the fourth evolution of Darkwood’s in...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69b7b53dda35a522838829.png" /></p><p>Darkwood <strong>v1.0.4</strong> is now live.</p><p>This release introduces <strong>Design V4</strong>, the fourth major visual iteration of Darkwood.</p><p>For new readers, there are two different versioning ideas here:</p><ul><li><strong>v1.0.4</strong> is the software release</li><li><strong>Design V4</strong> is the fourth evolution of Darkwood’s interface</li></ul><p>Over the years, Darkwood has gone through several design iterations:</p><ul><li><strong>V1</strong> focused on the first visual identity</li><li><strong>V2</strong> explored new layout directions</li><li><strong>V3</strong> refined the brand and overall structure</li><li><strong>V4</strong> reworks navigation across the entire site</li></ul><p>So this release is not “Darkwood version 4” in the product sense.
It is <strong>release v1.0.4</strong>, which brings <strong>Darkwood Design V4</strong>.</p><p>And this matters, because this update is more than visual polish. It also modernizes the technical stack and opens Darkwood to AI-powered workflows.</p><p>Release notes:
<a href="https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4">https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4</a></p><h2>What Is Darkwood?</h2><p>Darkwood is an <strong>API-first tactical game</strong>.</p><p>It is built as both:</p><ul><li>a playable game system</li><li>a technical playground</li><li>a Symfony application designed for long-term experimentation</li></ul><p>The core idea is simple: gameplay should not depend entirely on the graphical interface.</p><p>The UI is important, but the game logic lives in the API first.</p><p>That approach was described previously here:
<a href="https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game">https://blog.darkwood.com/article/darkwood-building-an-api-first-tactical-game</a></p><p>This release continues that direction.</p><p>Darkwood now combines:</p><ul><li>a redesigned interface</li><li>an updated PHP stack</li><li>and MCP integration for AI agents</li></ul><h2>Why Design V4?</h2><p>Over time, Darkwood accumulated layers.</p><p>Pages were added.
Experiments were integrated.
Navigation expanded.</p><p>The result was functional, but not always clear.</p><p>Design V4 focuses on one main objective:</p><p><strong>make navigation feel natural again.</strong></p><p>The biggest change from V3 to V4 is not the brand itself.
It is the way users move through the site.</p><p>Previous iterations were mostly about layout and visual identity.
This one is about <strong>navigation architecture</strong>.</p><p>The new design was first explored with <a href="https://www.pencil.dev">Pencil</a>, which helped accelerate interface studies and layout decisions before implementation.</p><p>It also benefits directly from lessons learned while building <a href="https://uniflow.io/docs">Uniflow</a>.</p><p>In Uniflow, a lot of work went into making menus clearer across desktop and mobile. That experience helped shape Darkwood’s new navigation model.</p><p>A good way to summarize that mindset is:</p><p><strong>Think macro, act micro.</strong></p><p>At a macro level, the platform needs a clear structure.
At a micro level, every interaction needs to stay simple.</p><p>That is the spirit behind Design V4.</p><h2>What Changed in the Interface</h2><h3>A New Navigation Structure</h3><p>The most visible change is the navigation.</p><p>Darkwood now uses a <strong>top-centered navigation</strong> instead of the previous side-oriented structure.</p><p>The site is organized around four main sections:</p><ul><li><strong>Play</strong> - access the tactical game</li><li><strong>World</strong> - explore the universe and context around it</li><li><strong>Journal</strong> - read technical articles and development notes</li><li><strong>Projects</strong> - discover experiments and related work</li></ul><p>This makes the platform easier to understand at first glance.</p><p>Instead of feeling fragmented, the experience is now organized around four clear entry points.</p><p>The same logic is used across desktop and mobile, so the navigation remains consistent regardless of device.</p><h3>A Lighter Header</h3><p>The header was redesigned to feel lighter and more deliberate.</p><p>It stays available during scroll, but with less visual weight.</p><p>The goal was not to make it more decorative.
The goal was to make it more useful.</p><h3>A Reworked Footer</h3><p>The footer was also restructured.</p><p>It now groups content more clearly while staying secondary to the page itself.</p><p>The intention was to improve orientation without making the footer dominate the reading experience.</p><h3>A More Cohesive Visual System</h3><p>Design V4 also introduces a broader cleanup across the site:</p><ul><li>improved spacing</li><li>cleaner button hierarchy</li><li>better mobile navigation</li><li>refined login experience</li><li>more consistent layout behavior</li></ul><p>This is not a radical redesign.
It is a coherence pass across the full experience.</p><h2>Built with an Updated Stack</h2><p>This release also updates Darkwood’s technical foundation.</p><p>Darkwood now runs with:</p><ul><li><strong>PHP 8.5</strong></li><li><strong>Symfony 8</strong></li><li><strong>FrankenPHP v1.12.1</strong></li></ul><p>It also includes:</p><ul><li>migration of controllers from annotations to PHP attributes</li><li>updated Nix and CI configuration</li><li>upgraded recipes and framework configuration</li><li>deprecation fixes around the Darkwood IA Exception Bundle</li><li>production hardening on several points, including SEO, Castor, user serialization, reCAPTCHA, and optional Baserow integration</li></ul><p>The objective here is simple:</p><p>keep the platform current, fast, and maintainable.</p><p>Not for fashion.
For durability.</p><p>Darkwood should be able to grow without carrying avoidable technical friction.</p><h2>MCP Integration for AI Workflows</h2><p>This release also adds <strong>MCP tool integration</strong> through API Platform’s new AI capabilities.</p><p>Reference:
<a href="https://les-tilleuls.coop/blog/sortie-dapi-platform-4-3-rencontre-avec-lia">https://les-tilleuls.coop/blog/sortie-dapi-platform-4-3-rencontre-avec-lia</a></p><p>This fits naturally with Darkwood’s API-first approach.</p><p>If the game logic already exists as an API, exposing it to AI agents becomes an extension of the same philosophy.</p><p>In other words, the tactical game was already programmable.
Now it is also <strong>agent-ready</strong>.</p><h2>DarkwoodGame MCP Tools</h2><p>The <code>DarkwoodGame</code> API resource now exposes four MCP tools:</p><ul><li><p><code>get_darkwood_state</code>
Returns the current game state</p></li><li><p><code>darkwood_action</code>
Executes a game action from input</p></li><li><p><code>list_darkwood_archives</code>
Lists archived puzzle snapshots for premium users</p></li><li><p><code>get_darkwood_archive</code>
Retrieves one archive by id for premium users</p></li></ul><p>All of them use structured content output, which means the API response is directly returned as MCP tool output.</p><p>No new HTTP routes were introduced for this.</p><p>The MCP layer simply exposes existing API capabilities in a way AI agents can consume cleanly.</p><h2>Article MCP Tools</h2><p>Darkwood articles are also now exposed through MCP.</p><p>Two tools were added:</p><ul><li><code>list_articles</code></li><li><code>get_article</code></li></ul><p>This allows AI agents to retrieve structured article data while keeping the same security rules as the API resource itself.</p><p>Again, the goal is not to duplicate the application.
It is to make the existing system accessible through a new interaction layer.</p><h2>Free vs Premium</h2><p>Darkwood currently runs as <strong>Beta Season 0</strong>.</p><p>The commercial proposal remains the same.</p><p>Two types of access keys are available.</p><h3>🎟 Beta Access (Free)</h3><ul><li>Personal API key</li><li>Limited daily actions</li><li>Access to the current playable state</li><li>No archive access</li></ul><h3>💎 Founder Premium</h3><ul><li>Personal API key</li><li>Unlimited daily actions</li><li>Access to archived puzzle snapshots</li><li>Early supporter status</li></ul><p>Archives are read-only snapshots of past playable states.
They expose historical game states without affecting the live game.</p><h2>Limited Founder Release</h2><p>This release stays intentionally small.</p><p>Available now:</p><ul><li>5 Beta Access keys</li><li>5 Founder Premium keys</li></ul><p>That’s all.</p><p>This is not a mass-market launch.
It is a controlled release meant to validate the model.</p><p>Access is handled through Bonzai:</p><p><strong>Beta Access (Free)</strong><a href="https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free">https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free</a></p><p><strong>Founder Premium</strong><a href="https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium">https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium</a></p><p>Each key is personal, and can be rotated if needed.</p><h2>What This Release Really Means</h2><p>Darkwood v1.0.4 is a release with three goals:</p><ul><li>make the interface easier to navigate</li><li>update the technical stack to modern standards</li><li>extend the API-first game model to AI agents through MCP</li></ul><p>Design V4 is the visible part.</p><p>But behind it, the project is also becoming more solid and more open.</p><p>The same tactical game can now be approached through:</p><ul><li>the website</li><li>the API</li><li>and AI-driven workflows</li></ul><p>That continuity matters.</p><p>Darkwood is not being split into separate ideas.
It is becoming more coherent.</p><h2>Explore the Release</h2><p>Darkwood v1.0.4 is live.</p><p>It brings <strong>Design V4</strong>, a modernized Symfony and PHP stack, and MCP integration for the API-first tactical game.</p><p>Explore the interface.
Read the journal.
Access the API.
Or start playing.</p><p>Release:
<a href="https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4">https://github.com/darkwood-com/darkwood-com/releases/tag/v1.0.4</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/darkwood-v1-0-4-introducing-design-v4</link><guid>https://blog.darkwood.com/article/darkwood-v1-0-4-introducing-design-v4</guid><enclosure url="http://darkwood.com/media/articles/69b7b53dda35a522838829.png" /></item><item><title>🎬 The most expensive video on my YouTube channel 💰</title><pubDate>Sat, 21 Mar 2026 16:34:25 +0000</pubDate><description><![CDATA[
I recently published a first draft of the Darkwood trailer:

And yes… you could say that this is probably the most expensive video on my YouTube channel.
Why make a trailer now?
It&#039;s something I&#039;ve had in mind for a while.
Currently, the gameplay shown on...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69bec8925acb4477446748.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/UtpqkdlFspw?si=0kPLaNI01yVELQ5S" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>I recently published a first draft of the Darkwood trailer:</p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/vWrGwZrW4As?si=YclzhK9z9zG_COEV" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>And yes… you could say that this is probably <strong>the most expensive video on my YouTube channel</strong>.</p><p>Why make a trailer now?</p><p>It's something I've had in mind for a while.</p><p>Currently, the gameplay shown on Darkwood remains quite limited:
👉 <a href="https://darkwood.com/rules-of-the-game">https://darkwood.com/rules-of-the-game</a></p><p>The system works, but it still lacks the substance to truly immerse players in the universe.</p><p>👉 That's what the trailer is for.</p><h2>A 100% AI-generated trailer</h2><p>This trailer was entirely generated from:</p><ul><li>a handwritten script</li><li>of AI video generation models</li><li>audio generation AI models</li></ul><p>👉 The result?</p><ul><li>It's not yet at the expected level</li><li>It's even far from what I imagined</li></ul><p>But for an MVP:</p><p>👉 That's acceptable</p><p>And most importantly:</p><ul><li>I spent several hours iterating on the scenario</li><li>to understand the limitations of the models</li><li>to structure the generation</li></ul><h2>⚠️ Why the video is difficult to understand</h2><p>If you watch the trailer:</p><p>👉 You will probably find that it lacks consistency</p><p>And that's normal.</p><p>Each scene is generated independently, which creates:</p><ul><li>visual breaks</li><li>inconsistent characters</li><li>a narrative that is difficult to follow</li></ul><p>👉 So, I'm going to spoil the initial scenario to explain what I really wanted to produce.</p><p>Here is a more <strong>narrative, immersive and deliberately mysterious</strong> version, without explaining the purpose:</p><h2>🎭 The scenario</h2><p>The trailer unfolds in three movements.</p><h3>🌑 Darkwood</h3><p>It all begins in silence.</p><p>A cold glow illuminates the surface of the moon.
Then, slowly, the fall.</p><p>The camera descends, passes through the clouds, and crashes into a dense, black, almost living forest.
Lightning flashes across the sky.
The trees are trembling.
Something is leaking into the darkness.</p><p>A path appears.</p><p>Winding. Narrow.
He guides the camera, as if he had been designed for it.</p><p>At the end: a gate.</p><p>Forged from iron, eaten away by brambles.
It opens without being touched.</p><p>A squeak. Long. Metallic.</p><p>Beyond that, a manor house.
Isolated. Frozen. Observer.</p><p>The door opens a crack.</p><p>Inside, the air is heavy.
A vast hall, shadows gliding along the walls.
Laughter. Quiet. Almost muffled.</p><p>A staircase. Then a corridor.
Then a door.</p><p>It opens.</p><p>A library.</p><p>And there, in the dim light, a silhouette.
Motionless, then slowly animated.</p><p>A pot is boiling.
Impossible colors dance across its surface.</p><p>A voice is raised.</p><p>“Finally… finally… the time has come…”</p><p>A laugh. Too forced. Almost fake.
Then another one.</p><p>The words repeat themselves, follow one another, and are lost in the echo of the room.</p><p>The potion reacts.
She trembles. She swells.</p><p>Then she gives in.</p><p>In this liquid chaos, something is taking shape.</p><p>“You… insignificant…”</p><p>Other names follow.
Other silhouettes.
Forms barely defined, but already present.</p><p>And the voice continues.</p><p>Always.</p><h3>🌈 Happyland</h3><p>The light returns.</p><p>Soft. Warm. Almost too much.</p><p>A forest.
Calm. Welcoming.</p><p>A man is walking.
Quietly. He picks. He observes.</p><p>Then he falls.</p><p>A simple misstep.
A root. Nothing more.</p><p>A voice suddenly appeared.</p><p>“Oh… you fell?”</p><p>A smile.
Then a laugh.</p><p>Another laugh responds.
Then another one.</p><p>They are spreading.</p><p>The man gets up.</p><p>“It’s nothing.”</p><p>But already, something has changed.</p><p>On the way back, glances were exchanged.
Murmurs.</p><p>“It’s him… he fell…”</p><p>In the village, everyone seems to already know.</p><p>The baker smiled.
A bit too much.</p><p>“Is everything alright?”</p><p>He answers yes.</p><p>But the laughter doesn't really stop.
They move.</p><p>They accompany him.</p><p>At home, finally alone, he stops.</p><p>Back against the door.</p><p>Silence.</p><p>Then the thoughts.</p><p>They arrive quickly. Too quickly.</p><p>“Why…?”</p><p>The sentences follow one another, become distorted, and blend together.
Logic. Absurdity. Mathematics.</p><p>“What if…?”</p><p>A doubt.
Then another one.</p><p>And finally, a smile.</p><p>A real one.</p><p>“Yes… the time has come…”</p><p>A laugh escapes him.</p><h3>⚖️ Narrator</h3><p>Two figures.</p><p>One in the shadows.
The other one in the light.</p><p>Or perhaps the opposite.</p><p>A suspended moment.</p><p>Then a voice.</p><p>“And now… what do you think…”</p><p>Silence.</p><blockquote><p>“…which one is the most benevolent?”</p></blockquote><h2>⚙️ Technical Stack</h2><h3>🧠 Architecture</h3><p>The project uses a <strong>Domain-Driven Design</strong> approach:</p><ul><li>Trailer</li><li>Scene</li><li>Asset (audio / video)</li></ul><p>With a clear pipeline:</p><ul><li>scene generation</li><li>generation of assets</li><li>fallback fake</li><li>final rendering</li></ul><h2>The open source project</h2><p>The repository used to generate the trailer is available here:</p><p>👉 <a href="https://github.com/darkwood-com/darkwood-trailer">https://github.com/darkwood-com/darkwood-trailer</a></p><h3>🔁 Orchestration with Flow</h3><p>👉 <a href="https://flow.darkwood.com/">https://flow.darkwood.com/</a></p><p>Flow allows:</p><ul><li>to parallelize the scenes</li><li>to accelerate generation</li><li>to structure the pipeline</li></ul><h3>🤖 Provider AI: Replicate</h3><p>👉 <a href="https://replicate.com/">https://replicate.com/</a></p><h4>🎥 Video</h4><ul><li><code>bytedance/seedance-1-lite</code> → used for the MVP ✅</li><li><code>minimax/hailuo-02-fast</code> → requires additional parameters</li><li><code>p-video</code> → requires an input image</li></ul><h4>🔊 Audio</h4><ul><li><code>minimax/speech-2.6-turbo</code> → used for the MVP ✅</li></ul><p>👉 Seedance was chosen because:</p><ul><li>easy to use</li><li>Only works with a text prompt</li><li>fast enough to iterate</li></ul><h2>Generate your own trailer</h2><p>You can generate your own video from the project.</p><p>The scenario is defined in a YAML file:</p><pre><code class="language-bash">examples/trailer.yaml
</code></pre><p>Then start the generation:</p><pre><code class="language-bash">php bin/console app:trailer:generate examples/trailer.yaml --video-model=seedance
</code></pre><h2>💸 Actual cost</h2><p>After several tests:</p><ul><li>Approximately 30 minutes generated</li><li>~10 iterations</li></ul><p>👉 Total ≈ <strong>€75</strong></p><h3>⚠️ Tip</h3><p>A flag allows you to:
👉 generate only the first scene in real life</p><p>The rest is fake.</p><p>✔️ avoids blowing the budget</p><h2>🧩 Problems identified</h2><ul><li>Add pvideo and hailuo support</li><li>Add FX + soundscape</li><li>Multiple voices (characters + narrator)</li><li>Rework Flow orchestration</li></ul><p>👉 Contributions welcome</p><h2>Conclusion</h2><p>Today, Darkwood is able to generate a complete trailer from a script.</p><p>The result is not yet at the expected level:</p><ul><li>lack of consistency</li><li>difficult-to-follow narrative</li><li>model limitations</li></ul><p>But :</p><p>👉 The pipeline is working
👉 Costs are controllable
👉 and most importantly, the system is iterable</p><p>This trailer is not the end.</p><p>👉 This is a starting point.</p><h2>⚠️ Access to the Darkwood beta</h2><p>The API keys mentioned here:</p><p>👉 <a href="https://blog.darkwood.com/fr/article/darkwood-creer-un-jeu-tactique-axe-sur-les-api">https://blog.darkwood.com/fr/article/darkwood-creer-un-jeu-tactique-axe-sur-les-api</a></p><p>⏳ Valid until <strong>March 25th at midnight</strong></p><p>After :
👉 No more access to the beta</p><p>👉 Remember to collect your key on Bonzai.</p><ul><li><p>Beta Access (Free):
<a href="https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free">https://www.bonzai.pro/matyo91/shop/yDxv_7247/darkwood-api-beta-access-free</a></p></li><li><p>Founder Premium:
<a href="https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium">https://www.bonzai.pro/matyo91/shop/lQxn_7249/darkwood-api-founder-premium</a></p></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/the-most-expensive-video-on-my-youtube-channel</link><guid>https://blog.darkwood.com/article/the-most-expensive-video-on-my-youtube-channel</guid><enclosure url="http://darkwood.com/media/articles/69bec8925acb4477446748.jpg" /></item><item><title>🧠 Expose Nothing. Show Everything - Building Public Systems on Private Foundations</title><pubDate>Fri, 27 Mar 2026 20:46:36 +0000</pubDate><description><![CDATA[
Introduction
Most systems expose too much.
Structure.
Logic.
Intent.
Everything becomes visible.
But visibility is not understanding.
In this video, I’m doing something a bit different.
I’m not just talking about security.
I’m showing what it actually mean...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69c6ed393e77b900400650.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/hMbDIaQpFOw?si=nOSvsD5h7Dnzj9FK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Introduction</h2><p>Most systems expose too much.</p><p>Structure.
Logic.
Intent.</p><p>Everything becomes visible.</p><p>But visibility is not understanding.</p><p>In this video, I’m doing something a bit different.
I’m not just talking about security.</p><p>I’m showing what it actually means.</p><h2>What “security” really means</h2><p>When we talk about security, most people think about:</p><ul><li>authentication</li><li>permissions</li><li>encryption</li></ul><p>But that’s not where it starts.</p><p>Security begins with a much simpler idea:</p><blockquote><p>A system needs secrets.</p></blockquote><p>Not secrets for the sake of hiding.</p><p>But secrets to preserve <strong>control, uncertainty, and integrity</strong>.</p><p>Because in any real environment:</p><blockquote><p>exposure creates attack surface
and transparency can become a weakness</p></blockquote><h2>Introducing Lain (through Navi)</h2><p>Today, I’m releasing a public part of a system I use at Darkwood.</p><p>The repository is called <strong>Navi</strong>.</p><p>But what I’m actually introducing is something deeper:</p><blockquote><p><strong>Lain</strong></p></blockquote><p>Lain is not a product.
It’s not a tool.
It’s not even the system itself.</p><p>It is a <strong>controlled surface</strong>.</p><h2>The role of Navi</h2><p>Navi is the <strong>public layer</strong> of how I work.</p><p>It exposes:</p><ul><li>structure</li><li>architectural patterns</li><li>high-level concepts</li></ul><p>For example:</p><ul><li>Domain-Driven Design (DDD)</li><li>execution flows</li><li>workflows</li><li>infrastructure boundaries</li><li>testing approach</li></ul><p>But it does NOT expose:</p><ul><li>production logic</li><li>real execution</li><li>internal systems</li></ul><h2>Public vs Private</h2><p>At Darkwood, every system is built with a separation:</p><ul><li><strong>Public layer → observable</strong></li><li><strong>Private layer → operational</strong></li></ul><p>The public repository shows <em>how things are structured</em>.</p><p>The private system defines <em>what actually runs</em>.</p><p>And that boundary is intentional.</p><h2>Semi-transparency as a model</h2><p>This approach is not new.</p><p>It is inspired by models like the one I described years ago in Uniflow:</p><p>→ a mixed repository approach
→ public + private
→ with the private system importing the public one</p><p>This creates something important:</p><blockquote><p><strong>semi-transparency</strong></p></blockquote><p>You can see enough to understand the structure.</p><p>But not enough to reproduce or exploit the system.</p><h2>Security as architecture</h2><p>Security is not a layer you add.</p><p>It is something you design from the beginning.</p><ul><li>You define boundaries</li><li>You control what is exposed</li><li>You separate execution from representation</li></ul><p>In this model:</p><blockquote><p>what you see is not what runs</p></blockquote><p>And that is the point.</p><h2>Why expose anything at all?</h2><p>Because systems need to be:</p><ul><li>observed</li><li>partially understood</li><li>trusted</li></ul><p>But trust does not require full access.</p><p>It requires coherence.</p><p>Navi is not here to “teach everything”.</p><p>It is here to show:</p><blockquote><p>how a system can be exposed
without exposing itself</p></blockquote><h2>On Lain and Navi</h2><p>The naming is intentional.</p><p>It comes from <em>Serial Experiments Lain</em>.</p><p>In that world:</p><ul><li>Lain interacts with a system</li><li>through a machine called <strong>Navi</strong></li><li>which gives access to information</li></ul><p>That idea stayed with me.</p><p>So I reused it.</p><p>Not as a reference.</p><p>But as a structure.</p><h2>The system behind</h2><p>At Darkwood, Navi is only one piece.</p><p>There are others:</p><ul><li>orchestration systems</li><li>internal tooling</li><li>production layers</li><li>experimental systems</li></ul><p>Some are public.</p><p>Most are not.</p><p>And that balance is what defines the system.</p><h2>Evolution</h2><p>Navi is minimal by design.</p><p>It is a starting point.</p><p>A structure.</p><p>A foundation.</p><p>It will evolve over time.</p><p>But its purpose will remain the same:</p><blockquote><p>expose structure
keep execution private</p></blockquote><h2>Conclusion</h2><p>The goal is not to hide.</p><p>The goal is to decide what is visible.</p><p>And what is not.</p><h2>Watch the video</h2><p>This article is tied to a video where I explain and demonstrate this approach.</p><p>👉 Watch the full breakdown to see how it applies in practice.</p><h2>Repository</h2><p>👉 <a href="https://github.com/darkwood-com/navi">https://github.com/darkwood-com/navi</a></p><h2>Final note</h2><p>Some systems are built to be used.</p><p>Others are built to be understood.</p><p>And some are built to be observed…</p><p>without ever being fully known.</p><h2>Sources</h2><ul><li>Unsupervised Learning: Security, Secrecy, and Obscurity : <a href="https://www.youtube.com/watch?v=V2X0twHBGqE">https://www.youtube.com/watch?v=V2X0twHBGqE</a></li><li>Lain : <a href="https://darkwood.com/profile/matyo">https://darkwood.com/profile/matyo</a> and <a href="https://darkwood.com/profile/lain">https://darkwood.com/profile/lain</a></li><li>Darkwood Navi : <a href="https://github.com/darkwood-com/navi">https://github.com/darkwood-com/navi</a></li><li>Uniflow How we manage sourcing ? : <a href="https://uniflow.io/blog/2019-10-17-how-we-manage-sourcing">https://uniflow.io/blog/2019-10-17-how-we-manage-sourcing</a></li><li>Flow : <a href="https://flow.darkwood.com">https://flow.darkwood.com</a></li><li>Le gardien du Savoir : <a href="https://apps.darkwood.com/lgs">https://apps.darkwood.com/lgs</a></li><li>Darkwaar Will you be the darkest one at waar ? : <a href="https://darkwaar.com/blog/2020-08-20-welcome-darkwaar">https://darkwaar.com/blog/2020-08-20-welcome-darkwaar</a></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/expose-nothing-show-everything-building-public-systems-on-private-foundations</link><guid>https://blog.darkwood.com/article/expose-nothing-show-everything-building-public-systems-on-private-foundations</guid><enclosure url="http://darkwood.com/media/articles/69c6ed393e77b900400650.png" /></item><item><title>🗂️ Hellcats Over The Pacific - ouverture des archives</title><pubDate>Mon, 30 Mar 2026 07:09:19 +0000</pubDate><description><![CDATA[There are games that disappear.
Not because they were removed.
But because their environment disappeared with them.
This is the case with Hellcats Over The Pacific.
An aerial combat game released in 1991 on Mac.
Designed for a system that no longer exists t...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69ca219fcf58f234452919.png" /></p><p>There are games that disappear.</p><p>Not because they were removed.
But because their environment disappeared with them.</p><p>This is the case with Hellcats Over The Pacific.</p><p>An aerial combat game released in 1991 on Mac.
Designed for a system that no longer exists today.</p><h2>🖥️ Replaying is not enough</h2><p><img src="/blog/images/articles/hellcats-over-the-pacific/hellcats.jpg" alt="Hellcats" /></p><p><img src="/blog/images/articles/hellcats-over-the-pacific/resedit.png" alt="Resedit" /></p><p><img src="/blog/images/articles/hellcats-over-the-pacific/Hellcats_Over_The_Pacific_Mac_Original_1991_Box_Cover.jpg" alt="Hellcats_Over_The_Pacific_Mac_Original_1991_Box_Cover" /></p><p><img src="/blog/images/articles/hellcats-over-the-pacific/Hellcats_bombing_run.png" alt="Hellcats_bombing_run" /></p><p>The game is still accessible.</p><p>It can be restarted via:</p><ul><li><a href="https://infinitemac.org/1996/System%207.5.3?utm_source=chatgpt.com">System 7.5.3 (InfiniteMac)</a></li><li><a href="https://infinitemac.org/1999/Mac%20OS%209.0?utm_source=chatgpt.com">Mac OS 9.0 (InfiniteMac)</a></li></ul><p>But restarting is not the same as understanding.</p><p>What interests me here is not playing it.
It's about <strong>understanding what remains of the system</strong>.</p><h2>💾 A forgotten constraint</h2><p><img src="/blog/images/articles/hellcats-over-the-pacific/disquette.jpeg" alt="disquette" /></p><p><img src="/blog/images/articles/hellcats-over-the-pacific/mac_classic.jpg" alt="mac_classic" /></p><p><img src="/blog/images/articles/hellcats-over-the-pacific/101-jeux-mac.jpg" alt="101-jeux-mac" /></p><p>This game fit on <strong>a single floppy disk</strong>.</p><p>A 3D game.
Yes, on a Mac like the Macintosh II.
In <strong>256 colours</strong>.</p><p>At the time, it seemed almost impossible.</p><p>Today, it mainly raises one question:</p><p>What has been sacrificed, compressed, or reinvented to make it work?</p><h2>🧾 The artifacts</h2><p>On classic Mac OS, a program is not a simple file.</p><p>It is composed of two layers:</p><ul><li>the <strong>data</strong></li><li>the <strong>resources</strong> (UI, sounds, structures…)</li></ul><p>These resources are accessible via ResEdit.
A tool that allows you to explore what the game still reveals.</p><p>But the logic of the game is not found there.</p><p>It's in the binary.</p><h2>🧠 An old attempt</h2><p>Long before this project, I had already tried to rebuild a similar simulation.</p><p>Starting from scratch.</p><p>Based on:</p><ul><li>physical formulas</li><li>forces applied to an airplane</li><li>simplified mathematical models</li></ul><p>I had filled entire pages with writing.</p><p>These notes are now lost.</p><p>But the intention was already there:</p><blockquote><p><strong>understand the system, not just reproduce it visually</strong></p></blockquote><p>I also wanted to recreate it faithfully:</p><ul><li>the maps</li><li>the environments</li><li>the constraints of the original game</li></ul><p>Without access to the code.</p><h2>🧠 Reading the ghost code</h2><p>Today, the approach is different.</p><p>I use Ghidra.</p><p>Objective :</p><ul><li>Retrieve the executable segments</li><li>Rebuild the functions</li><li>Identify the structures still present</li></ul><p>This is not a rewrite.
This is not emulation.</p><p>This is an attempt at <strong>reading</strong>.</p><h2>🧱 Current status</h2><p>The work submission is public:
<a href="https://github.com/matyo91/hellcats-over-the-pacific?utm_source=chatgpt.com">github.com/matyo91/hellcats-over-the-pacific</a></p><p>For now, it contains:</p><ul><li>exports resulting from decompilation</li><li>reconstructed code fragments</li><li>usable traces</li></ul><p>Nothing is “clean”.
Nothing is final.</p><p>It's an <strong>archive project</strong>.</p><h2>📌 Position</h2><p>I am not trying to:</p><ul><li>modernize the game</li><li>reinventing its gameplay</li><li>produce a “remastered” version</li></ul><p>I am looking to:</p><ul><li>understand what has been written</li><li>document what is still legible</li><li>Reconstruct only what can be proven</li></ul><h2>🔍 Continued</h2><p>Each step forward will be based on:</p><ul><li>a real artifact</li><li>a verifiable observation</li><li>an accepted limit</li></ul><p>Nothing more.</p><p>👉 Game source:</p><ul><li><a href="https://www.jeuxvideo.com/jeux/mac/00008302-hellcats-over-the-pacific.htm?utm_source=chatgpt.com">Jeuxvideo.com file</a></li><li><a href="https://en.wikipedia.org/wiki/Hellcats_over_the_Pacific?utm_source=chatgpt.com">Wikipedia</a></li></ul><p>👉 Reverse engineering:</p><ul><li><a href="https://korben.info/un-launcher-ghidra-pour-macos.html?utm_source=chatgpt.com">Install Ghidra (macOS)</a></li></ul><p>🎨 Cover credit : <a href="https://www.myabandonware.com/game/hellcats-over-the-pacific-3ky">https://www.myabandonware.com/game/hellcats-over-the-pacific-3ky</a></p>
]]></content:encoded><link>https://blog.darkwood.com/article/hellcats-over-the-pacific-ouverture-des-archives</link><guid>https://blog.darkwood.com/article/hellcats-over-the-pacific-ouverture-des-archives</guid><enclosure url="http://darkwood.com/media/articles/69ca219fcf58f234452919.png" /></item><item><title>💡 I created a GDPR-compliant AI app in 1 hour with Symfony</title><pubDate>Thu, 02 Apr 2026 17:36:52 +0000</pubDate><description><![CDATA[
Today, many developers use AI to generate code.
The question we are addressing here is the following:

👉 How ​​to transform an idea into an executable system?

And that&#039;s normal.
Because we learned to:

coding features
write functions
connect APIs

But not...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/rss_cover/media/articles/69cea936a2cce321575605.png" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/OM15Zqs8NM4?si=1NNtBl-xuuTsdpm9" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><p>Today, many developers use AI to generate code.</p><p>The question we are addressing here is the following:</p><blockquote><p>👉 <strong>How ​​to transform an idea into an executable system?</strong></p></blockquote><p>And that's normal.</p><p>Because we learned to:</p><ul><li>coding features</li><li>write functions</li><li>connect APIs</li></ul><p>But not to:</p><blockquote><p><strong>structuring an idea so that it can be executed</strong></p></blockquote><p>At Darkwood, we never start with the code.</p><p>We begin with a much more fundamental step:</p><blockquote><p>👉 <strong>the reasoning</strong></p></blockquote><p>In this article, we will look at the following in concrete terms:</p><ol><li>How to transform an idea into a usable unit</li><li>How to use AI to execute this idea</li><li>How to apply this in a real project: <strong>SketchUp Shape</strong></li></ol><h2>🧠 1. An idea is not code</h2><p>When you think:</p><pre><code class="language-text">“Créer une application”
</code></pre><p>Your reflex as a developer is often:</p><blockquote><p>“Okay, I’m going to code an API, a database, etc.”</p></blockquote><p>👉 Bad starting point.</p><p>An idea is not yet something you can execute.</p><p>That's right:</p><blockquote><p>👉 a <strong>vague intention</strong></p></blockquote><h2>💡 The right mental model</h2><p>At Darkwood, we believe that:</p><blockquote><p>👉 <strong>one idea = one task</strong></p></blockquote><p>No more, no less.</p><h3>Example</h3><pre><code class="language-text">“Créer une application”
</code></pre><p>becomes :</p><pre><code class="language-text">Task: create_app
</code></pre><p>It may seem trivial.</p><p>But this is a significant change:</p><p>👉 You no longer think in terms of “projects”
👉 You think in <strong>executable units</strong></p><h1>⚙️ Why this method works: Church, Turing, and the idea as an executable unit</h1><p>One might think that “prompting an AI” is a recent, almost purely practical topic, linked to current LLM news.</p><p>In reality, the problem is much older.</p><p>When a developer takes an idea and tries to turn it into an executable system, they always encounter the same question:</p><p>How do we move from an abstract intention to a form that the machine can actually process?</p><p>This is exactly the type of question that lies at the root of theoretical computer science.</p><p>In a previous Darkwood article - <a href="https://blog.darkwood.com/index.php/fr/article/create-a-lambda-interpreter-in-php-1"><em>Create a Lambda Interpreter in PHP</em></a> - we already explored this boundary between:</p><ul><li><strong>the idea of ​​a calculation</strong></li><li>and <strong>its actual execution by a machine</strong></li></ul><p>This article started with Alonzo Church's λ-calculus, then linked it to the Turing machine, recalling a fundamental point:</p><blockquote><p><strong>The λ-calculus and the Turing machine are two equivalent models of computation</strong></p></blockquote><p>In other words:</p><ul><li>Church provides a <strong>conceptual model</strong></li><li>Turing provides a <strong>model of execution</strong></li></ul><p>And that's exactly what interests us here.</p><h2>🧠 Church: before execution, a conceivable form is necessary</h2><p>Alonzo Church does not start from a machine.
It stems from a much deeper problem:</p><p>What is a function?</p><blockquote><p>and more broadly:</p></blockquote><p>What is a calculation?</p><p>The λ-calculus responds to this with a radical idea:</p><p>Any calculation can be expressed as an abstraction and application of functions.</p><p>In this model:</p><ul><li>A function is a transformation</li><li>a value can be passed to another function</li><li>and evaluation consists of applying functions to one another</li></ul><p>This is the theoretical root of many things we use today without thinking about it:</p><ul><li>functional programming</li><li>the currying</li><li>closures</li><li>the combinators</li><li>pure transformations</li><li>DSLs</li></ul><p>In the article on the lambda interpreter in PHP, this idea was presented in a very concrete way:
We started with an expression, tokenized it, parsed it, built an AST, and then evaluated it.</p><p>In other words:</p><blockquote><p>before a system executes something,
First, it must <strong>understand a form</strong></p></blockquote><p>This is exactly the point that interests us regarding AI.</p><p>When you give an LLM a sentence like:</p><pre><code class="language-text">Create a house
</code></pre><p>You haven't given it an execution yet.
You give it an <strong>abstract form</strong>, an intention, a request that is still insufficiently structured.</p><p>And that's where Church's intuition becomes useful to us.</p><h3>Developer translation</h3><p>When we talk about ideas in this article, we are not talking about vague inspiration or brainstorming.</p><p>We are already talking about a <strong>manipulable abstraction</strong>.</p><p>In other words:</p><p>An idea must become a unit upon which a system can reason.</p><p>That's why, at Darkwood, we make an initial mental shift:</p><p>An idea is not yet code.</p><blockquote></blockquote><p>An idea is already a transformation in progress.</p><p>Or, to put it another way:</p><p>An idea is a potential task</p><h2>⚙️ Turing: once the form is defined, it must be executed</h2><p>Church formalizes calculation on the side of abstraction.
Turing, however, answers a different question:</p><p>What does a machine capable of performing this calculation look like?</p><p>His answer is famous:</p><ul><li>a memory strip</li><li>a reading head</li><li>a current state</li><li>transition rules</li></ul><p>The power of the model does not come from its complexity, but rather from its simplicity.</p><p>A Turing machine reads a cell, takes its state into account, applies a rule, possibly writes something, and then moves on.</p><p>It's an extremely simple model, but sufficient to reason about what a machine can do.</p><p>What interests us here is not teaching the entire theory of automata.
It's about recovering a very concrete intuition:</p><p>An executable system needs readable units.</p><blockquote></blockquote><p>and a clear mechanism for switching from one state to the other</p><p>This is where the link with modern work on ideas, tasks, and AI agents becomes very concrete.</p><h2>🔁 What Church and Turing teach us about working with AI</h2><p>The essential point is this:</p><ul><li>Church teaches us to think of calculation as <strong>transformation</strong></li><li>Turing teaches us to think of computation as <strong>structured execution</strong></li></ul><p>When you combine the two, you get a much healthier way of working with AI.</p><p>We stop thinking:</p><p>“I’m going to ask the model for some code”</p><p>And we start to think:</p><blockquote><p>“I’m going to give him a structured unit of work,
that he will be able to transform,
then another system can execute”</p></blockquote><p>That's exactly what we do at Darkwood.</p><h2>🧩 Darkwood translation: an idea becomes a task</h2><p>At this stage, we can simplify the model without betraying it.</p><p>Here is the translation we are using as a basis:</p><p>| Theoretical concept | Darkwood interpretation |
| ----------------- | ---------------------------- |
| Abstraction | Structured idea |
| Function | Transformation |
| Memory slot | Task |
| Strip | To-do list / stack |
| Read | Execute |
| Transition | Change from one state to another |</p><p>This gives us a simple rule:</p><blockquote><p><strong>an idea becomes a task</strong></p><p><strong>a task becomes a readable unit</strong></p></blockquote><p>A readable unit can be executed.</p><p>It is this change of perspective that matters.</p><p>Because as long as an idea remains only in your head, it is unusable by the system:</p><ul><li>nor your terminal</li><li>nor your IDE</li><li>nor your LLM</li><li>nor your orchestrator</li></ul><p>cannot work on it properly.</p><p>It therefore needs to be given a form.</p><h2>💡 The idea as a unit of calculation</h2><p>This is where our method becomes truly meaningful.</p><p>When we say:</p><pre><code class="language-text">Créer une application
</code></pre><p>It's not a system yet.
This is not yet architecture.
This is not yet a usable prompt.</p><p>But it's not &quot;nothing&quot; either.</p><p>That's already it:</p><blockquote><p>a unit of calculation to be specified</p></blockquote><p>At Darkwood, we put it through a nomination and reduction stage.</p><p>For example :</p><pre><code class="language-text">Task: create_app
</code></pre><p>Or</p><pre><code class="language-text">Task: generate_sketchup_shape
</code></pre><p>From this point on, the machine - or the system of agents - no longer manipulates just a human sentence.
She is manipulating an identifiable task.</p><p>And once you can identify a task, you can:</p><ul><li>store it</li><li>reread it</li><li>reproduce it</li><li>transmit it</li><li>cut it</li><li>parallelize it</li><li>to orchestrate it</li></ul><p>That's it, that's the real change.</p><h2>🧠 Why this is so useful for a developer</h2><p>A developer often tends to jump directly to implementation:</p><ul><li>create a folder</li><li>Install Symfony</li><li>connect an API</li><li>write an order</li></ul><p>But if the initial idea has not been modeled correctly, everything else becomes unstable.</p><p>This leads to what many people experience with LLMs today:</p><ul><li>vague prompts</li><li>unclear outputs</li><li>fragile structures</li><li>projects that “work”, but lack coherence</li></ul><p>The theory of Church and Turing reminds us of something very simple:</p><p>The quality of the execution depends on the quality of the initial representation.</p><p>In other words:</p><p>If you want to improve the performance of an AI,
First, you need to represent your idea better.</p><p>And that's precisely what we're going to do next with SketchUp Shape:</p><ul><li>starting from an intention</li><li>convert it into a task</li><li>to structure it</li><li>transform it into a design</li><li>then only in code</li></ul><h2>🧭 The rule to remember</h2><p>If this entire section had to be condensed into a single sentence, it would be this:</p><p>A useful idea for AI is not an inspiration.</p><blockquote><p><strong>It's a sufficiently clear abstraction to become an executable task</strong></p></blockquote><p>And that's where Church and Turing cease to be distant theory.</p><p>They become a practical model for the modern developer:</p><ul><li>Church helps you think about form</li><li>Turing helps you think about execution</li><li>Darkwood helps you connect the two</li></ul><h1>📚 Concrete example</h1><p>You have several ideas:</p><pre><code class="language-text">- créer une app
- construire une API
- générer un modèle 3D
</code></pre><p>👉 You can represent them as a stack:</p><pre><code class="language-text">Stack:
- create_app
- build_api
- generate_model
</code></pre><p>And then, everything becomes simpler:</p><p>You can handle each task <strong>one by one</strong></p><p>Or</p><blockquote><p>in parallel</p></blockquote><h1>⚡ 2. Your brain already works like this</h1><p>You don't need to learn a new system.</p><p>👉 You're already using it.</p><h2>🧠 Simple case: different tasks</h2><pre><code class="language-text">Task A: répondre à un message
Task B: installer un package
</code></pre><p>👉 No link
👉 You can easily switch between them</p><h2>⚠️ Complicated case: similar tasks</h2><pre><code class="language-text">Task A: coder une API
Task B: refactor la même API
</code></pre><p>👉 Now, things are getting tough</p><p>For what ?</p><ul><li>same context</li><li>same mental variables</li><li>same files</li></ul><p>👉 Result:</p><ul><li>confusion</li><li>errors</li><li>fatigue</li></ul><h2>💥 What this implies</h2><p>Your brain:</p><ul><li>has limited memory</li><li>handles too much context poorly</li><li>saturates quickly</li></ul><p>👉 So:</p><p>You can't manage many complex tasks at the same time.</p><h1>🧩 3. The real problem: reproducibility</h1><p>A task is only valuable if you can:</p><ul><li>find her</li><li>to revive it</li><li>share it</li></ul><p>👉 Otherwise, it stays in your head
👉 and she disappears</p><h2>🧠 Darkwood Approach</h2><p>We introduce a simple idea:</p><blockquote><p>👉 <strong>one task = one pointer</strong></p></blockquote><h3>In concrete terms</h3><ul><li>You write your task in Joplin</li><li>she has an ID</li><li>This ID becomes your “pointer”</li></ul><p>And then:</p><ul><li>in your terminal → you are referencing this task</li><li>in your IDE → same</li><li>in your AI → same</li></ul><p>👉 Result:</p><blockquote><p>you manipulate <strong>the same object</strong>, everywhere</p></blockquote><h2>💡 What this changes</h2><p>You no longer say:</p><p>“I’m going to work on my idea.”</p><p>You say:</p><p>“I will carry out this task”</p><p>And that's much more powerful.</p><h1>⚙️ 4. AI: not a magic tool, an execution system</h1><p>Today, many developers use AI like this:</p><ul><li>“generate a function for me”</li><li>“write me a class”</li><li>“Fixes this bug”</li></ul><p>👉 It works.</p><p>But you remain within a certain logic:</p><blockquote><p><strong>responsive</strong></p></blockquote><h2>🧠 Darkwood Approach</h2><p>We completely change the perspective:</p><blockquote><p>👉 AI is becoming an <strong>execution system</strong></p></blockquote><h2>🏗 We model like a business</h2><p>Rather than “magical agents”, a simple structure is used:</p><h3>👤 You (human)</h3><ul><li>you define the intention</li><li>you pose the problem</li></ul><h3>🧠 AI Architect</h3><ul><li>he understands your intention</li><li>he breaks it down into tasks</li><li>he decides how to organize the system</li></ul><h3>⚙️ Agents</h3><ul><li>they execute</li><li>they produce code</li><li>they transform the data</li></ul><h2>💡 Key Rule</h2><blockquote><p>👉 <strong>The prompt = your intention</strong></p></blockquote><p>If your prompt is unclear:</p><p>👉 the system is unclear</p><p>If your prompt is structured:</p><p>👉 the system becomes structured</p><h2>🔥 Example</h2><p>❌ Bad prompt:</p><pre><code class="language-text">“Generate a house”
</code></pre><p>✅ Good prompt:</p><pre><code class="language-text">“Create a structured architectural design of a house,
with walls, roof, proportions and constraints,
then generate SketchUp Ruby code from it”
</code></pre><p>👉 Here, you give:</p><ul><li>a direction</li><li>a structure</li><li>a clear objective</li></ul><h1>🧠 What you need to remember</h1><p>👉 You don't need to be better at coding</p><p>👉 You need to get better at:</p><ul><li>structuring</li><li>intention</li><li>orchestration</li></ul><p>And that's exactly what we're going to apply now with:</p><blockquote><p>👉 <strong>SketchUp Shape</strong></p></blockquote><h1>🚀 5. Practical application: SketchUp Shape</h1><p>Project :
👉 <a href="https://github.com/matyo91/sketchup-shape">https://github.com/matyo91/sketchup-shape</a></p><h2>🎯 Objective</h2><p>Transformer:</p><pre><code class="language-text">“Create a house”
</code></pre><p>in:</p><p>👉 Ruby script executable in <a href="https://sketchup.trimble.com/?utm_source=chatgpt.com">SketchUp</a></p><h2>🧱 Why SketchUp?</h2><ul><li>3D modeling tool</li><li>Documented Ruby API:
→ <a href="https://ruby.sketchup.com/?utm_source=chatgpt.com">SketchUp Ruby API</a></li><li>extensible (plugins, scripts)</li></ul><h2>🎓 Context</h2><p>I personally learned SketchUp with
<a href="https://www.youtube.com/@sebastienmaison?utm_source=chatgpt.com">Sébastien Maison (YouTube)</a></p><p>👉 Here, the goal is not to use their AI:</p><p>→ <a href="https://sketchup.trimble.com/fr/ai-in-sketchup?utm_source=chatgpt.com">Official SketchUp AI</a></p><p>👉 But to build <strong>our own system</strong></p><h1>⚙️ 6. Pipeline: from idea to (concrete) 3D model</h1><p>Before going any further, let's take a real-life example.</p><p>👉 Here, we're not talking about an abstract API
👉 We're talking about <strong>generating a 3D object in SketchUp</strong></p><h2>🧱 A little background: why SketchUp?</h2><p><a href="https://sketchup.trimble.com/fr?utm_source=chatgpt.com">SketchUp</a> is a widely used 3D modeling tool:</p><ul><li>architecture</li><li>design</li><li>prototyping</li></ul><p>Personally, I discovered SketchUp thanks to <a href="https://www.youtube.com/@sebastienmaison?utm_source=chatgpt.com">Sébastien Maison</a>, with whom I took a course.</p><p>👉 I modeled a house there “by hand”</p><p>And that's where the idea came from:</p><blockquote><p>👉 “What if I could generate that directly with code?”</p></blockquote><h2>⚠️ Why not use SketchUp's native AI?</h2><p>SketchUp already offers AI:</p><p>👉 <a href="https://sketchup.trimble.com/fr/ai-in-sketchup?utm_source=chatgpt.com">SketchUp AI</a></p><p>But that's not the point here.</p><p>👉 We are developers.</p><p>👉 We want:</p><ul><li>to understand</li><li>control</li><li>automate</li></ul><p>So we go through:</p><blockquote><p>👉 <strong>SketchUp Ruby API</strong></p></blockquote><h2>🧠 The technical entrance</h2><p>To do this, SketchUp explains:</p><ul><li><a href="https://developer.sketchup.com/learn?utm_source=chatgpt.com">Developer documentation</a></li><li><a href="https://ruby.sketchup.com/?utm_source=chatgpt.com">Ruby API</a></li></ul><p>👉 In concrete terms:</p><p>You write Ruby like this:</p><pre><code class="language-ruby">model = Sketchup.active_model
entities = model.entities
</code></pre><p>And you build:</p><ul><li>faces</li><li>volumes</li><li>groups</li></ul><h2>🧩 Resources used</h2><p>To make the AI ​​more reliable, I used:</p><ul><li><p><a href="https://github.com/SketchUp/ruby-api-stubs?utm_source=chatgpt.com">Ruby API Stubs</a>
👉 to give the LLM a clear view of the available objects</p></li><li><p><a href="https://github.com/SketchUp/sketchup-ruby-api-tutorials/tree/main/examples?utm_source=chatgpt.com">Official examples</a>
👉 to understand the real patterns</p></li></ul><p>And if you want to go further:</p><p>👉 <a href="https://extensions.sketchup.com/extension/add?utm_source=chatgpt.com">SketchUp Extensions</a>
→ You can package your code as a plugin</p><h2>⚠️ Important prerequisite</h2><p>To run Ruby:</p><p>👉 You must use the desktop version:</p><p><a href="https://sketchup.trimble.com/fr/products/sketchup-pro/trial?utm_source=chatgpt.com">SketchUp Pro Trial</a></p><p>👉 The web version does not allow this (or only in very limited ways)</p><h1>🔁 Pipeline Darkwood (applied)</h1><p>Now that we have the context, here is the actual pipeline:</p><pre><code class="language-text">Intention
   ↓
Design (LLM #1)
   ↓
Code (LLM #2)
   ↓
SketchUp
</code></pre><h2>🧠 Step 1: Intention</h2><p>You start with a simple idea:</p><pre><code class="language-bash">bin/console app:generate-shape &quot;Create a house&quot;
</code></pre><p>👉 Nothing more.</p><h2>🧱 Step 2: Design (LLM #1)</h2><p>Here, AI does not code.</p><p>👉 She <strong>thinks</strong></p><p>She acts like an architect:</p><pre><code class="language-json">{
  &quot;type&quot;: &quot;house&quot;,
  &quot;structure&quot;: {
    &quot;walls&quot;: {...},
    &quot;roof&quot;: {...}
  }
}
</code></pre><p>👉 She decides:</p><ul><li>proportions</li><li>elements</li><li>of the structure</li></ul><h2>⚙️ Step 3: Code (LLM #2)</h2><p>Only then:</p><p>👉 a second AI transforms this plan into code</p><pre><code class="language-ruby">model.start_operation('House', true)
...
model.commit_operation
</code></pre><p>👉 She acts like a developer:</p><ul><li>It uses the SketchUp API</li><li>she constructs the geometry</li></ul><h1>⚠️ 7. Why 2 LLMs (and not 1)</h1><p>This is one of the most important parts.</p><h2>❌ Naive approach</h2><pre><code class="language-text">idée → code
</code></pre><p>👉 What you get:</p><ul><li>inconsistent</li><li>unpredictable</li><li>difficult to correct</li></ul><h2>✅ Darkwood Approach</h2><pre><code class="language-text">idée → design → code
</code></pre><p>👉 You separate:</p><ul><li>🧠 the <strong>what</strong></li><li>⚙️ the <strong>comment</strong></li></ul><p>💡 It's exactly like in a team:</p><ul><li>architect → decides</li><li>developer → implements</li></ul><h1>🧠 8. The real problem encountered</h1><p>When I launched:</p><pre><code class="language-bash">Create a house
</code></pre><p>👉 Result:</p><ul><li>technically valid</li><li>but visually… false</li></ul><p>👉 It wasn't a house</p><h2>❌ Why?</h2><p>Because AI did this:</p><p>“A house = shapes”</p><p>👉 She stacked:</p><ul><li>cubes</li><li>a roof</li><li>without logic</li></ul><h2>💥 The real problem</h2><p>AI doesn't understand:</p><ul><li>gravity</li><li>the proportions</li><li>actual usage</li></ul><p>👉 She doesn't understand:</p><blockquote><p>what a house is</p></blockquote><h2>🧠 Correction made</h2><p>A layer was introduced:</p><blockquote><p>👉 <strong>structured design</strong></p></blockquote><p>Instead of :</p><pre><code class="language-json">{ &quot;parts&quot;: [...] }
</code></pre><p>We force:</p><pre><code class="language-json">{
  &quot;type&quot;: &quot;house&quot;,
  &quot;foundation&quot;: {...},
  &quot;walls&quot;: {...},
  &quot;roof&quot;: {...},
  &quot;constraints&quot;: {
    &quot;symmetry&quot;: true,
    &quot;alignment&quot;: &quot;centered&quot;
  }
}
</code></pre><p>👉 Result:</p><ul><li>consistency</li><li>stability</li><li>made credible</li></ul><h1>⚙️ 10. Technical Stack</h1><h2>🧱 Backend</h2><ul><li>Symfony 8</li><li>Symfony AI</li><li><code>darkwood/navi</code></li></ul><p>👉 Installation:</p><pre><code class="language-bash">composer require darkwood/navi
</code></pre><h2>🧠 Local AI (GDPR)</h2><ul><li><a href="https://mistral.ai/news/mistral-3">Mistral 3</a></li><li><a href="https://ollama.com/library/ministral-3">Ollama</a></li></ul><p>👉 everything runs locally</p><h2>⚖️ Why this is important</h2><ul><li>no external API</li><li>no data leak</li><li>total control</li></ul><p>👉 You build a system:</p><blockquote><p><strong>GDPR compliant by design</strong></p></blockquote><h1>⚙️ 11. Orders</h1><h2>🧠 Local LLM</h2><pre><code class="language-bash">ollama pull ministral-3:8b
ollama serve
</code></pre><h2>⚙️ Generation</h2><pre><code class="language-bash">bin/console app:generate-shape &quot;Create a house&quot;
</code></pre><h2>Useful Options</h2><pre><code class="language-bash">-o house.rb        # sauvegarde du script
--spec design.json # sauvegarde du design
-v                 # debug complet
</code></pre><h1>🧠 12. What you really need to remember</h1><h2>❌ This is not:</h2><ul><li>“How to use AI”</li></ul><h2>✅ It is:</h2><blockquote><p>👉 <strong>How ​​to structure an idea so that an AI can execute it</strong></p></blockquote><h1>🔁 Final Model</h1><pre><code class="language-text">idée
 → tâche
 → design
 → code
 → exécution
</code></pre><h1>🚀 Conclusion</h1><p>The future of development is not:</p><blockquote><p>write more code</p></blockquote><p>But :</p><blockquote><p>structuring ideas
and orchestrate their execution</p></blockquote><p>👉 At Darkwood:</p><p>we are not trying to go faster</p><blockquote><p>we are trying to be fairer</p></blockquote>
]]></content:encoded><link>https://blog.darkwood.com/article/i-created-a-gdpr-compliant-ai-app-in-1-hour-with-symfony</link><guid>https://blog.darkwood.com/article/i-created-a-gdpr-compliant-ai-app-in-1-hour-with-symfony</guid><enclosure url="http://darkwood.com/media/articles/69cea936a2cce321575605.png" /></item><item><title>🤩 Unleach connectors - From Tools to Language</title><pubDate>Mon, 13 Apr 2026 18:27:43 +0000</pubDate><description><![CDATA[
Introduction
Automation has reached a paradox.
We have never had so many tools:

connectors
workflows
orchestration engines
AI agents

Yet, something fundamental is still missing.

We don’t have a language.

This article revisits a previous experiment arou...]]></description><content:encoded><![CDATA[<p><img src="https://darkwood.com/media/cache/resolve/rss_cover/media/articles/69dd35a0be2a0899189460.jpg" /></p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/GIapXGIdPng?si=NzHCxjnvV8BgqcWY" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Introduction</h2><p>Automation has reached a paradox.</p><p>We have never had so many tools:</p><ul><li>connectors</li><li>workflows</li><li>orchestration engines</li><li>AI agents</li></ul><p>Yet, something fundamental is still missing.</p><blockquote><p>We don’t have a language.</p></blockquote><p>This article revisits a previous experiment around Composio and MCP, and introduces a new direction:</p><blockquote><p><strong>Automation should not be a workflow. It should be a language.</strong></p></blockquote><h2>Revisiting the First Approach</h2><p>A year ago, an implementation was proposed to automate Gmail and Google Calendar using PHP agents, MCP, and Composio.</p><p>The system relied on:</p><ul><li>tool exposure via MCP</li><li>connector orchestration</li><li>agent-driven execution</li></ul><p>While functional, this approach had structural limitations:</p><ul><li>tight coupling to specific providers (Composio)</li><li>workflow-centric design</li><li>lack of composability</li><li>no abstraction of intent</li></ul><p>This led to the archival of the original project:
→ <code>composio-mcp</code></p><p>The problem was not the tools.</p><p>The problem was the model.</p><h2>The Limits of Connectors</h2><p>Modern automation platforms provide access to hundreds of integrations:</p><ul><li>Composio</li><li>Symfony Mate</li><li>Kestra</li><li>n8n</li></ul><p>Each exposes capabilities:</p><ul><li>send email</li><li>fetch data</li><li>trigger workflows</li><li>call APIs</li></ul><p>However, these systems share a common limitation:</p><blockquote><p>They define <strong>how to connect</strong>, not <strong>how to compute</strong>.</p></blockquote><p>They operate as:</p><ul><li>pipelines</li><li>graphs</li><li>sequences</li></ul><p>But not as a formal system.</p><h2>Back to First Principles</h2><p>To redefine automation, we revisit two foundational models:</p><h3>Church - The Language</h3><p>Lambda calculus defines computation as:</p><ul><li>function abstraction</li><li>function application</li></ul><p>Example:</p><pre><code>λx.x + 1
(λx.x + 1)(5) = 6
</code></pre><p>Key properties:</p><ul><li>functions are first-class</li><li>no mutable state</li><li>computation = evaluation</li></ul><h3>Turing - The Execution</h3><p>The Turing machine defines:</p><ul><li>how computation is executed</li><li>how state evolves</li><li>how instructions are processed</li></ul><h3>Equivalence</h3><p>The Church–Turing thesis states:</p><blockquote><p>Any computation expressed as a Turing machine can be expressed in lambda calculus.</p></blockquote><h2>A New Model for Automation</h2><p>Applying this equivalence:</p><p>| Concept    | Role                |
| ---------- | ------------------- |
| Lambda     | Language (intent)   |
| Flow       | Execution (runtime) |
| Connectors | External primitives |</p><p>This leads to a new architecture:</p><pre><code>Intent → Lambda → Execution → Connector
</code></pre><h2>Connect Flow</h2><p>A new system, <strong>connect-flow</strong>, implements this model.</p><p>It introduces three core domains:</p><h3>1. LambdaCapability</h3><p>Represents:</p><ul><li>a computation</li><li>a composable expression</li><li>a formal structure</li></ul><p>Example:</p><pre><code>λfetchemails.λuserId.fetchemails(userId)
</code></pre><h3>2. Execution (Flow)</h3><p>Execution is delegated to:</p><ul><li>an orchestration engine</li><li>supporting async and parallel computation</li></ul><p>Flow acts as the <strong>Turing machine</strong> of the system.</p><h3>3. LanguageCapability</h3><p>A higher-level abstraction:</p><ul><li>transforms natural language into lambda expressions</li><li>uses a local LLM (Ollama + Mistral)</li><li>preserves privacy (RGPD-compliant)</li></ul><h2>From Tools to Primitives</h2><p>In this model:</p><ul><li>Composio</li><li>Symfony Mate</li><li>n8n</li><li>Kestra</li></ul><p>are no longer central systems.</p><p>They become:</p><blockquote><p><strong>execution backends</strong></p></blockquote><p>Each tool becomes a primitive callable within lambda.</p><h2>Practical Example</h2><h3>Lambda Execution</h3><pre><code class="language-bash">bin/console connect-flow:lambda:run \
&quot;λfetchemails.λuserId.fetchemails(userId)&quot; \
--args &quot;[5]&quot;
</code></pre><p>This defines:</p><ul><li>a function taking <code>fetchemails</code></li><li>then <code>userId</code></li><li>applying <code>fetchemails(userId)</code></li></ul><h3>Natural Language → Lambda</h3><pre><code class="language-bash">bin/console -vvv connect-flow:language:to-lambda \
&quot;fetch emails you have the tool 'fetchemails'&quot;
</code></pre><p>Produces:</p><pre><code>λfetchemails.fetchemails()
</code></pre><h2>Why This Matters</h2><p>Traditional automation:</p><pre><code>Workflow → Tools → Execution
</code></pre><p>This model:</p><pre><code>Intent → Lambda → Flow → Connector
</code></pre><h3>Key Differences</h3><p>| Traditional        | Lambda-based        |
| ------------------ | ------------------- |
| Static workflows   | Dynamic composition |
| Tool-driven        | Language-driven     |
| Provider-dependent | Provider-agnostic   |
| Hard to scale      | Composable          |</p><h2>Extending the Language</h2><p>Future iterations will introduce:</p><ul><li>data mappers</li><li>conditional logic</li><li>loops</li><li>HTTP primitives</li><li>process execution</li></ul><p>Example:</p><pre><code>compose(
  fetch_emails,
  filter_important,
  map(summary),
  send_email
)
</code></pre><h2>Relationship with Functional Programming</h2><p>This approach builds upon:</p><ul><li>lambda calculus</li><li>combinatory logic</li><li>functional composition</li></ul><p>As previously explored in:</p><p>→ Lambda interpreter in PHP
→ Y combinator implementations
→ Flow execution model</p><h2>Toward a Universal Execution Layer</h2><p>This architecture suggests a new category of systems:</p><blockquote><p><strong>Capability Composition Engines</strong></p></blockquote><p>Where:</p><ul><li>connectors are interchangeable</li><li>execution is abstracted</li><li>intent is formalized</li></ul><h2>Projet sources</h2><p>You can find sources of the project here : <a href="https://github.com/matyo91/connect-flow">https://github.com/matyo91/connect-flow</a></p><h2>Conclusion</h2><p>Automation has evolved from scripts to workflows.</p><p>The next step is clear:</p><blockquote><p>From workflows to language.</p></blockquote><p>By combining:</p><ul><li>Lambda (Church)</li><li>Flow (Turing)</li><li>Connectors (primitives)</li></ul><p>we obtain a system that is:</p><ul><li>composable</li><li>extensible</li><li>formally grounded</li></ul><h2>Final Thought</h2><blockquote><p>Automation is not a sequence of steps.
It is a computation.</p></blockquote><p>And computation deserves a language.</p><h2>Music credit</h2><p>The music that help me deeply write the article, in remembering of times past at <a href="https://www.bigyouth.fr">https://www.bigyouth.fr</a> : ODESZA - The Last Goodbye (feat. Bettye LaVette) - Official Visualizer</p><div class="ratio ratio-16x9"><iframe width="560" height="315" src="https://www.youtube.com/embed/iLKoiq6Su-8?si=LGIv2sMAScO8S4-7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div><h2>Resources</h2><ul><li><a href="https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents">https://blog.darkwood.com/article/automating-gmail-and-google-calendar-with-php-agents</a></li><li><a href="https://github.com/matyo91/composio-mcp">https://github.com/matyo91/composio-mcp</a></li><li><a href="https://composio.dev/">https://composio.dev/</a></li><li><a href="https://symfony.com/doc/current/ai/components/mate.html">https://symfony.com/doc/current/ai/components/mate.html</a></li><li><a href="https://kestra.io/plugins">https://kestra.io/plugins</a></li><li><a href="https://n8n.io/integrations/">https://n8n.io/integrations/</a></li><li><a href="https://navi.darkwood.com/">https://navi.darkwood.com/</a></li><li><a href="https://flow.darkwood.com/">https://flow.darkwood.com/</a></li></ul>
]]></content:encoded><link>https://blog.darkwood.com/article/unleach-connectors-from-tools-to-language</link><guid>https://blog.darkwood.com/article/unleach-connectors-from-tools-to-language</guid><enclosure url="http://darkwood.com/media/articles/69dd35a0be2a0899189460.jpg" /></item></channel></rss>