<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>AWSD</title>
      <link>https://awsd.fr</link>
      <description>AWSD is an independent company that builds and maintains its own software products.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://awsd.fr/en/index.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Sun, 07 Jun 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Conductor, not Coder</title>
          <pubDate>Sun, 07 Jun 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://awsd.fr/en/blog/conductor-not-coder/</link>
          <guid>https://awsd.fr/en/blog/conductor-not-coder/</guid>
          <description xml:base="https://awsd.fr/en/blog/conductor-not-coder/">&lt;p&gt;I&#39;ve never produced as much as I have since I started using AI. And yet, some days, after six commits and seven hours of work, I feel like I&#39;ve done nothing.&lt;/p&gt;
&lt;p&gt;For two months, I&#39;ve been building Yog-Sothoth alone — an analytics and observability tool for the Meteora DeFi protocol on Solana. Architecture, Rust backend, Next.js frontend, database, CI/CD, Docker, UX, content, documentation — that&#39;s me on all of it. A project of this complexity normally requires a team: a backend developer, a frontend developer, a DevOps engineer, a product manager, occasionally a designer or a data analyst. The cost can climb to €10,000 a month.&lt;/p&gt;
&lt;p&gt;And yet I&#39;m doing it alone. Does AI replace a team? After two months of intensive development, my answer is no. But it fundamentally changes the size of the team you need, and the role of each person in it.&lt;/p&gt;
&lt;h2 id=&quot;how-it-actually-goes&quot;&gt;How it actually goes&lt;/h2&gt;
&lt;p&gt;At the start of the project, Claude proposes a three-piece architecture: a Rust daemon for the indexer, Next.js for the frontend, Node.js for the API. It&#39;s coherent, I approve it, I move on.&lt;/p&gt;
&lt;p&gt;Then comes the day I start the API. I write code, and I realize I&#39;m about to rewrite in Node everything that already exists in &lt;code&gt;yog-core&lt;/code&gt;, my shared Rust crate: schemas, SQL queries, repositories, contracts. It&#39;s all there, cleanly separated between the domain and the persistence layer in a standalone &lt;code&gt;yog-persistence&lt;/code&gt; crate. And I&#39;m about to maintain two implementations of the same domain.&lt;/p&gt;
&lt;p&gt;I stop. I reopen the discussion with Claude. Its first answer: building the API in Rust will take much more work. That&#39;s wrong — it doesn&#39;t see that the domain factoring in &lt;code&gt;yog-core&lt;/code&gt; makes the operation trivial. I decide: it will be a &lt;code&gt;yog-api&lt;/code&gt; crate in Rust. Two days later, the API is in place.&lt;/p&gt;
&lt;p&gt;A week later, same story. The API works but it&#39;s hand-rolled. I restart the conversation, I identify the problem, Claude proposes, I choose: switch to axum. The implementation takes a day. Acceptable, because I&#39;d spent time up front cutting the project along DDD and SRP lines, and any one piece can be swapped without touching the rest.&lt;/p&gt;
&lt;h2 id=&quot;what-ai-does-better-than-i-do&quot;&gt;What AI does better than I do&lt;/h2&gt;
&lt;p&gt;I barely write any code anymore. But no line is added without my approval. Claude writes and proposes; I approve, reject, redirect.&lt;/p&gt;
&lt;p&gt;At pure coding, AI is better than I am. It produces higher-quality code, faster, without syntax errors. Repetitive tasks become a formality: Zod schemas, DTOs, unit tests. It codes, I verify.&lt;/p&gt;
&lt;p&gt;Shipping a feature used to take time: reading documentation, searching StackOverflow or GitHub, then trial and error. The cycle is different now: I lay out the problem and the context, I have a technical discussion with Claude, we explore several paths and weigh complexity against relevance, the code gets generated once the context is solid, I verify, I integrate.&lt;/p&gt;
&lt;p&gt;It&#39;s much less sexy than the vibe-coding fantasy. It&#39;s also much more effective.&lt;/p&gt;
&lt;h2 id=&quot;then-what-am-i-for&quot;&gt;Then what am I for?&lt;/h2&gt;
&lt;p&gt;If Claude writes the code, what am I for?&lt;/p&gt;
&lt;p&gt;Whatever the exact nature of what AI is doing, it doesn&#39;t carry the consequences of its proposals. It doesn&#39;t know which problem is important and which can wait. It doesn&#39;t know what actually adds value to the product. It proposes, I live with it.&lt;/p&gt;
&lt;p&gt;A concrete example. At the start, Yog-Sothoth was pool-centric: the project was built around pools, like most DeFi observability tools. That&#39;s what the words &quot;DeFi&quot; and &quot;observability&quot; naturally evoke, and it&#39;s exactly what an AI proposes — a weighting of probabilities over related vocabulary.&lt;/p&gt;
&lt;p&gt;An AI would never have made the decision to switch to protocol-centric. And yet that&#39;s the project&#39;s best decision, the one that gives it its whole point. Because this isn&#39;t a technical problem: it&#39;s a problem of market understanding and product positioning.&lt;/p&gt;
&lt;p&gt;To the AI, option A and option B are two probability distributions. To me, they&#39;re choices I&#39;m committed to — I&#39;m the one who&#39;ll pay the cost of the wrong one. I&#39;m the only one guaranteeing the project&#39;s long-term coherence. I&#39;m the only one with the full picture: product, architecture, constraints, future evolutions.&lt;/p&gt;
&lt;p&gt;And before anyone tells me &quot;you&#39;re not giving it enough context&quot;: Yog-Sothoth is a complex project split into multiple subsystems. The context isn&#39;t complex in itself — what&#39;s complex is the different contexts and their interactions. No AI can hold that load yet.&lt;/p&gt;
&lt;h2 id=&quot;is-it-still-my-product&quot;&gt;Is it still my product?&lt;/h2&gt;
&lt;p&gt;If all I do is direct, without producing anything myself, is Yog-Sothoth my product, or an assemblage of fragments written by others and recycled by the AI?&lt;/p&gt;
&lt;p&gt;Flip the question: a developer who copies a snippet from StackOverflow and pastes it into their project — do they still own that project? Yes. Because the value of a project has never been in the syntax of the code. It&#39;s in the understanding of the domain, in the ability to translate a business need into a program.&lt;/p&gt;
&lt;p&gt;The value of Yog-Sothoth isn&#39;t in the Rust syntax, the React components, or the SQL queries. It&#39;s in the choice of which data to observe, which metrics to compute, which architecture to set up, which tradeoffs to accept. Those are my choices, my responsibilities.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The job is changing. I code less, I produce more, I&#39;m cognitively tired. The satisfaction metric is no longer the number of lines shipped but the number of decisions made correctly. I&#39;m no longer a coder — I&#39;m a conductor, and it&#39;s far more demanding.&lt;/p&gt;
&lt;p&gt;I don&#39;t know what the developer job will look like in five or ten years. What I am convinced of, though, is this: AI doesn&#39;t replace responsibility. Someone still has to set the direction, arbitrate the choices, understand why the product exists, and own the consequences.&lt;/p&gt;
&lt;p&gt;AI hasn&#39;t turned me into a team of ten. It&#39;s let me concentrate my time on the decisions that matter, by delegating execution.&lt;/p&gt;
&lt;p&gt;For now, the one who decides is still the developer.&lt;/p&gt;
</description>
      </item>
      <item>
          <title>Yog-Sothoth: How a Simple Question Changed the Nature of the Product</title>
          <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://awsd.fr/en/blog/yog-sothoth-pool-centric-to-protocol-centric/</link>
          <guid>https://awsd.fr/en/blog/yog-sothoth-pool-centric-to-protocol-centric/</guid>
          <description xml:base="https://awsd.fr/en/blog/yog-sothoth-pool-centric-to-protocol-centric/">&lt;h2 id=&quot;the-starting-point&quot;&gt;The starting point&lt;/h2&gt;
&lt;p&gt;Yog-Sothoth is a real-time liquidity analysis engine for Meteora pools, a decentralized exchange protocol on Solana. The tool ingests the on-chain transaction stream, reconstructs pool state, computes financial metrics, and will eventually expose alerts and visualizations through a web dashboard. It&#39;s not a block explorer like Solscan: it&#39;s an analysis and signal tool, somewhere between Dune Analytics and Nansen, focused on Meteora liquidity.&lt;/p&gt;
&lt;p&gt;By the time I asked the question, I had two weeks of code behind me: the ingestion pipeline was working, DAMM v2 swap decoding was in place, PostgreSQL persistence too. What I had never done, however, was seriously check whether other tools already occupied this space.&lt;/p&gt;
&lt;h2 id=&quot;the-review&quot;&gt;The review&lt;/h2&gt;
&lt;p&gt;I started with what I should have done at the outset: typing &quot;Meteora analytics&quot;, &quot;Meteora LP tracker&quot;, &quot;Solana DEX flow analyzer&quot; and reading what came back. Within an hour, I had a reasonable map of the landscape.&lt;/p&gt;
&lt;p&gt;The first group is dense. UltraLP, TrackLP, MetLab, Tokleo, MetEngine, Cleopetra, Liquid Nova, Starseed. All built around the same proposition: &lt;em&gt;my positions, my P&amp;amp;L, my copy trading&lt;/em&gt;. The user shows up with a wallet, the tool tracks what that wallet does in pools. The pool is the unit of subscription, the position is the unit of analysis.&lt;/p&gt;
&lt;p&gt;The second group is more disparate. Bitquery offers Solana flows specific to DEXes, with explicit Meteora support and several delivery channels (WebSocket, Kafka, gRPC). It&#39;s powerful, but their product remains a structured data service: you subscribe to pairs, wallets, aggregated trades. The user is still the one defining what to observe. Shyft, on the other hand, sells Yellowstone gRPC streaming with DAMM v2 examples in Rust — technically very close to what I&#39;m building, but positioned as an infrastructure provider. They sell the pipe, not what flows through it. Alongside these two, Blockworks Research exposes aggregated dashboards on Meteora (fees by pool, volumes), but on consolidated historical data for research use, not on the live flow.&lt;/p&gt;
&lt;p&gt;What I&#39;m looking for in this list is a tool that observes Meteora as a whole. One that doesn&#39;t ask the user to designate which pools to watch. One that doesn&#39;t reason in terms of individual positions but in terms of protocol flow — which pools concentrate activity, where liquidity moves, what patterns emerge at the scale of the entire protocol.&lt;/p&gt;
&lt;p&gt;I don&#39;t find it. The LP tools are user-centric. The infrastructure providers are transport-centric. Nobody, in this list, positions themselves as an analytical observer of the protocol.&lt;/p&gt;
&lt;p&gt;That&#39;s enough to convince me there&#39;s a space. Not a huge market, maybe not a market at all — but an angle that isn&#39;t taken.&lt;/p&gt;
&lt;h2 id=&quot;the-pivot&quot;&gt;The pivot&lt;/h2&gt;
&lt;p&gt;Yog-Sothoth is not an LP tool. It&#39;s a flow observer that watches Meteora as a whole.&lt;/p&gt;
&lt;p&gt;This sentence sounds harmless. It changes everything.&lt;/p&gt;
&lt;p&gt;In the previous version, the base unit was the pool. The user declared which pools to follow, the system subscribed to each one, and all the analysis was built pool by pool. The pool was the entry key of the domain — the thing you subscribe to, index, store.&lt;/p&gt;
&lt;p&gt;In the new version, the base unit is the protocol. You subscribe to Meteora as a whole. Pools become data emitted by the flow: they&#39;re discovered as transactions arrive, recorded along the way, never declared in advance. Analysis happens at the protocol level, and individual pools are just one dimension among others for slicing that flow.&lt;/p&gt;
&lt;p&gt;The name takes on its meaning at that point. Yog-Sothoth, in Lovecraft&#39;s cosmogony, is the entity that sees everything simultaneously — past, present, future, all planes of existence at once. If the tool bears that name, it has to see everything happening on Meteora, not a selection. The pivot makes the project consistent with its own name.&lt;/p&gt;
&lt;p&gt;And it places it in a space that the competitive review showed to be sparsely occupied.&lt;/p&gt;
&lt;h2 id=&quot;what-this-changes-in-the-code&quot;&gt;What this changes in the code&lt;/h2&gt;
&lt;p&gt;I had two weeks of code behind me, written with the pool as the key everywhere. The conceptual translation into code wasn&#39;t a detail — it touched the spine of the domain. Four changes capture the essentials.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The pipeline&#39;s entry point.&lt;/strong&gt; &lt;code&gt;RpcListener&lt;/code&gt; used to store a set of watched pools and open one WebSocket subscription per pool. It now stores a &lt;code&gt;HashSet&amp;lt;Protocol&amp;gt;&lt;/code&gt; and opens one subscription per Meteora program. Concretely, the system shifts from N subscriptions (one per configured pool) to a handful of stable subscriptions (one per protocol variant). The system no longer asks the user what to watch: it watches Meteora.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The data flowing between ingestion and indexing.&lt;/strong&gt; The typed channel connecting &lt;code&gt;RpcListener&lt;/code&gt; to &lt;code&gt;IndexerService&lt;/code&gt; used to carry &lt;code&gt;(WatchedPool, Signature)&lt;/code&gt; — the pool was needed to know what to decode. It now carries &lt;code&gt;(Protocol, Signature)&lt;/code&gt;. It&#39;s a single line of code, and it&#39;s the boundary between the two versions of the project: before, the pool identifier preceded the transaction; now, the transaction reveals it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Parsers that discover pools instead of receiving them.&lt;/strong&gt; Previously, parsers were instantiated with a &lt;code&gt;pool_address&lt;/code&gt; argument — they were told in advance which pool they would decode. Now, they&#39;re instantiated without any address, and a helper &lt;code&gt;extract_pool_address&lt;/code&gt; reads position 1 in the accounts of the outer DAMM v2 instruction to derive it from the transaction itself. It&#39;s a complete reversal of the flow: the pool is no longer an input to the parser, it&#39;s an output.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A new domain model, &lt;code&gt;Pool&lt;/code&gt;, as a discovery registry.&lt;/strong&gt; Where there was &lt;code&gt;WatchedPool&lt;/code&gt; (declarative, created by the user), there&#39;s now &lt;code&gt;Pool&lt;/code&gt; (descriptive, upserted on every incoming event). It&#39;s the database trace of the fact that nothing is configured anymore: we record what passes through.&lt;/p&gt;
&lt;p&gt;The rest of the refactor follows mechanically from these four points. SQL migration redone from scratch without foreign keys to align the schema with the new domain. &lt;code&gt;reserve_a/b&lt;/code&gt; renamed to &lt;code&gt;reserve_in/out&lt;/code&gt; in &lt;code&gt;SwapEvent&lt;/code&gt; because the swap direction now matters more than the stable convention of the old model. Removal of &lt;code&gt;WatchedPool&lt;/code&gt;, &lt;code&gt;WatchedPoolService&lt;/code&gt;, &lt;code&gt;PgWatchedPoolRepository&lt;/code&gt; — all the machinery of the old world, now dead. The full diff is on the repo for anyone who wants to look.&lt;/p&gt;
&lt;h2 id=&quot;mainnet-test-that-same-evening&quot;&gt;Mainnet test, that same evening&lt;/h2&gt;
&lt;p&gt;The refactor took a day. By the end, what remained was finding out whether the pipeline held up under real data. WebSocket connection to &lt;code&gt;api.mainnet-beta.solana.com&lt;/code&gt;, subscription to the DAMM v2 program (&lt;code&gt;cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG&lt;/code&gt;), execution. Signatures arriving in real time.&lt;/p&gt;
&lt;p&gt;First observed behavior: no swaps decoded. The DAMM v2 instruction detector consistently returns &lt;code&gt;false&lt;/code&gt;. Diagnosis: &lt;code&gt;program_id_str&lt;/code&gt; was passing the string &lt;code&gt;&quot;meteora_damm_v2&quot;&lt;/code&gt; instead of the actual on-chain identifier — a leftover from the pool-centric model where the label was sufficient. One-line fix, the detector starts working again.&lt;/p&gt;
&lt;p&gt;Second behavior: the detector now recognizes DAMM v2 transactions, but extracting the associated transfers fails every time. &lt;code&gt;extract_swap_transfers&lt;/code&gt; was looking for the DAMM v2 instruction &lt;em&gt;inside&lt;/em&gt; the inner instructions, whereas in the new protocol-centric model it&#39;s an outer instruction that needs to be identified as such, with transfers then read from its inner group. Fixed by tracking the outer&#39;s index instead of doing blind matching. Extraction works.&lt;/p&gt;
&lt;p&gt;After these two fixes, DAMM v2 swaps are decoded live against mainnet. Amounts come out correct, mints come out correct, pools appear in the discovery table as transactions arrive — without any of them having been declared in advance. The pipeline holds end to end.&lt;/p&gt;
&lt;p&gt;Not everything is resolved. The public RPC is heavily throttled on &lt;code&gt;getTransaction&lt;/code&gt;: acceptable for validating the architecture, untenable for continuous use — switching to Yellowstone gRPC (Shyft, Helius, Triton) will be necessary before claiming production readiness. Liquidity events, for their part, don&#39;t persist correctly to the database yet; swap decoding works, liquidity event decoding still needs work. And the pool-centric machinery isn&#39;t entirely removed — there are still zombie structs to clean up.&lt;/p&gt;
&lt;p&gt;But the essential is validated. The pivot didn&#39;t stay a sketch on paper: it runs against mainnet on the same evening.&lt;/p&gt;
&lt;h2 id=&quot;what-this-day-shifted&quot;&gt;What this day shifted&lt;/h2&gt;
&lt;p&gt;The lesson I take from this day isn&#39;t &quot;check your competitors before coding&quot;. If I had done it at day zero, I would have had nothing concrete to compare against — no domain in mind, no sketched architecture, no intuition of what would be easy or hard to build. The review would have stayed abstract.&lt;/p&gt;
&lt;p&gt;What this day shifted is my understanding of &lt;em&gt;when&lt;/em&gt; the question becomes useful. Checking that what you&#39;re building has an angle isn&#39;t a business plan step to tick off before writing the first line. It&#39;s an architecture step: it gets asked at the moment when you have enough code to understand what you&#39;re doing, and not yet enough for pivoting to cost too much. Two weeks, for this project, was about the right moment. Three months would have been too late.&lt;/p&gt;
&lt;p&gt;The raw cost of the pivot is easy to count: a day of refactoring, two bugs caught during the run, some zombie code left to clean up. The cost of having continued without doing it is harder to quantify but more important. I would have shipped a product that already existed under eight other names, better funded and better distributed. Yog-Sothoth would have been a portfolio exercise, not an attempt at a product.&lt;/p&gt;
&lt;p&gt;The question I leave open, and which has no clean answer, is one of frequency. How often should you reopen this question on an ongoing project? Every month? At every phase change? When you sense something doesn&#39;t fit, without knowing what? I don&#39;t have the answer. But I now know that asking it on a Sunday evening, almost out of boredom, can change the nature of a project in twenty-four hours.&lt;/p&gt;
</description>
      </item>
    </channel>
</rss>

