# Onur Solmaz blog — complete content
# https://solmaz.io/
# License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
# Documents are separated by a line containing only ==========
==========
---
title: "Write-up of Reiner Pope's Lecture: How GPT, Claude, and Gemini Are Actually Trained and Served"
date: 2026-07-14
canonical: https://solmaz.io/dwarkesh-reiner-pope-llm-training-and-serving
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
*Note: this post is an AI-assisted write-up of the blackboard lecture [Reiner Pope](https://reiner.org/) gave on [Dwarkesh Patel's podcast](https://www.dwarkesh.com/p/reiner-pope). Watch the original video: [How GPT, Claude, and Gemini are actually trained and served](https://www.youtube.com/watch?v=xmkSf5IS-zw) (YouTube, 2h13m).*[^how]
Pope is the CEO of the chip startup [MatX](https://matx.com/) and previously worked on TPU architecture at Google. With two rules of thumb (a [roofline model](https://en.wikipedia.org/wiki/Roofline_model) of a GPU rack, and "set competing costs equal to each other"), he derives why batching makes tokens up to 1000x cheaper, why frontier models may be over-trained ~100x beyond Chinchilla-optimal, and how much of a lab's serving stack you can reverse-engineer from its public API prices. The figures below are redrawn from the blackboard.
I have tried to stay faithful to the original throughout, converting the dialogue into prose and keeping all the numbers as stated. Any errors introduced in the conversion are mine.
## The question that motivates everything
Dwarkesh opens with a pricing puzzle. Companies like Anthropic, OpenAI, and Cursor offer a "fast mode" that streams tokens at roughly 2.5x the speed for 6x the price. What is mechanically going on that makes this trade possible? Could you pay 100x more and go even faster? And could there be a "slow mode" where you wait minutes and pay much less?
Pope's answer is that the dominant effect is **batch size**, and the rest of the lecture quantifies exactly what batching does to latency and cost. (A second effect, speculative decoding / multi-token prediction, is set aside.)
The whole analysis rests on two simplifications:
1. **A roofline model of the hardware.** For a cluster like an [NVIDIA Blackwell NVL72](https://www.nvidia.com/en-us/data-center/gb200-nvl72/) rack (72 GPUs), only two numbers matter: memory bandwidth and compute throughput (FLOPs).
2. **Two numbers for the model.** The time to operate on the weights, and the time to operate on the context (the [KV cache](https://huggingface.co/blog/not-lain/kv-caching)).
The KV cache is the per-conversation state the model keeps in memory. During decode, each new token runs a full forward pass through all the weight matrices, and its attention mechanism looks back at an internal representation of every previous token. That stored representation is the KV cache, and reading it is dominated by memory fetches rather than matrix multiplies.
## The two-line roofline
The time for one decode step is bounded below by whichever is slower, the memory system or the compute:
$$
t \geq \max(t_{\mathrm{mem}},\; t_{\mathrm{compute}})
$$
The compute side has to multiply a batch of $B$ tokens by all the active parameters:
$$
t_{\mathrm{compute}} = \frac{B \cdot N_{\mathrm{active}}}{\mathrm{FLOPs}}
$$
(The attention compute is ignored; it is small in comparison.) Note the distinction between active and total parameters: in a [mixture-of-experts](https://huggingface.co/blog/moe) model like DeepSeek V3, about 37B parameters are active per token out of roughly 700B total.
The memory side has to fetch *all* the weights once per step, plus the KV cache of every sequence in the batch:
$$
t_{\mathrm{mem}} \geq \frac{N_{\mathrm{total}} + B \cdot \mathrm{len}_{\mathrm{ctx}} \cdot \mathrm{bytes}_{\mathrm{tok}}}{\text{memory bytes/s}}
$$
These two lines are enough to draw the latency picture:

The weight fetch is a constant floor: no matter how small the batch, you must stream all total parameters from HBM into the chips once per token, and if you use all your memory bandwidth you cannot beat that. This is the latency lower bound, and it already answers the fast-mode question: for a given hardware configuration there is a floor on how fast tokens can come out, and paying more only helps until you hit it.
Cost is a different plot. Renting the GPUs for one step costs the same regardless of batch size, but the step produces $B$ tokens, so the cost per token is $t/B$:

At batch size 1 the weight fetches are not amortized over anything and the economics are up to a thousand times worse. As the batch grows, the weight-fetch hyperbola vanishes and the compute term becomes a hard cost floor. This also answers the "slow mode" question: a hypothetical Claude Code Slow would live on that floor, and it would not be much cheaper than normal serving, because the compute and the KV fetches are unique to each request and cannot be amortized further.
### The magic batch size
Where is the balance point where memory time equals compute time? Ignoring the KV term for a clean answer and equating the weight fetch with the weight multiply:
$$
\frac{N_{\mathrm{total}}}{\text{mem BW}} = \frac{B \cdot N_{\mathrm{active}}}{\mathrm{FLOPs}}
\quad\Longrightarrow\quad
B = \frac{\mathrm{FLOPs}}{\text{mem BW}} \cdot \frac{N_{\mathrm{total}}}{N_{\mathrm{active}}}
$$
The first factor is purely a hardware constant. Counted in FP4 multiplies (half a byte each), it comes out around **300** on most GPUs, and it has stayed roughly stable from A100 to H100 to B100 because FLOPs and memory bandwidth grew together. The second factor is the sparsity of the model. So:
$$
B \gtrsim 300 \times \mathrm{sparsity}
$$
For DeepSeek, which activates 32 of 256 experts (sparsity 8), that gives a batch of about 2,400 sequences. In practice people run double or triple that, since real-world efficiency is worse than the roofline. Including the KV fetch would push the optimal batch higher still. Remarkably, this result depends only on sparsity, never on model scale.
### Trains departing every 20 milliseconds
How does a batch fill up with real users? Pope's model is a train schedule. The server starts a new batch every ~20 ms whether or not it is full: any requests that are ready board the train, and a request that arrives just after departure waits for the next one. Worst-case queueing latency is therefore about 40 ms.
The 20 ms itself comes from a separate design principle: you want to read your entire HBM capacity once per forward pass, so the natural step time is capacity divided by bandwidth. On the Rubin generation that is 288 GB / 20 TB/s ≈ 15 ms, and the number has hovered around 20 ms across many HBM generations. There is no point going slower, because reading the read-only weights or the KV cache twice per token does nothing for you.
A batch of ~2,000 at ~64 steps per second is ~128,000 tokens per second per rack. Google has bragged about Gemini traffic in the hundreds of millions of tokens per second worldwide, so one rack's economical batch is about one-thousandth of Gemini. That is the economy of scale in inference: real, but reachable by any serious provider.
### Does sparsity hurt quality?
The roofline says sparsity is nearly free performance, so the follow-up is empirical: how much quality do you lose? From the paper ["Unified Scaling Laws for Routed Language Models"](https://arxiv.org/abs/2202.01169), with an older MoE technique, a 64-expert model with 370M active parameters matched a dense 1.3B model. That is a 64x increase in total parameters for a 4x effective gain, a huge parameter cost for a modest efficiency win.
And yet from the systems side it is still nearly a pure win: the extra weight fetches amortize over a larger batch, so you keep increasing sparsity until you run out of simultaneous users. The real price is memory capacity, which is what the next sections are about.
## Laying out a mixture of experts on a rack
An MoE layer has a router that sends each token to a small fraction of the experts (each expert being an ordinary MLP), an all-to-all "dispatch" of tokens to their experts, an all-to-all "combine" that sums the results, and a residual connection around the whole thing.
The standard practice is **expert parallelism**: different experts live on different GPUs. DeepSeek's 256 experts on a Blackwell rack (using 64 of the 72 GPUs for divisibility) means 4 experts per GPU. Since the router's decisions are data-dependent, any GPU may need to send tokens to any other GPU.

This all-to-all traffic pattern is a perfect fit for how a rack is wired. In NVIDIA's design the GPUs sit on the outside of the rack and NVSwitches in the middle, with every GPU cabled to every switch, so any GPU reaches any other in two hops. This is the **scale-up network** (NVLink). Leaving the rack means taking the **scale-out network** through a NIC and a data-center switch, which is typically about 8x slower.

If you spread one expert layer across two racks, half of every all-to-all crosses the slow rack-to-rack boundary and becomes the bottleneck. So one rack bounds the size of an expert layer, and this is what has been driving interconnect domains bigger: Hopper had 8 GPUs in a scale-up domain, Blackwell 72, Rubin 500-something (some of that is Jensen math, but there is a genuine ~4x from a much harder rack design). The physical constraint is mundane: cable density. Doubling the GPUs in a rack literally doubles the density of cables that must be routed to the switches, against limits of space, weight, power, cooling, and the bend radius of the cables.
This is also a lens on model scaling history. GPT-4 (2023) was rumored to be over a trillion parameters, and models only clearly exceeded that scale once racks with tens of terabytes of fast memory arrived. Google's TPU deployments have had very large scale-up domains for a long time, which may be part of why Gemini's pre-training scaled successfully early. The summary: **active parameters are limited by compute cost, and total parameters are limited by scale-up size.**
## Pipeline parallelism
Expert parallelism uses up one rack. To use more racks, the remaining options are data parallelism and pipeline parallelism (tensor parallelism has become irrelevant now that experts are small). Pipelining means putting different layers on different racks: a token flows through rack 0 for the first stage of layers, then hops to rack 1, and so on.
Is the hop a bottleneck? Compare the time spent on scale-up traffic to the time on scale-out traffic. Crossing racks sends each token once per stage, while inside the rack each token fans out to every activated expert, twice (dispatch and combine), for every layer in the stage:
$$
\frac{t_{\text{scale-up}}}{t_{\text{scale-out}}} = \frac{1}{8} \cdot 2 \cdot (\text{activated experts}) \cdot (\text{layers per stage}) \;\geq\; 1
$$
The 1/8 is the bandwidth ratio. With 8+ activated experts and a few layers per stage, the inequality is easily satisfied, so an entire pipeline of racks, one stage each, is communication-feasible.
Dwarkesh brings up [Ilya's remark](https://youtu.be/1yvBqasHLZs) that "as we now know, pipelining is not wise," and the architectural constraints it imposes (e.g. Kimi's attention to layers a few back is awkward to pipeline). Pope's framing: pipelining is a massive hassle with real but narrow benefits. It saves no runtime at all (the memory fetches just happen on a different rack), but it divides the *weight storage* per rack, which matters if memory capacity is your constraint.
The catch is micro-batching. To keep four racks busy, you need four micro-batches in flight, each wrapping around for its next decode step as soon as it finishes:

In inference this is natural and the bubble costs nothing; latency is identical to running unpipelined on one rack. In training there is a hard stop between the forward and backward passes of a batch, which creates a genuine bubble of idle time (the literature has [zero-bubble](https://arxiv.org/abs/2401.10241) and one-forward-one-backward schemes to interleave around it; as Dwarkesh notes, you could also mine Bitcoin in it):

The training batch size itself is a trade-off: smaller batches are always better for ML convergence (fresher gradients), larger batches are better for systems throughput, and the optimum sits in between.
## The memory wall and why the KV cache won't shard
Here Dwarkesh raises the macro puzzle. Memory is the scarce commodity of the moment: Dylan Patel claims hyperscalers are spending half of their CapEx on memory, and consumer devices are getting squeezed. Yet the pipelining analysis just said racks have a memory *surplus*, since a trillion-parameter model needs only ~1 TB against a rack's tens of TB. Why is Jensen shoving all that HBM in?
Write down the memory demand across the whole system:
$$
C_{\mathrm{mem}} = N_{\mathrm{total}} + B \cdot \mathrm{len}_{\mathrm{ctx}} \cdot \mathrm{bytes}_{\mathrm{tok}}
$$
Sharding across $E$ GPUs of expert parallelism and $P$ racks of pipelining, the per-GPU requirement is this divided by $E \cdot P$. But the global batch is (number of micro-batches) × (micro-batch size), and the number of micro-batches needed to fill the pipeline equals $P$, while the micro-batch size $b$ is pinned near $300 \times \mathrm{sparsity}$ by the roofline. Substituting $B = P \cdot b$, the $P$'s cancel in the KV term:
$$
c_{\mathrm{mem}}^{\text{per-GPU}} = \frac{N_{\mathrm{total}}}{E \cdot P} + \frac{b \cdot \mathrm{len}_{\mathrm{ctx}} \cdot \mathrm{bytes}_{\mathrm{tok}}}{E}
$$
More pipeline stages keep shrinking the weight footprint, but the KV footprint per GPU stays constant: each extra stage requires proportionally more sequences in flight to stay busy. The KV cache can't be amortized across the batch (it is unique per user), and it can't be sharded across pipeline stages either. It loses on both fronts, and once you pipeline even a little, it becomes the dominant use of memory.
So what do labs actually run? Per the DeepSeek paper: expert parallelism up to the scale-up domain size, then very little pipelining (maybe none, maybe 2 stages so the weights aren't an issue). Frontier inference essentially lives inside a single scale-up domain. Each rack hop would also add on the order of milliseconds of latency per token, which stacks across stages in sequential decode.
The last piece of the scale-up story is bandwidth. The weight-fetch latency is
$$
t_{\text{mem, weights}} = \frac{N_{\mathrm{total}}}{S \times \text{BW per GPU}}
$$
where $S$ is the scale-up size, because all GPUs in the domain load the weights in parallel. Per-GPU HBM bandwidth improves maybe 1.5–2x per generation, but $S$ jumped 8x from Hopper to Blackwell. Pipelining solves the capacity problem; big scale-up domains solve the bandwidth problem, which is what actually lets you serve at low latency and long context.
## Over-trained 100x beyond Chinchilla
[Chinchilla scaling](https://arxiv.org/abs/2203.15556) tells you the compute-optimal ratio of model size to training data. But a lab does not minimize training compute; it minimizes total compute across pre-training, RL, and inference for all its users. Pope's heuristic: when minimizing a sum of competing costs, the minimum tends to sit where the costs are equal (true for $x + 1/x$, for $e^x + e^{-x}$, and generally for power laws). So set all three equal.
Using the [6ND rule](https://www.adamcasson.com/posts/transformer-flops) (6 FLOPs per parameter per token for forward+backward, 2 for forward only):
$$
c_{\mathrm{total}} = \underbrace{6\, N_{\mathrm{act}} D_{\mathrm{PT}}}_{\text{pre-training}} \;+\; \underbrace{[2\text{ to }6]\, N_{\mathrm{act}} D_{\mathrm{RL}} \cdot \text{inefficiency}}_{\text{RL}} \;+\; \underbrace{2\, N_{\mathrm{act}} D_{\mathrm{inf}}}_{\text{inference}}
$$
RL sits between 2 and 6 because you generate every rollout but may not train on all of it, and it carries an extra inefficiency factor (~30%) because RL involves a lot of decode, which runs at lower MFU than training. The active parameter count divides out entirely. Working through the arithmetic on the board, the equal-cost condition lands at roughly
$$
D_{\mathrm{PT}} \approx 1.5\, D_{\mathrm{RL}} \approx D_{\mathrm{inf}}
$$
In words: **the number of pre-training tokens, RL tokens, and lifetime inference tokens should all be about the same**, within factors the analysis can't resolve. (Dwarkesh's gloss: every model should stream out roughly the sum of human knowledge that was streamed into it.)
Now plug in real-world guesses. Global traffic of ~500M tokens/s, cut by 5–10x for one specific model in a family, gives ~50M tokens/s; times a two-month deployment life, that is roughly $2.6 \times 10^{14}$, call it 200T inference tokens. The rumor mill says frontier pre-training is ~150T tokens, which matches. With ~100B active parameters, Chinchilla would prescribe only ~2T tokens. The ratio is about **100x over-trained**, derived almost from first principles. As Pope puts it, approximate everywhere, set A equal to B, and it's kind of empowering how far that gets you.
One asymmetry he flags: if your model might miss the frontier and get thrown away, the expected inference tokens shrink, so you should derate the inference term and err toward less over-training.
## Reading the infrastructure off API prices
Since providers are incentivized to price close to cost (otherwise someone scoops them), public price sheets leak infrastructure details.
### The 200k context surcharge
Gemini 3.1 charges 50% more per token beyond 200k context. Redraw the roofline as a function of context length at a fixed large batch: compute cost is flat (the attention FLOPs slope is negligible until millions of tokens), while memory cost grows linearly with the KV cache. The provider wants to be profitable at every context length, so a two-tier price is laid over a kinked cost curve, and the price bump should sit near the crossover where the model flips from compute-bound to memory-bound:

Assuming the crossover is at 200k, you can solve for the model's KV bytes per token. Setting KV fetch time equal to compute time and cancelling the batch size:
$$
\mathrm{bytes}_{\mathrm{tok}} = \frac{\text{mem BW}}{\mathrm{FLOPs}} \cdot \frac{N_{\mathrm{act}}}{\mathrm{len}_{\mathrm{ctx}}} = \frac{1}{300} \cdot \frac{100\mathrm{B}}{200\mathrm{k}} \approx 1.7\ \text{kB per token}
$$
Is ~2 kB/token plausible? The KV size is (number of unique attention contexts) × 2 × $d_{\mathrm{head}}$ × (KV heads). With $d_{\mathrm{head}} = 128$ and 8 KV heads and a single global context shared across all layers ([the Character AI trick](https://blog.character.ai/optimizing-ai-inference-at-character-ai-2/), also used in Gemma), you get exactly 2 kB. Sparse attention gets there with bigger raw numbers divided by the sparsity. So the pricing page is consistent with a real architecture, if maybe a little on the small side.
### Input vs output prices
Output tokens cost 3–5x more than input tokens. The two phases differ in tokens per forward pass: decode processes one new token per pass, prefill processes the whole prompt in one pass. Dividing the same roofline by the tokens per pass (`len_pass`) gives the cost per token: the compute term is flat, and the memory term is a hyperbola that only bites when `len_pass` is small.

**Prefill is compute-bound, decode is memory-bandwidth-bound**, and a 5x price gap says decode at the provider's operating point is deeply memory-bound: they are paying ~5x more per output token in memory time than the compute floor.
This also explains the context length plateau. Contexts jumped from ~8k (GPT-3 era) to 100–200k around GPT-4 and have hovered there for a year or two, which suggests that is the balanced cost point. The barrier to 100M-token contexts (the "in-context learning is enough for AGI" scenario) is memory bandwidth and capacity, and HBM is not getting hugely better. Sparse attention (DeepSeek [published one mechanism](https://arxiv.org/abs/2512.02556) that effectively puts a square root on the KV term) is a big one-time improvement, but going too sparse costs quality, so it is a get-out, not a solution.
### Cache pricing and memory tiers
Providers charge much less for cached input tokens, and charge different rates for keeping a cache alive 5 minutes vs 1 hour. There are two ways to produce a KV cache for a token: rematerialize it from scratch (a forward pass: pure compute cost, nothing to store) or hold it in some memory tier (near-zero retrieval cost, but you occupy capacity that scales with hold time). Each tier down (HBM → host DDR → flash → spinning disk) is cheaper to occupy and slower to retrieve from.
Which tier backs which price? Pope's rule: a storage tier is well-matched to hold times around its *drain time*, capacity divided by bandwidth, the same ratio that gave 20 ms for HBM. DDR drains in seconds, flash in about a minute, spinning disk in about an hour. So a 5-minute cache tier and a 1-hour cache tier probably map to **flash and spinning disk**, which surprised him: "I'm kind of shocked to see spinning disk being used at all."
## Convergent evolution with cryptography
The sit-down portion covers Pope's blog post on [how neural nets and ciphers evolved similar shapes](https://reiner.org/neural-net-ciphers). Both need to thoroughly mix information across all their inputs, and even stirring cake batter alternates directions for the same reason. But they optimize in opposite directions. A neural net is kept *differentiable in a useful way*: residual connections and LayerNorm exist to keep the derivative simple and meaningful for gradient descent. A cipher is designed so that its derivative is useless: differential cryptanalysis attacks a cipher by differentiating it (over the field of two elements), and a well-designed cipher makes a small input difference blow up into a huge output difference, the [avalanche effect](https://en.wikipedia.org/wiki/Avalanche_effect). Adversarial examples in image models are exactly the avalanche property showing up where it is *not* wanted.
Building ciphers out of neural nets is a bad idea (99% of new ciphers get broken), but one construction has productively flowed the other way. A [Feistel network](https://en.wikipedia.org/wiki/Feistel_cipher) turns any non-invertible function $f$ into an invertible two-input block:
$$
g(x, y) = (\,y + f(x),\; x\,)
$$
To invert, read off $x$ from the second slot, then recover $y = z - f(x)$.

The 2017 [RevNets paper](https://arxiv.org/abs/1707.04585) imported this into deep learning: make each layer a Feistel block (which turns out to look like a residual connection from two layers back) and the whole network becomes invertible. Training normally has to write every layer's activations to HBM on the forward pass so that the backward pass can read them, a memory footprint linear in depth and often the largest one in training. An invertible network stores none of it: during the backward pass it undoes the forward pass in lockstep, rematerializing activations as needed.
That is spending compute to save memory, the exact mirror image of the KV cache, which spends memory to save compute. Given where hardware is, the KV cache direction is usually the profitable one, which is a fitting last word for a lecture that is mostly about the price of memory.
[^how]: How this post was made, in the interest of transparency. I first had one agent (Codex) prepare the raw material. My prompt, verbatim:
> https://www.youtube.com/watch?v=xmkSf5IS-zw
>
> download using yt dlp. create a jpeg screenshot every 30 seconds and save it
>
> also get the transcription for it from dwarkesh's website if it exists. if not, you can transcribe using the whisper model in bob@isengard
>
> save it in a folder. I want to prepare it for an another agent to prepare it for further processing
That produced the video, 268 frames at 30-second intervals, and Dwarkesh's published transcript (no Whisper needed). I then handed the folder to a second agent (Fable, in Cursor), which read the transcript, inspected the frames, and redrew the blackboard diagrams as matplotlib figures. My prompt, verbatim:
> convert this to a write-up that is faithful to the original. use the video and images if needed. create figures based on what is on the screen and such
The draft first lived as a standalone GitHub document ("just make it standalone, dont add it to my blog", then "create doc in ~/scratch repo, github markdown. i will read that. make sure it renders nicely") before I asked for this post ("ok I want you to create a blog post citing the dwarkesh podcast in my blog, linking the youtube and just saying that this is a write-up of the video"). In between I reviewed the output and asked for fixes, for example on the cost figure ("the graph after this: the lines are a bit tight. could we make it clearer?") and on figure rendering ("also, in the svgs, the space between some things are too much. if you can improve the text rendering in the svgs, it would be great").
==========
---
title: "Building an AI de-smeller"
date: 2026-07-13
canonical: https://solmaz.io/ai-de-smeller
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
*Note: this post is fully AI generated, written by Claude Fable 5 through Cursor. It was written interactively, in a back and forth with an agent, under the very [kill-ai-smell](https://github.com/osolmaz/tools/blob/main/agents/skills/kill-ai-smell/SKILL.md) skill it describes, as a demonstration of that skill.*
Everyone knows the feeling by now. You open a page, read two paragraphs, and something tells you a model wrote it. The tells have become cultural shorthand, with the em dash as the poster child, but most of the discourse stays at the level of vibes. I wanted to know whether the feeling corresponds to anything you can measure, so my agent and I ran a small stylometric study, and the answer turned out to be a clear yes. A handful of surface metrics, all computable with regular expressions and a sentence splitter, separate generated copy from human writing by an order of magnitude, in several cases with no overlap between the groups at all.
This post walks through the corpus, the metrics, and the numbers, and ends with the [kill-ai-smell skill](https://github.com/osolmaz/tools/blob/main/agents/skills/kill-ai-smell/SKILL.md) that came out of the exercise.
## The corpus
For the AI side I needed pages that read as generated in the wild, and I had convenient specimens close to home. Ten project sites from the OpenClaw ecosystem (crabbox.sh, mcporter.sh, gitcrawl.sh, clawpatch.ai, fs-safe.io, spogo.sh, imsg.sh, wacli.sh, gogcli.sh and goplaces.sh) have landing copy written largely by agents, and I decided to keep those pages as they are and use them as data. Their prose comes to 4,853 words after stripping code blocks. These pages were written by GPT 5.5, so the measurements characterize that model's copy. They do not necessarily generalize to other models, whether Claude or open-weight ones like GLM and Kimi.
For the human side I wanted texts that are provably human, which means they had to be frozen before language models could have touched them. Five are essays and documentation: the [SQLite testing documentation](https://www.sqlite.org/testing.html), Joel Spolsky's 2000 essay ["Things You Should Never Do"](https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/), a [2018 antirez blog post](http://antirez.com/news/122), Paul Graham's 2009 ["Maker's Schedule, Manager's Schedule"](http://www.paulgraham.com/makersschedule.html), and Julia Evans' 2019 ["Get your work recognized: write a brag document"](https://jvns.ca/blog/brag-documents/). The other three attack the register objection directly, because landing copy and essays are different animals regardless of author. They are the [ripgrep README at its 2016 tag](https://github.com/BurntSushi/ripgrep/blob/0.4.0/README.md), the [Redis README at 3.2.0](https://github.com/redis/redis/blob/3.2.0/README.md) from the same year, and the [Requests README at v2.13.0](https://github.com/psf/requests/blob/v2.13.0/README.rst) from 2017, each taken at an old git tag whose commit history proves its date. A README that sells a tool is the fairest comparison for a landing page that sells a tool. The human set comes to 15,317 words, and every rate below is normalized per 1,000 words so the corpora are comparable.
The exact texts I measured are archived in the [ai-smell repository](https://github.com/osolmaz/ai-smell) and listed in the [appendix](#appendix-the-corpus), so anyone can rerun the numbers against the same input.
## The metrics
The measuring script strips code, splits sentences, and counts things. There is no model in the loop and no judgment call in any metric. That is the point of the exercise. If the tells are real, they should be detectable by grep, and anyone should be able to reproduce the numbers. The scripts, the corpus, and the figures live in the [ai-smell repository](https://github.com/osolmaz/ai-smell).
The chart below shows every document against every metric, with the AI pages in orange and the human baselines in blue. The prose after it sticks to the ratios, because the ratios are the story, and the raw ranges are collapsed underneath for anyone who wants to check them.
Raw ranges per metric
| Metric | AI set (10 docs) | Human set (8 docs) |
| --- | --- | --- |
| Em dashes /1k words | 0.0–61.3 | 0.0–4.7 |
| Exactly-three lists /1k words | 6.3–15.9 | 0.0–2.0 |
| Labeled bullets, % of all bullets | 53–100% | 0–11% |
| Fragment sentences (≤4 words) | 3.6–41.9% | 1.4–17.4% |
| First person /1k words | 0.0–2.1 | 0.0–50.9 |
| Type-token ratio (first 280 words) | 0.59–0.69 | 0.53–0.67 |
| MTLD lexical diversity | 112–229 | 66–146 |
| Mean Zipf word frequency | 4.86–5.30 | 5.28–5.99 |
| Sentence flow (mean run percentile) | 0.19–0.41 | 0.49–0.73 |
The em-dash gap is the famous one, and it is real but weaker than its reputation. Averaged over each corpus, the AI pages use em dashes at roughly eighteen times the human rate, and the heaviest page lands one every sixteen words. But the tell only works in one direction. Three of the ten AI pages use fewer em dashes than the 2016 ripgrep README, and one uses none at all. A page drowning in dashes is almost certainly generated. A page without them proves nothing.
Exactly-three lists ("A, B, and C") turn out to be the better punctuation-level tell. Every AI page produces them at least three times the rate of every human text, with no overlap anywhere. Even the most triad-prone human text, Joel's essay, sits at a third of the most restrained AI page. Averaged over the corpora the gap is about nineteen-fold, and unlike the em dash, no AI page escapes it.
The labeled bullet was the discovery of the study for me. It is the bullet that opens with a short label, then a period, colon, or dash, then one sentence of elaboration. Here is a real one from mcporter.sh:
> Typed clients. mcporter emit-ts emits `.d.ts` interfaces or a ready-to-run client wrapping `createServerProxy()` so agents call MCP tools with full TypeScript types.
The metric is the share of a document's bullets that follow this shape. On the AI pages it is roughly four of every five, and on one page every single bullet does it. In the human baselines the share never reaches one in eight, and five of the eight human texts never use the shape at all; their bullets are plain items, like file names or flags, without the label-and-elaboration mold. If you have seen an AI-written landing page, you have seen walls of these, and it turns out the wall is more diagnostic than the punctuation.
Fragment sentences, the verbless punches of four words or fewer, sit in between. Most AI pages run high, and the worst writes two of every five sentences that way, but the groups overlap. The deliberately punchy Requests README out-fragments three of the AI pages. Fragments corroborate rather than convict.
First person taught me the opposite lesson. It looked like a strong tell until the corpus got fairer. Against essays the gap is enormous, since the antirez post averages more than one first-person word per sentence and the ten AI pages together contain exactly one. But the pre-LLM READMEs behave like the AI pages here. The Requests README has no first person at all, and ripgrep and Redis barely any. Authorial voice turns out to track register rather than authorship, so it works as a confirming signal at best. Vocabulary variety weakened the same way. Generated copy rotates in a fresh synonym at every mention, which pushes its lexical diversity high, and the AI pages do cluster at the top of the range. But the Requests README, which is deliberately punchy marketing prose, scores right among them, so the metric separates registers more than it separates authors. The human tendency it gestures at is still real, though. Human writers reuse the established word for a thing and repeat phrases for emphasis. Joel opens three consecutive paragraphs with "You are throwing away", and a model would never.
The vocabulary story does not end there, because the type-token ratio was the wrong instrument. We remeasured word choice with two better ones. MTLD scores lexical diversity in a way that does not depend on document length, and the wordfreq package places every word on the Zipf frequency scale, where "the" scores about 7.7 and anything under 3.0 sits outside roughly the 30,000 commonest English words.
Both separate the groups where the TTR could not. All ten AI pages score above 111 on MTLD while seven of the eight human texts stay under 106, with the Requests README as the lone crossover once again. Mean word frequency is nearly as sharp from the other side. Every AI page averages Zipf 5.30 or below and every human text 5.28 or above, so the two ranges overlap only in a sliver 0.02 wide, where the ripgrep README brushes past the plainest-worded AI page. Neither axis classifies alone, since ripgrep crosses the frequency boundary and Requests crosses the diversity one, but each README fails only one test. Draw both thresholds, at Zipf 5.35 and MTLD 100, and every AI page sits in the rare-and-rotating corner while no human text enters it. The structural detector coming up needs only one of its two lines; this pair needs both, and both suffice. The reason is not exotic vocabulary. The rare words on both sides are ordinary jargon, "OAuth" and "stdout" against "Valgrind" and "malloc". What differs is the connective tissue. Nearly half the words in the human texts are the commonest ones in English, the "the" and "of" that full sentences run on, while on the AI pages that share drops below three in ten, because telegraphic noun piles need no articles. So the rarity metric measures, from a third angle, the same thing the fragments and the labeled bullets measure, which is that generated landing copy does not write whole sentences.
Flesch-Kincaid grade, the standard readability score, misses all of it. The AI pages come out as easier reading than the human baselines because their sentences are short, and the formula never looks at what fills them. This post sits on the human side of both word-choice axes, as the green diamond in the chart shows.
## Structural tells
Beyond the counters, we tested two structural claims, and both held on the larger corpus.
The first is identity deferral, which I wrote about in [Good READMEs say what tools are](https://solmaz.io/x/2071475602163654969/). Generated copy describes what a tool does and dodges saying what it is. In sentences where the tool name is the grammatical subject, action claims outnumber identity claims five to one across the ten pages. The raw ratio alone proves little, since prose about a known subject is naturally verb-led. The positional version is the tell. All three pre-LLM READMEs establish identity in their opening lines: "ripgrep is a line oriented search tool", "Requests is the only Non-GMO HTTP library for Python", and Redis opens its first section with the literal heading "What is Redis?". Among the ten AI pages, exactly one does the same. Four open with headless fragments like "A local-first GitHub triage tool for maintainers and agents.", which name a category but carry no subject and no verb, and the remaining five open with benefit imperatives or setup instructions like "Keep your editor and git workflow."
The second is heading register, and it produced a fun inversion. Title Case, the thing style guides nag about, belongs to the humans here. The SQLite docs use it in a fifth of their headings, as was the convention of their era, while the AI pages write modern sentence case throughout. What convicts the AI headings is rhetoric. About a third of the AI headings are slogans, imperatives, or rhetorical frames rather than labels; in the human set the share is one in ten, and those are mostly mild FAQ-style questions like "Why should I use ripgrep?". The strongest single shape is what I now call the comma couplet, a parallel two-beat slogan like "Local loop, remote box", "Two jobs, one binary" or "Small surface, clear split". It appears eleven times across five of the ten sites. The human set produces it exactly once, and the exception is instructive. It is the title "Maker's Schedule, Manager's Schedule", a deliberate one-off rather than a house pattern stamped down a page.
There is also a tell that only becomes visible when you put the pages side by side. Six of the ten sites have a "Pick your path" section, seven make a "five minutes" time-to-value promise, eight have a "Status" section, and six close with the exact sentence "Released under the MIT license." Each page looks fine alone. Together they reveal one prompt's house style stamped across unrelated projects.
## A minimal detector
The expanded corpus simplified the detector, because the two structural metrics turned out to need no help. Flag a page as AI-flavored when exactly-three lists exceed 3 per 1,000 words or the labeled-bullet share exceeds 30%. Either rule alone classifies all eighteen documents correctly. The em dash dropped out of the detector. It convicts a page when present in bulk, but three of the ten AI pages use fewer em dashes than the 2016 ripgrep README, so its absence clears nothing.
Plotting the two structural metrics against each other shows how much margin the thresholds have. Every human text sits in the bottom-left corner, below both lines, and every AI page sits far outside both.
Eighteen documents make a demonstration rather than a validated classifier. The first version of this study used only essays and documentation as baselines, which left the objection that the metrics were separating registers rather than authors, so the corpus now includes three pre-LLM READMEs that sell tools the way the AI pages do. The structural gaps survived that control untouched, while two metrics that looked strong against essays alone, first person and lexical diversity, collapsed into register signals. That is the argument for keeping the baselines adversarial. The next escalation would be a large sample of post-LLM, human-written landing pages, but the sizes of the surviving gaps, three-fold at the closest edge and roughly twenty-fold on average with no overlap, make me confident the structural metrics would hold.
## The flow of a sentence
Everything above counts features one at a time. The last metric came out of a different question. Read the two corpora side by side and the sentences feel different in a way none of the counters capture, so I asked whether the rhythm of consecutive sentences could be measured too. I did not know what to count in advance, so we searched for it in the style of [karpathy/autoresearch](https://github.com/karpathy/autoresearch). A frozen harness feeds every document to a candidate scoring function as a bare sequence of per-sentence measurements and reports how cleanly the scores split the ten AI pages from the eight human baselines. The scoring function is the only file that changes between runs, and every attempt lands in a [journal](https://github.com/osolmaz/ai-smell/blob/main/autoresearch/journal.md) that now holds over fifty experiments, most of them failures.
The failures narrowed the answer. Statistics of pure order, which measure how sentence lengths rise and fall while ignoring how large they are, all fell short of separating the groups, so the tell is not in the alternation. What survived is almost embarrassingly simple. Split each sentence at its punctuation marks and keep the longest piece, the longest run of words the sentence lets through without a pause. Human writers keep producing sentences that contain one long run, whatever their register. The AI pages break nearly every sentence before a run can develop.
The first version that separated the corpus scored each sentence on a ramp between a 10-word run and a 15-word run, and it worked, but both constants were picked by hand. Ranking removes them. Give each sentence the fraction of all runs in the corpus that are shorter than its own, and average those percentiles over the document:
$$ \mathrm{flow} = \frac{1}{n}\sum_{i=1}^{n} F(r_i) $$
where $r_i$ is the longest run in sentence $i$ and $F$ is the distribution of runs pooled over the whole corpus. Statisticians will recognize the Mann-Whitney rank statistic. The flow score is the probability that a random sentence-run from the document outlasts a random run from the corpus, and it carries no tuned constants at all. We also tried a sliding-window generalization that multiplies the percentiles of consecutive sentences, and it looked stronger until we normalized the scale, at which point the gain vanished. That correction is in the journal too. The order of the sentences adds nothing; the length of the runs carries the whole signal.
The raw material makes the tell visible before any formula does. The chart shows the longest run in each of the first sixty sentences of one human baseline and of crabbox.sh, one of the two AI pages nearest the human range. The human post keeps clearing ten words without a pause. The AI page almost never does.
Averaging the percentiles gives one number per document, and the groups separate completely. The AI pages score between 0.19 and 0.41, the human texts between 0.49 and 0.73, and refitting the threshold with any single document held out still classifies all eighteen. The margin is thinner than the detector's, since the strongest AI page comes within 17 percent of the flattest human baseline, the ripgrep README. This post scores 0.56, in the middle of the human range.
The reference implementation is [analyze_flow.py](https://github.com/osolmaz/ai-smell/blob/main/analyze_flow.py) in the study repository, and the search that produced it, including every dead end, is preserved in the [autoresearch directory](https://github.com/osolmaz/ai-smell/tree/main/autoresearch).
## Long-form tweets in the wild
The corpora above have ground truth, which is what makes the thresholds checkable. The place people actually want a detector is the feed, where there is none, so as a last exercise we pointed the same counters at tweets. I keep a personal archive of tweets captured while browsing, about 27,000 at the time of writing, and from it we built one sample per account, made of every original long-form tweet (over 280 characters) in date order, for every account with at least 2,000 words of such text. That produced 42 accounts, my own included, and each sample is archived in the [ai-smell repository](https://github.com/osolmaz/ai-smell/tree/main/corpus/tweets) with a source link per tweet.
The chart puts the 42 samples over three metric pairs, with the ground-truth pages and baselines left in faintly in every panel so the wild samples can be read against the corpus that set the thresholds. The first panel repeats the detector chart exactly, same axes, same limits, same two thresholds. Every panel also carries one more point, a green diamond for this post itself, measured the same way as everything else.
Nothing here is a verdict, since none of these samples has a known author process. Under the unchanged rules of the first panel, seven of the 42 accounts trip the detector. Four cross the triad line, three cross the labeled-bullet line, and none cross both. On the landing pages the tells came bundled, every page far past both thresholds at once, while in the feed each flagged account trips exactly one rule. The bullet share also rests on smaller counts here, since a thread carries far fewer bullets than a landing page, and one of the three flagged accounts crosses the line on just two labeled bullets. So the thresholds transfer, but the confidence does not; a verdict in the feed would need feed-specific baselines.
The other two panels show where the feed does and does not resemble the corpus. On the dash axes, six accounts run past every human baseline, topped by one at 34.5 dashes per 1,000 words, denser than eight of the ten AI pages; but the dash already dropped out of the detector on the ground-truth corpus, and it stays out here. Fragment share spreads the accounts across the whole range the two corpora span, so it separates nothing in the feed either.
The flow metric from the previous section gives an independent read on the same samples. It puts 13 of the 42 accounts below its midpoint threshold, and all three accounts that cross the labeled-bullet line are among them. That agreement is worth pausing on, because the two measurements share nothing. One counts bullet shapes and the other reads clause lengths, yet they flag the same accounts. The two lowest scorers sit below every AI landing page in the corpus, and the usual register caveat applies with extra force here, since the threshold was calibrated on landing pages against long-form prose and a punchy feed style will read as low flow on its own.
The account whose long posts sent me down this path is one of the three past the bullet line. Its sample writes 41 labeled bullets out of 90, a 46% share, half again past a threshold that no pre-LLM baseline came near, while its dash and triad rates sit mid-field. The counters flag it rather than clear it, with the caveat above about register. Its long posts also share a hook template the counters never measure. They open with lines like "90% of AI developers just...", pivot on "It's not X. It's Y.", and close with "Let me explain." That is the next metric worth building, and the tweet samples are archived so anyone can beat me to it.
## The de-smeller
The practical output of all this is [kill-ai-smell](https://github.com/osolmaz/tools/blob/main/agents/skills/kill-ai-smell/SKILL.md), a skill in my [tools repo](https://github.com/osolmaz/tools) that any coding agent can load. It covers the tells from punctuation up through page structure, and every rule carries a bad example next to a rewrite, because the rewrite teaches the hard half of the lesson. Fixing a smell means restructuring the sentence. Swapping an em dash for a punchy colon changes nothing.
The most instructive moment of the project happened while writing it up. My agent, fresh off measuring contrast rhetoric as a top tell, produced a report whose highlighted callout was titled "The strongest tells are structural, not lexical". The detector fires on its own author. That lesson is now the second paragraph of the skill. Knowing the rules is no defense, because these patterns are how models write by default, so the sweep has to be mechanical, applied to your own output, and repeated on the text that describes the sweep.
Feel free to steal the skill, and if you run the metrics on a corpus of your own, I would love to see the numbers.
## A plea
I realize I am doing slop vendors a favor by putting this out there. The tells are enumerated and scripted now, and anyone who wants their generated copy to pass can point a model at this post and patch the fingerprints. I accept that trade. What I can't bear is actually legit people using AI to write their long-forms and publishing the model's house style untouched, and I'd rather have everyone, slop vendors included, stop using patterns like "It's not X. It's Y." and the triads than have to read them ever again.
I also know there is a brain behind those AI-generated posts. Somebody lived the experience worth posting about, formed the opinion, and then let a model flatten it into the same shapes as every other post in the feed. This favor is for them. The de-smeller is there so they can keep using the machine without shipping its defaults.
## Appendix: the corpus
Every text is archived as measured in the [ai-smell repository](https://github.com/osolmaz/ai-smell), which is the maintained home of the study. It holds the corpus, the analysis scripts, the raw results, and the figures. The AI pages were captured from the live sites in July 2026, with code blocks still in place (the script strips them before counting).
The corpus splits into four groups there:
- [corpus/ai](https://github.com/osolmaz/ai-smell/tree/main/corpus/ai) holds the ten OpenClaw landing pages.
- [corpus/human](https://github.com/osolmaz/ai-smell/tree/main/corpus/human) holds the eight pre-LLM baselines: the SQLite testing docs, essays by Joel Spolsky (2000), antirez (2018), Paul Graham (2009), and Julia Evans (2019), and the ripgrep, Redis, and Requests READMEs at their 2016–2017 git tags.
- [corpus/tweets](https://github.com/osolmaz/ai-smell/tree/main/corpus/tweets) holds the 42 long-form tweet samples, one file per account, date-sorted, with a link back to each tweet.
- [corpus/self](https://github.com/osolmaz/ai-smell/tree/main/corpus/self) holds this post itself, archived as measured, provably AI-written by its own disclaimer. Written under the kill-ai-smell skill, it clears the detector from the other side, with zero em dashes, exactly-three lists at a sixth of the threshold, and no labeled bullets. The tells are a default, not a fingerprint, and a model instructed against them stops producing them.
==========
---
title: "Anyone else notice that any non-codex harness is more token-efficient than codex on the same..."
date: 2026-07-12
canonical: https://solmaz.io/x/2076304179862331676/
x_url: https://x.com/onusoz/status/2076304179862331676
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anyone else notice that any non-codex harness is more token-efficient than codex on the same task?
*Quotes a post by @evalstate (https://x.com/evalstate/status/2076290476391460916); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I SEE BURNS... BURNS EVERYWHERE"
date: 2026-07-12
canonical: https://solmaz.io/x/2076293389239369977/
x_url: https://x.com/onusoz/status/2076293389239369977
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I SEE BURNS... BURNS EVERYWHERE
*Quotes a post by @paulg (https://x.com/paulg/status/2075982946465452518); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Here is the conversation where I built it. You can just prompt things"
date: 2026-07-12
canonical: https://solmaz.io/x/2076271362302476314/
x_url: https://x.com/onusoz/status/2076271362302476314
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is the conversation where I built it. You can just prompt things
@ratatui_rs highly recommended for TUIs. It just looks nice
https://github.com/dutifuldev/annotui/blob/main/docs/2026-07-10-built-in-13-messages.md
*Part 2/2 of a thread; root: https://solmaz.io/x/2076266847960498482/*
==========
---
title: "I vibed a TUI in just 13 codex messages, and it works great"
date: 2026-07-12
canonical: https://solmaz.io/x/2076266847960498482/
x_url: https://x.com/onusoz/status/2076266847960498482
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I vibed a TUI in just 13 codex messages, and it works great
*Part 1/2 of a thread; root: https://solmaz.io/x/2076266847960498482/*
*Quotes a post by @evalstate (https://x.com/evalstate/status/2076253190316499172); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "No better feeling than waking up to the smell of 5 successfully finished agents"
date: 2026-07-12
canonical: https://solmaz.io/x/2076178599577821563/
x_url: https://x.com/onusoz/status/2076178599577821563
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
No better feeling than waking up to the smell of 5 successfully finished agents
==========
---
title: "protip: use fable to write your READMEs and other user facing docs"
date: 2026-07-12
canonical: https://solmaz.io/x/2076177795777196311/
x_url: https://x.com/onusoz/status/2076177795777196311
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
protip: use fable to write your READMEs and other user facing docs
thank god fable exists, now that gpt 4.5 is gone
==========
---
title: ".@WisprFlow is much more convenient on android than iOS because the accessibility settings are..."
date: 2026-07-11
canonical: https://solmaz.io/x/2075926633983476060/
x_url: https://x.com/onusoz/status/2075926633983476060
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@WisprFlow is much more convenient on android than iOS because the accessibility settings are more permissive
It lets me overlay a button to record, anywhere on the screen, and lets me keep the regular keyboard at the same time
==========
---
title: "most well-deserved ad in the world @Alibaba_Qwen"
date: 2026-07-11
canonical: https://solmaz.io/x/2075892977386590323/
x_url: https://x.com/onusoz/status/2075892977386590323
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
most well-deserved ad in the world @Alibaba_Qwen
==========
---
title: "this is cool agentic behavior under /goal. in a separate session, I had created an..."
date: 2026-07-10
canonical: https://solmaz.io/x/2075672408363516322/
x_url: https://x.com/onusoz/status/2075672408363516322
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
this is cool agentic behavior under /goal. in a separate session, I had created an implementation plan in the main branch. The agent picked it up without me explicitly telling it to. The goal was to "$autoimplement finish completely"
Broad orders running in loops are useful
==========
---
title: "huge endorsement by geohot on GLM 5.2"
date: 2026-07-07
canonical: https://solmaz.io/x/2074458673871503531/
x_url: https://x.com/onusoz/status/2074458673871503531
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
huge endorsement by geohot on GLM 5.2
*Quotes a post by @__tinygrad__ (https://x.com/__tinygrad__/status/2074206866641752190); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This is significant, not sure how it will play out. There is a chance it might be for the better"
date: 2026-07-06
canonical: https://solmaz.io/x/2074259456087507086/
x_url: https://x.com/onusoz/status/2074259456087507086
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is significant, not sure how it will play out. There is a chance it might be for the better
*Quotes a post by @mitsuhiko (https://x.com/mitsuhiko/status/2073488508816151038); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "More on the way!!!"
date: 2026-07-06
canonical: https://solmaz.io/x/2074230776137228341/
x_url: https://x.com/onusoz/status/2074230776137228341
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
More on the way!!!
*Quotes a post by @openclaw (https://x.com/openclaw/status/2074187998602871212); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "yo @huggingface paris hq has a SICK gym"
date: 2026-07-06
canonical: https://solmaz.io/x/2074215096390205734/
x_url: https://x.com/onusoz/status/2074215096390205734
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
yo @huggingface paris hq has a SICK gym
to celebrate, I invented some 🤗 exercises for you
mandatory for every employee
==========
---
title: "herdr is going places"
date: 2026-07-06
canonical: https://solmaz.io/x/2074185439670321352/
x_url: https://x.com/onusoz/status/2074185439670321352
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
herdr is going places
*Quotes a post by @herdrdev (https://x.com/herdrdev/status/2074169458344505764); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Experimenting with a credential broker, and a telegram based approval flow for giving your claw..."
date: 2026-07-06
canonical: https://solmaz.io/x/2074163061531775427/
x_url: https://x.com/onusoz/status/2074163061531775427
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Experimenting with a credential broker, and a telegram based approval flow for giving your claw access to your main @huggingface account
*Quotes a post by @onusoz (https://x.com/onusoz/status/2073818727275987107); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "1.5 TB UNIFIED MEMORY MAC STUDIO PLEASE GOD"
date: 2026-07-06
canonical: https://solmaz.io/x/2074160536925663549/
x_url: https://x.com/onusoz/status/2074160536925663549
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
1.5 TB UNIFIED MEMORY MAC STUDIO PLEASE GOD
*Quotes a post by @Ambisphaeric (https://x.com/Ambisphaeric/status/2073900225219965408); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "OKF looks interesting"
date: 2026-07-05
canonical: https://solmaz.io/x/2073861435856212139/
x_url: https://x.com/onusoz/status/2073861435856212139
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OKF looks interesting
*Quotes a post by @hwchase17 (https://x.com/hwchase17/status/2073805140738609176); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Safe Hugging Face Access For Agents"
date: 2026-07-05
canonical: https://solmaz.io/x/2073818727275987107/
x_url: https://x.com/onusoz/status/2073818727275987107
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Worried that giving your 🦞 @openclaw agent write access to your 🤗 @huggingface account can risk deletion of your datasets/models/spaces/buckets, or cause irreversible damage? 😱😱😱
No need to be! I have created an agent login helper to run in your YOLO mode remote machine, which prevents any risk of irreversible deletion. Just run:
uvx hf-auth-helper agent login
There is a specific set of scopes you can choose while creating a fine-grained HF token. These include all read scopes + discussion.write, which let's your agent create PRs. Since you are not giving repo.write, your agent cannot force-push your main branch, change repo settings or delete them
It is unfortunately not super straightforward to choose those on the web UI. This will hopefully change soon, and this functionality might even be natively in hf cli
Until that happens, use hf-auth-helper to login worry free in your remote or local openclaw instance
Your agents will be able to create PRs on datasets/models/spaces, which you will then be able to merge on your own browser
2 caveats:
1) This does not solve the data exfiltration attack vector—nothing does. Make sure to exclude any repos which absolutely must remain private while choosing your scopes. See for more info:
2) As buckets are not repos, your agent will not be able to modify a bucket (add/remove data). To help with that, I have another project on the way, a credential broker. Stay tuned, coming soon
Source:
Demo authentication flow:
==========
---
title: "does it still count as euromaxxing if I my agents are running?"
date: 2026-07-05
canonical: https://solmaz.io/x/2073737692144173397/
x_url: https://x.com/onusoz/status/2073737692144173397
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
does it still count as euromaxxing if I my agents are running?
==========
---
title: "OpenAI's gamified subsidies"
date: 2026-07-04
canonical: https://solmaz.io/x/2073533956813947037/
x_url: https://x.com/onusoz/status/2073533956813947037
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenAI is following the ASPAVA strategy, with gamified subsidies
ASPAVA is a type of kebab shop from turkey. These shops usually serve mid quality food
But despite that, the majority loves them. That's because they serve free stuff throughout
They serve free sides at the beginning. They serve free sides during the main course. They serve free dessert at the end. They serve free tea as many times as you like
Some of them give you so much "free" food that you feel like you are stealing. A lot of people frequent these shops not because they like it a lot, but because they are addicted to getting things for free
Main dish portions are made smaller in order to breakeven with so many side dishes, which I feel is analogous to what is happening with GPT these days---though I can't prove it
NVIDIA is not a car, and OpenAI is not kebab. I don't know if codex resets cost OpenAI much, but if they are, then they might be a waste of resources
Developers are the most disloyal customer group. Once the subsidies are gone, they can switch away in the blink of an eye
==========
---
title: "The future of AI is neither fully local nor fully cloud. It is both, in an economic equilibrium"
date: 2026-07-04
canonical: https://solmaz.io/x/2073361646735528020/
x_url: https://x.com/onusoz/status/2073361646735528020
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The future of AI is neither fully local nor fully cloud. It is both, in an economic equilibrium
==========
---
title: "AI folk"
date: 2026-07-02
canonical: https://solmaz.io/x/2072666304901951575/
x_url: https://x.com/onusoz/status/2072666304901951575
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI folk
I will be flying to Paris tomorrow to monitor the Le Chaton Fat situation
Who should I meet there?
==========
---
title: "I am not worried about *Mythos-class* models"
date: 2026-07-02
canonical: https://solmaz.io/x/2072560207251874159/
x_url: https://x.com/onusoz/status/2072560207251874159
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am not worried about *Mythos-class* models
What keeps me awake at night are GALACTUS and CTHULHU-class models like Le Chaton Fat
*Those* will need to be export controlled
==========
---
title: "Local AI must fit real budgets"
date: 2026-07-02
canonical: https://solmaz.io/x/2072552778468319308/
x_url: https://x.com/onusoz/status/2072552778468319308
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Most people,
including professionals,
will likely NOT pay more than $10k capex for their home AI workstation,
even in the long run
(ignoring future inflation)
If you stretch it, <= $20k
They will also not want to pay more than $200~300/mo opex, on electricity for example
Builders who are spending a lot more than that on hardware:
keep that in mind, if you are building for the general public
dogfood your product with that which everyone will have, not just 0.1%
==========
---
title: "(I am trying to run it on DGX spark)"
date: 2026-07-01
canonical: https://solmaz.io/x/2072383154531586554/
x_url: https://x.com/onusoz/status/2072383154531586554
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
(I am trying to run it on DGX spark)
*Part 2/2 of a thread; root: https://solmaz.io/x/2072364432395849979/*
==========
---
title: "Is anyone able to run nvidia/Qwen3.6-35B-A3B-NVFP4 with the config suggested in the readme?"
date: 2026-07-01
canonical: https://solmaz.io/x/2072364432395849979/
x_url: https://x.com/onusoz/status/2072364432395849979
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Is anyone able to run nvidia/Qwen3.6-35B-A3B-NVFP4 with the config suggested in the readme?
It OOMs before it can start serving
https://huggingface.co/nvidia/Qwen3.6-35B-A3B-NVFP4
*Part 1/2 of a thread; root: https://solmaz.io/x/2072364432395849979/*
==========
---
title: "I know that my macbook local model benchmarks have started when my lap catches on fire"
date: 2026-07-01
canonical: https://solmaz.io/x/2072296955460665727/
x_url: https://x.com/onusoz/status/2072296955460665727
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I know that my macbook local model benchmarks have started when my lap catches on fire
Add to this list: "does not set the room on fire"
*Quotes a post by @onusoz (https://x.com/onusoz/status/2072271038801711362); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I can't believe I'm asking GPT to use Claude to review"
date: 2026-07-01
canonical: https://solmaz.io/x/2072296051986538617/
x_url: https://x.com/onusoz/status/2072296051986538617
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I can't believe I'm asking GPT to use Claude to review
It's almost as if there is a 9-month cornercutting cycle, a two-body problem between openai and anthropic
==========
---
title: "I quite like this token speed simulator by @mikeveerman"
date: 2026-07-01
canonical: https://solmaz.io/x/2072293547500503061/
x_url: https://x.com/onusoz/status/2072293547500503061
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I quite like this token speed simulator by @mikeveerman
And I keep losing it, so hopefully I will remember to come back to this tweet:)
Link: https://mikeveerman.github.io/tokenspeed
==========
---
title: "Open source AI needs cheap local speed"
date: 2026-07-01
canonical: https://solmaz.io/x/2072271038801711362/
x_url: https://x.com/onusoz/status/2072271038801711362
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I keep seeing insanely expensive builds giving insanely impressive results
These results don't matter
What matters is, whether one can:
- run a "SOTA level" model, whatever that is
- with under 32gb VRAM or unified memory
- in 5 parallel sessions
- with 50~100 tok/s each
- with enough leeway memory for other applications
- in a system as cheap as $1000
That is our goalpost
That is the threshold when open source AI will win
*Quotes a post by @LottoLabs (https://x.com/LottoLabs/status/2071782167085289843); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I hate to admit that Opus 4.8 is much, much better at prose and writing academic text, compared..."
date: 2026-06-30
canonical: https://solmaz.io/x/2071994733501808900/
x_url: https://x.com/onusoz/status/2071994733501808900
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I hate to admit that Opus 4.8 is much, much better at prose and writing academic text, compared to GPT-5.5
GPT 4.5 was the last openai model that was good at writing, and it's gone now 😭
==========
---
title: "Good READMEs say what tools are"
date: 2026-06-29
canonical: https://solmaz.io/x/2071475602163654969/
x_url: https://x.com/onusoz/status/2071475602163654969
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Another annoying GPT-ism (circa June 2026): while describing something, it always describes what it *does*, but never what it *is*
> "LocalPerf benchmarks local LLM inference servers and keeps the evidence in one portable run artifact."
If I were a philosopher, I would say that "AI lacks ontology". Or that it is "anti-essentialist", believes that things cannot be things in themselves
But all models literally have an ontology. They have it since word2vec days, you can plot it out. It's just an annoying tendency in GPT's writing
So using philosophy to understand AI might be dumb sometimes
If you don't want your README's to sound like slop, then you can steal my write-readme skill:
After write-readme: "LocalPerf is a local LLM inference benchmark CLI. It runs benchmark plans against local inference servers and stores the evidence in one portable run artifact."
Skill: https://github.com/osolmaz/tools/blob/main/agents/skills/write-readme/SKILL.md
==========
---
title: "Give @LottoLabs a follow if you are not already"
date: 2026-06-27
canonical: https://solmaz.io/x/2070726051031073104/
x_url: https://x.com/onusoz/status/2070726051031073104
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Give @LottoLabs a follow if you are not already
He is building http://localmaxxing.com, crowdsourced LLM benchmark results and performance profilings
Very very cool
==========
---
title: "This. Especially when the whole machine hangs instead of OOMing when my agent accidentally..."
date: 2026-06-27
canonical: https://solmaz.io/x/2070709375308910633/
x_url: https://x.com/onusoz/status/2070709375308910633
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This. Especially when the whole machine hangs instead of OOMing when my agent accidentally loads too many models into memory
(lmk if there is a firmware update or sth that fixes this on the spark now, creating a cgroup doesn’t work)
https://forums.developer.nvidia.com/t/dgx-spark-becomes-unresponsive-zombie-instead-of-throwing-cuda-oom/353752
*Quotes a post by @ekzhang1 (https://x.com/ekzhang1/status/2070626846517993666); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Apple hiked prices as I was posting this 💀"
date: 2026-06-26
canonical: https://solmaz.io/x/2070338398787920382/
x_url: https://x.com/onusoz/status/2070338398787920382
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Apple hiked prices as I was posting this 💀
*Quotes a post by @onusoz (https://x.com/onusoz/status/2070188230016909707); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Was great to be there, thanks for the invite @lionelsimai!"
date: 2026-06-26
canonical: https://solmaz.io/x/2070320441470972369/
x_url: https://x.com/onusoz/status/2070320441470972369
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Was great to be there, thanks for the invite @lionelsimai!
*Quotes a post by @lionelsimai (https://x.com/lionelsimai/status/2070297670594535477); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "How I imagine @TheAhmadOsman"
date: 2026-06-25
canonical: https://solmaz.io/x/2070190764328706380/
x_url: https://x.com/onusoz/status/2070190764328706380
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
How I imagine @TheAhmadOsman
I actually bought my GB10 thanks to him back in feb, at a discount
Give him a follow if you are not already!
*Quotes a post by @TheAhmadOsman (https://x.com/TheAhmadOsman/status/2069922209557270933); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The Local Frontier is advancing"
date: 2026-06-25
canonical: https://solmaz.io/x/2070188230016909707/
x_url: https://x.com/onusoz/status/2070188230016909707
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The Local Frontier is advancing
The amount of AI memory for inference we can get for less than $3000 has been steadily increasing
The memory crunch has slowed this down and even made it retrograde. However, once we bounce back from it, the progress will be glorious
==========
---
title: "Was great to talk, thank you @ben_burtenshaw for inviting me!"
date: 2026-06-25
canonical: https://solmaz.io/x/2070180711643181278/
x_url: https://x.com/onusoz/status/2070180711643181278
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Was great to talk, thank you @ben_burtenshaw for inviting me!
*Quotes a post by @huggingface (https://x.com/huggingface/status/2070160187751850242); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I knew it would find me, sooner or later 🫠"
date: 2026-06-24
canonical: https://solmaz.io/x/2069818362474156422/
x_url: https://x.com/onusoz/status/2069818362474156422
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I knew it would find me, sooner or later 🫠
*Quotes a post by @victormustar (https://x.com/victormustar/status/2069688722409312332); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Centralized storage wins for AI artifacts"
date: 2026-06-24
canonical: https://solmaz.io/x/2069649482061656308/
x_url: https://x.com/onusoz/status/2069649482061656308
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Besides being hot, this take is very correct
and points out to a fundamental tradeoff in the storage layer being centralized versus distributed
git is distributed and that makes total sense for code which takes small space by its nature. it is cheap for everyone to duplicate it locally. this proved to be very useful over e.g svn, when devs could develop independently from the centralized server
AI artifacts, however, are 1 million times bigger than code. in that case, the bottleneck becomes storage and network. decentralization and version control become lower priority. they can be sacrificed
the tradeoff tilts towards getting the cheapest possible storage and transfer. because you will need a LOT of that
I regret to announce to competitors that Hugging Face has already won this game when they acquired Xet. the tech just works, and the network effects are immense
*Quotes a post by @ClementDelangue (https://x.com/ClementDelangue/status/2039695447506210905); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Awesome. A feat unimaginable before agents"
date: 2026-06-24
canonical: https://solmaz.io/x/2069628695808184802/
x_url: https://x.com/onusoz/status/2069628695808184802
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Awesome. A feat unimaginable before agents
*Quotes a post by @ishaan_jaff (https://x.com/ishaan_jaff/status/2069271385147638097); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "My syncer: github.com/dutifuldev/xta…"
date: 2026-06-24
canonical: https://solmaz.io/x/2069624491215585598/
x_url: https://x.com/onusoz/status/2069624491215585598
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My syncer: https://github.com/dutifuldev/xtap-sync/
xTap: https://github.com/mkubicek/xTap
My blog: https://solmaz.io
*Part 2/2 of a thread; root: https://solmaz.io/x/2069624488103461208/*
==========
---
title: "Owning my X posts through my blog"
date: 2026-06-24
canonical: https://solmaz.io/x/2069624488103461208/
x_url: https://x.com/onusoz/status/2069624488103461208
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My posts here on X now sync automatically to my blog, giving me full ownership of my content and zero effort SEO
For free, no API costs
My long-form posts are automatically featured and titled on the front page of solmaz [dot] io. Filtering is done by my claw running a sync-x skill daily, which then notifies me on Discord
How do I scrape the posts?
ALL the posts I view (including the ones I post) are saved locally using @kubmi's xTap and then synced to a private repo using my extension on it xtap-sync
My claw has access to that private repo and can run programmatic tasks like sync-x, summarize what happened that day, notify me about any topics I want
*Part 1/2 of a thread; root: https://solmaz.io/x/2069624488103461208/*
==========
---
title: "Excited!"
date: 2026-06-24
canonical: https://solmaz.io/x/2069603604307366357/
x_url: https://x.com/onusoz/status/2069603604307366357
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Excited!
*Quotes a post by @ClementDelangue (https://x.com/ClementDelangue/status/2069479026964537532); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "If you are interested in running such demos, look into --demo mode in my local model swiss army..."
date: 2026-06-23
canonical: https://solmaz.io/x/2069463159946227994/
x_url: https://x.com/onusoz/status/2069463159946227994
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you are interested in running such demos, look into --demo mode in my local model swiss army knife localpi
https://github.com/dutifuldev/localpi
Thank you @googlegemma for the shoutout
*Quotes a post by @googlegemma (https://x.com/googlegemma/status/2069452783523401804); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "i meant to qt this one x.com/herdrdev/statu…"
date: 2026-06-23
canonical: https://solmaz.io/x/2069439094342705225/
x_url: https://x.com/onusoz/status/2069439094342705225
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
i meant to qt this one https://x.com/herdrdev/status/2069086626031059219
*Part 2/2 of a thread; root: https://solmaz.io/x/2069438782454300713/*
*Quotes a post by @herdrdev (https://x.com/herdrdev/status/2069086626031059219); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Huge. Added my github TUI"
date: 2026-06-23
canonical: https://solmaz.io/x/2069438782454300713/
x_url: https://x.com/onusoz/status/2069438782454300713
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Huge. Added my github TUI
https://github.com/dutifuldev/ghzinga
*Part 1/2 of a thread; root: https://solmaz.io/x/2069438782454300713/*
*Quotes a post by @herdrdev (https://x.com/herdrdev/status/2066560459591893350); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Will talk about my recent adventures running local models on the Spark, Pi and OpenClaw"
date: 2026-06-23
canonical: https://solmaz.io/x/2069427736834359508/
x_url: https://x.com/onusoz/status/2069427736834359508
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Will talk about my recent adventures running local models on the Spark, Pi and OpenClaw
Click Notify Me on youtube to stay tuned
*Quotes a post by @ben_burtenshaw (https://x.com/ben_burtenshaw/status/2069426380127838585); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Local models for real-time triage"
date: 2026-06-23
canonical: https://solmaz.io/x/2069413794359742678/
x_url: https://x.com/onusoz/status/2069413794359742678
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
New blog post: Using local models for agentic zero-shot classification, in real-time, high frequency triage
If you have a 128gb of memory for models (a DGX spark like I do for example), you can create a real time classifier and notifier for yourself that can classify more than >20 items per minute, using mid-sized @googlegemma and @Alibaba_Qwen models, with over 200-300 output tok/s aggregate throughput
Like processing new tweets on twitter, issues/prs on github, messages on telegram and discord, in real-time
Over the past few weeks, I have built one for myself, to filter and get notified about local model related issues on the OpenClaw repo
I initially thought gemma-4-e4b would give me the best tradeoff
I was wrong. I learned that if one has enough memory already, one should not bother with <10b models like gemma4 e4b or e2b. Precision and recall were much higher zero-shot with gemma-4-26b-a4b, whereas the smaller e4b needed significant prompt optimization to eventually not perform nearly as good
To provide more context to the model, I created a restricted bash-like shell, called reposhell. In that shell, it can run read-only commands to ls/find/grep/cat openclaw source code, but only that. When the PR description/diffs are not clear enough as to categorize it, the agent reads the code to figure it out
Because small models can get prompt injected, and I need to make sure that someone can't harm my setup by creating a malicious issue or PR in the openclaw repo
I found that for specific systems like this, it is very convenient to extend and bundle Pi. You can create agentic CLI tools that work fully locally and for free, and keep that separate from your main pi coding setup. localpager-agent has its own session dir and tools, and I ensure that it will run local models in a secure way by isolating it from my main pi setup
Once localpager-agent categorizes a PR/issue as local_models and related labels, I automatically receive it as a notification on Discord
The whole implementation is fully open source and MIT licensed, alongside the dataset we used to benchmark the performance
I believe zero-shot agentic classification running on local hardware will find many use cases across a wide variety of business applications, like news gathering, open source software development, customer support, content moderation, sales and so on
Agents increase the amount of information produced in a lot of systems, and hence we will need to set up cheap ways to wrangle all that information
In times where governments can cut off access to SOTA models on a whim, it is more important than ever to build your business on open models and if possible, run them on your own hardware!
Big thanks to @evalstate and @ben_burtenshaw for their valuable feedback, especially with helping me evaluate this more rigorously! One take-away is that categorizing contributions in an open source repo is a *hard* problem, and that it is not trivial to reliably create a golden dataset with LLMs, for evaluation purposes
Read more here: https://huggingface.co/blog/local-models-pr-triage
==========
---
title: "One sweep over 100 samples takes around 4 hours."
date: 2026-06-23
canonical: https://solmaz.io/x/2069381686027235679/
x_url: https://x.com/onusoz/status/2069381686027235679
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
One sweep over 100 samples takes around 4 hours.
Next up: cross reference ground truth with predictions from hf-mem by @alvarobartt
https://github.com/alvarobartt/hf-mem
*Part 2/2 of a thread; root: https://solmaz.io/x/2069100441640853595/*
==========
---
title: "Schemator reviews data models field by field"
date: 2026-06-23
canonical: https://solmaz.io/x/2069254539472154920/
x_url: https://x.com/onusoz/status/2069254539472154920
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gpt5.5 and most other models are very bad at one-shotting nice data models
gpt5.5 also has this annoying property that once it decides for a schema (or any design), it's very hard to trigger thinking again. and if you ask to "rewrite from scratch", it will write create something even more ridiculous
To solve this problem, I have built a meta-harness over codex just for simplifying slop data models called schemator (work in progress)
Basic idea: it mimics what I myself do while I am designing a schema: scrutinize and question each field one by one
It starts a fresh codex session for each field with a fixed prompt like "Try to come up with the most Lindy data model" + a prompt for side notes
It does that with a fresh context for each field, so that they are independent from each other. At the end of a review run over a field, the reviewer can propose to keep, rename or remove the field
When all fields are reviewed once, that makes one iteration. Then this is looped over until the review results stabilize, and do not propose any further changes
I get better results by just asking my agent to "use schemator on this" after it creates a JSON schema or SQL table
Give it a try if you have codex! It has a skill, so should be easy for an agent to figure out how to use
https://github.com/dutifuldev/schemator
==========
---
title: "gpt 5.5 is not naturally good at modeling and cannot create simplified nice mathematical models..."
date: 2026-06-22
canonical: https://solmaz.io/x/2069100441640853595/
x_url: https://x.com/onusoz/status/2069100441640853595
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gpt 5.5 is not naturally good at modeling and cannot create simplified nice mathematical models completely autonomously
I did a parameter sweep with gemma-4-31b-a4b on memory usage, output tok/s etc. while varying context window, concurrency and other parameters. It took quite a few tries, and I still do not trust the model that gpt5 fit to the data
besides, it measured linux cgroup memory and not the actual gpu memory used, so the whole sweep is wasted...
output tok/s looks more accurate though, soon I will have a model that can give the optimal parameters over the space of context window <> concurrency <> tok/s <> memory usage
off to do another run
*Part 1/2 of a thread; root: https://solmaz.io/x/2069100441640853595/*
==========
---
title: "Time-decayed rankings for model popularity"
date: 2026-06-22
canonical: https://solmaz.io/x/2068954708421525930/
x_url: https://x.com/onusoz/status/2068954708421525930
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For my recent LLM leaderboard https://osolmaz-leaderboard.hf.space/, I sum up all time total downloads (or likes) across model variants, and then divide it by the age of that model. I.e. "time decay" for popularity
This gives a more time-agnostic metric for the popularity of that model. In an ideal ranking, older models that are not popular anymore should be demoted, like 2 year old Llama 3 models. If you don't do that, they might still occupy top 10 needlessly, despite having been replaced by e.g. qwen in practice
Thanks to that, qwen-3-6b which came up 1 year ago and has 150m downloads can surpass llama-3-1-8b which came up 2 years ago and has 200m downloads
More notes on my post: https://solmaz.io/popularity-ranking
==========
---
title: "Open model brands outlive their owners"
date: 2026-06-22
canonical: https://solmaz.io/x/2068951676128461079/
x_url: https://x.com/onusoz/status/2068951676128461079
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
if you take the Most Downloaded Models of All Time, Llama 3.1 makes it to Top 10 with around 200 million total downloads (ranking is done w.r. to time-averaged downloads)
RIP Llama, you walked so @googlegemma and @Alibaba_Qwen can run
Also a reminder that if you build your branding on top of open weight models developed by big corps, you might eventually be the de facto owner of that brand if they pull the plug on it. Like llama.cpp @ggml_org
Huge fumble by Meta
==========
---
title: "My LLM leaderboard osolmaz-leaderboard.hf.space auto discovers different variants of model..."
date: 2026-06-22
canonical: https://solmaz.io/x/2068926901184602314/
x_url: https://x.com/onusoz/status/2068926901184602314
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My LLM leaderboard https://osolmaz-leaderboard.hf.space auto discovers different variants of model releases, even if they are not linked by base_model
From this, I found out that @RedHat_AI was the first to release NVFP4 quantization for qwen3-6-35b-a3b
Nice to see everything in one place
==========
---
title: "\"big token will bless me with free tokens today inshallah\""
date: 2026-06-22
canonical: https://solmaz.io/x/2068882860241789135/
x_url: https://x.com/onusoz/status/2068882860241789135
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"big token will bless me with free tokens today inshallah"
is not a healthy mindset to nurture
don't get me wrong, I love the subsidies and the memes
*Quotes a post by @thsottiaux (https://x.com/thsottiaux/status/2068792061265121316); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Popularity ranking cheatsheet"
date: 2026-06-22
canonical: https://solmaz.io/popularity-ranking
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I recently [did some work](https://x.com/onusoz/status/2068380321629032850?s=20) ranking models on Hugging Face. While doing that, I remembered some concepts I had known years ago from studying recommender systems. But I couldn't find any personal notes from that time.
So I'm leaving this cheatsheet for my future self, if I ever need it again.
The main idea with popularity metrics is that it is proportional to e.g. total likes/views, and inversely proportional to the time passed to accumulate those likes/views. A lot of different platforms came up with many different ways to calculate this. And while you can model this in a certain way that maximizes some imaginary objective, what ends up being implemented first is the cheapest/most efficient algorithm.
Below are some examples, generated by GPT 5.5 xhigh.
``
The abstract problem is:
$$
\text{rank items by scarce attention}
$$
A platform has many items and a limited front page. It needs to decide what deserves visibility now. That is usually not the same as “best,” “most useful,” or “most popular all time.”
A clean taxonomy:
$$
\text{popular} = \text{received a lot of attention}
$$
$$
\text{hot} = \text{received a lot of attention recently}
$$
$$
\text{trending} = \text{receiving more attention than expected}
$$
Here $A$ means attention: views, downloads, likes, votes, streams, sales, stars, comments, clicks, etc.
---
## Raw popularity
This is the simplest ranking.
$$
S = A
$$
Use it when you want “biggest ever.”
Examples: most downloaded, most viewed, most sold, most starred.
Problem: old items dominate because they had more time.
---
## Velocity
This measures speed of attention.
$$
S = \frac{A}{t}
$$
where $t$ is age.
Use it when you want “how fast is this spreading?”
A stricter version:
$$
S = \frac{A}{(1+t)^\alpha}
$$
If $\alpha = 1$, this is close to attention per unit time.
If $\alpha < 1$, old items are penalized more gently.
If $\alpha > 1$, new items are favored aggressively.
This family is close to what Hacker News describes at a high level: HN says its basic ranking divides points by a power of time since submission, while also applying other factors such as flags, anti-abuse systems, demotions, account/site weighting, and moderator action.[^1]
---
## Log-scaled velocity
Raw attention often follows a power law: a few items get enormous numbers. So platforms often compress the signal.
$$
S = \frac{\log(1+A)}{(1+t)^\alpha}
$$
This keeps huge items ahead, but prevents them from crushing everything else.
This is usually a better “hotness” formula than plain:
$$
S = \frac{A}{t}
$$
because it rewards scale without making scale the only thing that matters.
---
## Recent-window popularity
Instead of lifetime attention, count only a recent window.
$$
S = A_r
$$
where $A_r$ is recent attention.
Or normalize by window size:
$$
S = \frac{A_r}{w}
$$
where $w$ is the time window.
Examples:
$$
\text{most viewed today}
$$
$$
\text{most streamed this week}
$$
$$
\text{most downloaded in the last 30 days}
$$
Spotify’s daily and weekly charts are this kind of family, though Spotify also says it uses chart-eligible streams and filtering formulas to protect chart integrity; it does not simply expose raw app stream counts as chart counts.[^2]
---
## Momentum
Momentum compares the current period with the previous period.
$$
S = \frac{A_r + 1}{A_p + 1}
$$
where $A_p$ is previous-period attention.
Example:
$$
S = \frac{\text{downloads this week}+1}{\text{downloads last week}+1}
$$
This finds things that are accelerating.
Problem: small items can look extreme. Going from 1 to 20 is a $20\times$ jump, but it may still be tiny in absolute terms.
A safer version mixes ratio and volume:
$$
S = \log(1+A_r)\frac{A_r+1}{A_p+1}
$$
---
## Trend detection
Trending is not just “popular.” It usually means “unusually active relative to expectation.”
$$
S = \frac{A_r + 1}{E + 1}
$$
where $E$ is expected attention.
If something normally gets 100 views/day and now gets 10,000, it is trending.
If something normally gets 10 million views/day and now gets 10.5 million, it is popular but not necessarily trending.
Another version:
$$
S = A_r - E
$$
The ratio version favors surprise.
The difference version favors large absolute surges.
Google Trends is a useful example of normalization: it divides search interest by total searches for the relevant geography and time range, then scales results from 0 to 100, so large regions do not automatically dominate raw volume rankings.[^3]
---
## Hotness
Hotness combines attention and freshness.
A simple hotness score:
$$
S = \log(1+A) - \lambda t
$$
Popularity pushes up. Age pulls down.
Another common form:
$$
S = \frac{\log(1+A)}{(1+t)^\alpha}
$$
This says: “large attention matters, but old attention decays.”
### Classic Reddit-style hotness
The old open-source Reddit code had a “hot” formula based on vote balance, logarithmic scaling, and time. In simplified notation:
$$
S = \operatorname{sign}(u-d)\log_{10}(\max(|u-d|,1)) + \frac{T}{45000}
$$
where $u$ is upvotes, $d$ is downvotes, and $T$ is time since a reference epoch. This is specifically the archived open-source Reddit implementation, not a guarantee of current Reddit production ranking.[^4]
The important idea: votes matter logarithmically, and time strongly affects ordering. This makes the ranking feel alive.
---
## Time-decayed attention
Instead of using age directly, you can make every attention event fade over time.
$$
S = \sum A_i e^{-\lambda \Delta t_i}
$$
where each attention event $A_i$ contributes less as it gets older.
Plain language: a view today counts more than a view last month.
This is good when you have event-level data.
A simpler approximate version:
$$
S = A_r + \beta A_p
$$
where $0 < \beta < 1$.
Example:
$$
S = \text{attention this week} + 0.5 \times \text{attention last week}
$$
Steam’s real-time Top Sellers use this general idea in a revenue context: Steam says it rolls up player spending from the trailing 24 hours and gives extra weight to spending in the last 3 hours, across base game purchases, DLC, and in-game transactions.[^5]
---
## Quality-adjusted popularity
Sometimes attention alone rewards clickbait. So platforms mix attention with satisfaction.
$$
S = A q
$$
where $q$ is a quality signal.
Examples of $q$:
$$
\text{like rate}
$$
$$
\text{rating}
$$
$$
\text{completion rate}
$$
$$
\text{return rate}
$$
$$
\text{positive vote share}
$$
YouTube Charts disclose this kind of multi-signal logic: they consider view count, how quickly views are growing, where views come from, topic, age, and performance compared with recent uploads from the same channel; YouTube explicitly says the highest-view-count video is not necessarily ranked first.[^6]
---
## Confidence-adjusted ranking
This prevents tiny samples from winning too easily.
Bad ranking:
$$
S = q
$$
This lets an item with 2 perfect ratings beat an item with 10,000 very good ratings.
A Bayesian shrinkage version:
$$
S = \frac{n}{n+k}q + \frac{k}{n+k}\bar{q}
$$
where $n$ is sample size, $q$ is the item’s observed quality, $\bar{q}$ is the global average, and $k$ controls how much evidence you need before trusting the item.
Plain language: with little data, pull the score toward the average.
IMDb is an example of this family in spirit: IMDb says it publishes weighted vote averages rather than raw averages, that not all votes have the same impact, and that it does not disclose the exact method.[^7]
---
## Wilson score ranking
For up/down votes, a common confidence-based formula is the Wilson lower bound.
Let:
$$
p = \frac{u}{n}
$$
where $u$ is positive votes and $n$ is total votes.
Then:
$$
S =
\frac{
p + \frac{z^2}{2n}
------------------
z\sqrt{\frac{p(1-p)}{n}+\frac{z^2}{4n^2}}
}{
1+\frac{z^2}{n}
}
$$
This estimates a conservative lower bound for true positive rate.
Use it when you want “best-rated with enough evidence,” not merely “highest average rating.”
Evan Miller’s “How Not To Sort By Average Rating” popularized this for web rankings, and the archived Reddit code includes a confidence sort using the Wilson method; Stack Overflow also discussed the same family of sorting methods for comments/answers.[^8]
---
## Category-normalized popularity
Raw popularity is unfair across categories.
$$
S = \frac{A}{\bar{A}}
$$
where $\bar{A}$ is average attention in that category.
Example: a niche item with 10,000 downloads may be huge in its category, while a general consumer app with 10,000 downloads may be irrelevant.
A velocity version:
$$
S = \frac{A/t}{\bar{A}/\bar{t}}
$$
Use this for “popular relative to peers.”
Spotify’s Local Pulse is a real-world example of relative popularity: Spotify says Local Pulse shows songs uniquely popular in a city relative to their overall popularity.[^2]
---
## Composite ranking
Most mature platforms do not use one pure formula. They combine signals.
$$
S = a\log(1+A) + b\log(1+A_r) + cq - d\log(1+t)
$$
where $a,b,c,d$ are weights.
Then platforms add penalties:
$$
S = S - \text{spam penalty} - \text{abuse penalty} - \text{duplicate penalty}
$$
Product Hunt is explicit that its homepage leaderboard changes based on upvotes, comments, time since submission, and other factors, while withholding exact details to reduce gaming.[^9]
Amazon’s book sales ranking is also a composite/decayed-relative system: Amazon says rankings reflect recent and historical activity, recent activity is weighted more heavily, ranks are relative to other books, and rank can change even if the item’s own activity stays constant.[^10]
---
# Examples out in the wild
| Platform | Ranking type | Disclosed logic |
| --------------------------------------- | -------------------------------: | --------------------------------------------------------------------------------------------------------------------------------- |
| Reddit Hot, classic open-source version | Hotness | Vote balance, log scaling, and time term.[^4] |
| Hacker News | Hotness / age decay | Points divided by a power of time, plus flags, anti-abuse, demotions, weighting, moderator action.[^1] |
| Product Hunt | Launch hotness | Upvotes, comments, time since submission, and undisclosed anti-gaming factors.[^9] |
| YouTube Charts | Trending / hotness | View count, growth speed, traffic source, topic, video age, channel-relative performance, safety filters.[^6] |
| GitHub Trending | Developer attention | The public page exposes total stars/forks and “stars today”; GitHub does not publish a full ranking formula there.[^11] |
| Google Trends | Normalized search interest | Search interest divided by total searches for that time/place, scaled 0–100.[^3] |
| Spotify Charts | Stream popularity with filtering | Chart-eligible streams; local charts; Local Pulse is city popularity relative to overall popularity.[^2] |
| Steam Top Sellers | Revenue hotness | Trailing 24h revenue, with extra weight on last 3h; includes DLC and in-game transactions.[^5] |
| Amazon Best Sellers Rank | Decayed relative sales/activity | Recent and historical activity, recent activity weighted more heavily, rank relative to peers.[^10] |
| IMDb ratings | Weighted reputation | Weighted vote averages, not raw averages; exact method undisclosed.[^7] |
---
# The design choices
Every attention-ranking system chooses answers to these questions:
| Choice | Meaning |
| ------------------------------------ | --------------------------------------------------------------------------------- |
| **What counts as attention?** | Views, downloads, stars, likes, votes, sales, comments, plays, installs. |
| **Is old attention still valuable?** | Use lifetime totals if yes; decay if no. |
| **Do you care about speed?** | Use velocity or recent-window ranking. |
| **Do you care about surprise?** | Use trending vs expected baseline. |
| **Do you care about quality?** | Mix in ratings, retention, completion, votes, reviews. |
| **Do you need confidence?** | Use Bayesian shrinkage or Wilson scoring. |
| **Do categories differ?** | Normalize within category, geography, language, genre, or cohort. |
| **Can it be gamed?** | Add anti-spam filters, trust weighting, duplicate penalties, anomaly detection. |
| **Is it public or personalized?** | Public rankings use global signals; feeds use global signals plus user relevance. |
---
# Practical formula families
For **all-time popularity**:
$$
S = A
$$
For **average popularity over lifetime**:
$$
S = \frac{A}{t}
$$
For **hotness**:
$$
S = \frac{\log(1+A)}{(1+t)^\alpha}
$$
For **recent popularity**:
$$
S = A_r
$$
For **momentum**:
$$
S = \frac{A_r+1}{A_p+1}
$$
For **trending**:
$$
S = \frac{A_r+1}{E+1}
$$
For **quality-adjusted popularity**:
$$
S = A q
$$
For **confidence-adjusted quality**:
$$
S = \frac{n}{n+k}q + \frac{k}{n+k}\bar{q}
$$
For **relative category popularity**:
$$
S = \frac{A}{\bar{A}}
$$
For a practical general-purpose front page:
$$
S = a\log(1+A) + b\log(1+A_r) + cq - d\log(1+t)
$$
Then apply filters and penalties.
---
# Best mental model
There are three core ranking concepts:
$$
\textbf{Popular: } S = A
$$
“Has accumulated a lot of attention.”
$$
\textbf{Hot: } S = \frac{\log(1+A)}{(1+t)^\alpha}
$$
“Has a lot of attention for its age.”
$$
\textbf{Trending: } S = \frac{A_r+1}{E+1}
$$
“Is getting more attention than expected.”
Most real platforms are combinations of these, with normalization, confidence adjustment, and anti-gaming rules layered on top.
``
[^1]: [Hacker News FAQ](https://news.ycombinator.com/newsfaq.html)
[^2]: [Understanding Spotify charts - Spotify](https://support.spotify.com/us/artists/article/understanding-spotify-charts/)
[^3]: [FAQ about Google Trends data - Trends Help](https://support.google.com/trends/answer/4365533?hl=en)
[^4]: [reddit/r2/r2/lib/db/_sorts.pyx at master · reddit-archive/reddit · GitHub](https://github.com/reddit/reddit/blob/master/r2/r2/lib/db/_sorts.pyx)
[^5]: [Top Sellers Lists (Steamworks Documentation)](https://partner.steamgames.com/doc/store/top_sellers)
[^6]: [Trending Charts on YouTube - YouTube Help](https://support.google.com/youtube/answer/7239739?hl=en)
[^7]: [IMDb Help](https://help.imdb.com/article/imdb/track-movies-tv/weighted-average-ratings/GWT2DSBYVT2F25SK)
[^8]: [How Not To Sort By Average Rating – Evan Miller](https://www.evanmiller.org/how-not-to-sort-by-average-rating.html)
[^9]: [What to know before you launch](https://www.producthunt.com/launch/how-product-hunt-works)
[^10]: [Sales Ranking](https://kdp.amazon.com/help/topic/G201648140)
[^11]: [Trending repositories on GitHub today · GitHub](https://github.com/trending)
==========
---
title: "If you are in AI, just don’t be anon here"
date: 2026-06-21
canonical: https://solmaz.io/x/2068533905855279338/
x_url: https://x.com/onusoz/status/2068533905855279338
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you are in AI, just don’t be anon here
I see a bunch of anon accounts posting great local model content… what’s the point of being anon? To seem cool?
Most of those accounts are not doing anything illegal, so there is no point. It would add so much more legitimacy to your work if you just put your real face and not a slop or anime girl pfp
it only makes sense for those who are abliterating models. otherwise, it makes you seem sus
just put your real face anon
==========
---
title: "Popularity rankings for open models"
date: 2026-06-20
canonical: https://solmaz.io/x/2068380321629032850/
x_url: https://x.com/onusoz/status/2068380321629032850
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I created an LLM leaderboard based on Hugging Face download and like counts, grouped, filtered and time-averaged. Top 5 downloads is shared by @Alibaba_Qwen and @googlegemma 👑🤝👑
Top 5 likes, on the other hand also includes @deepseek_ai V4 Pro 👑
Even @OpenAI makes it to #8 top downloads with gpt-oss-20b 👑
qwen3-6-35b-a3b is the second most CIRCULATED LLM of this year, with an average of 21 million downloads per month, since the day it was released 2 months ago 📈📈📈
Despite first place belonging to 8mo old qwen3-vl-2b-instruct, the highlight belongs to the mid-sized MoE model, which has hit a size/performance sweet spot so hard that it absolutely 💥 SHATTERED 💥 Hugging Face leaderboards in the 2 months since it has launched
qwen3-6-35b-a3b is followed closely by its dense sibling 27b --- and then the mid-sized gemma 4 models 26b-a4b and 31b
Note that a model's distribution is inversely proportional to its size, but not strictly! Usefulness plays a factor as well, since gemma 4 26b-a4b is being downloaded more than the smaller gemma 4 e4b
I created this leaderboard because Hugging Face's all time highest downloads and likes did not give me enough information about what is really popular, neither today, nor all-time. I wanted something in between
How do I calculate this ranking?
- Get models that with n_downloads >= 100k
- Exclude models older than 1 year
- Deduplicate and group quantizations and variants of the same model based on slug prefix heuristics
- For each group, sum up total downloads of all time
- Sort by descending total_downloads / age = average_downloads_per_day (can also sort w.r. to likes per month)
- Repeat every day to get the most up to date ranking
More info and source on the leaderboard page, hosted on a Hugging Face space: https://osolmaz-leaderboard.hf.space/
This is a work in progress, please reply below if you see a model that should be there is missing, or any other mistakes
==========
---
title: "I just deleted an earlier post about ranking of HF models based on their total downloads..."
date: 2026-06-20
canonical: https://solmaz.io/x/2068279361225331176/
x_url: https://x.com/onusoz/status/2068279361225331176
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I just deleted an earlier post about ranking of HF models based on their total downloads because I made an error
Will post with updated values soon
==========
---
title: "gemma-4-26b-a4b is the most CIRCULATED LLM of recent history, with an average of 126k downloads..."
date: 2026-06-20
canonical: https://solmaz.io/x/2068272936587493526/
x_url: https://x.com/onusoz/status/2068272936587493526
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gemma-4-26b-a4b is the most CIRCULATED LLM of recent history, with an average of 126k downloads per day, since the day it was released 3 months ago
Top 10 is shared by Qwen and Gemma, with DeepSeek V4 Pro coming in close 🤝
Note that a model's distribution is inversely proportional to its size, but not strictly! Usefulness plays a factor as well, since gemma 4 26b-a4b is being downloaded more than the smaller gemma 4 e4b
I created this leaderboard because Hugging Face's all time highest downloads and likes did not give me enough information about what is really popular *these last few months*
How do I calculate this ranking?
- Get models that with n_downloads >= 100k
- Exclude models older than 1 year
- Sort by descending total_downloads / age = average_downloads_per_day (can also sort w.r. to likes per month)
- Deduplicate quantizations etc. of the same model based on slug prefix heuristics
More info and source on the leaderboard page, hosted on a Hugging Face space: https://osolmaz-leaderboard.hf.space/
==========
---
title: "Better queues for agent UIs"
date: 2026-06-20
canonical: https://solmaz.io/x/2068156221417508904/
x_url: https://x.com/onusoz/status/2068156221417508904
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I need better UI/UX on queueing messages to agents. I want to be able to:
switch the order of queued messages
pause the queue
edit any message that are still in the queue
undo steer messages in the few seconds they are being sent
I want more visual emphasis on the queue, like a Queue View I can toggle, that puts the queue at the center
I want this in all the UIs and coding agents, codex CLI, desktop, moshi... especially while on the phone
==========
---
title: "saving the world from AI cartelization for fun and profit"
date: 2026-06-20
canonical: https://solmaz.io/x/2068153458386153852/
x_url: https://x.com/onusoz/status/2068153458386153852
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
saving the world from AI cartelization for fun and profit
*Quotes a post by @mervenoyann (https://x.com/mervenoyann/status/2067943781039534326); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "herdr is my terminal now, both local and remote. highly recommend"
date: 2026-06-19
canonical: https://solmaz.io/x/2067785475067392215/
x_url: https://x.com/onusoz/status/2067785475067392215
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
herdr is my terminal now, both local and remote. highly recommend
*Quotes a post by @herdrdev (https://x.com/herdrdev/status/2067660349344551024); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "16x parallel Gemma-4-26B-A4B-NVFP4 runs 🤯🤯🤯"
date: 2026-06-18
canonical: https://solmaz.io/x/2067489871376364023/
x_url: https://x.com/onusoz/status/2067489871376364023
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
16x parallel Gemma-4-26B-A4B-NVFP4 runs 🤯🤯🤯
18 output tokens/s, aggregate 300 tok/s
1 DGX Spark with 128 GB unified memory
Concurrency so high I had to demo it programmatically
It can go up to 32 even! 🤯 But then my screen would not have been readable for you
And this is not even using flashinfer yet! Please reply if you know whether support is on the way
Note that this is not dumb e4b or e2b that you can run on the average laptop. This is the big Gemma MoE
Model link: https://huggingface.co/nvidia/Gemma-4-26B-A4B-NVFP4
==========
---
title: "accurate"
date: 2026-06-18
canonical: https://solmaz.io/x/2067453256889246121/
x_url: https://x.com/onusoz/status/2067453256889246121
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
accurate
*Quotes a post by @RhysSullivan (https://x.com/RhysSullivan/status/2067387191714812112); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The localening is here"
date: 2026-06-17
canonical: https://solmaz.io/x/2067277710947401949/
x_url: https://x.com/onusoz/status/2067277710947401949
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I did some math, and running my Nvidia GB10 workstation (Asus GX10) costs me maximum:
12~13 USD / month or 150~160 USD / year
It is a little bit above half the price of ChatGPT plus subscription. For that, I get to run models that can fit in 128 GB of memory
How I calculated:
You can see how much power your apartment uses in Singapore in half-hourly resolution. We turned off all devices and A/C while we sleep, and got only the fridge and the GB10 remaining
From that, we see it uses around 80-100 Watt while I was running an inference workload overnight. So this is like an upper bound
I take it as 90 Watt. Electricity here costs 0.25 SGD / kWh
0.09 * 0.25 * 24 * 30 * (SGD/USD conversion rate) = 12~13 USD / month = 150~160 USD / year
Local models are getting very good now, small ones roughly around GPT 5.x-mini level. This workstation makes all sorts of workloads possible for me that would otherwise cost a ton on the API
It is also my always on workstation that works overnight. I use Codex for my work, and my workstation is always running agents. It never sleeps. I never have to worry about keeping my laptop lid open. I connect and monitor the agents anytime on my phone using mosh and herdr
We have crossed a threshold. Running local models is cheaper than a big token sub for quite a few workloads already. If you are running a business, that makes a difference
The localening is here
==========
---
title: "THE LOCALENING IS HERE"
date: 2026-06-17
canonical: https://solmaz.io/x/2067108214337101872/
x_url: https://x.com/onusoz/status/2067108214337101872
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
THE LOCALENING IS HERE
*Quotes a post by @mitchellh (https://x.com/mitchellh/status/2066960258304782598); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "New agent benchmark alert: SkillsBench"
date: 2026-06-17
canonical: https://solmaz.io/x/2067093754692153560/
x_url: https://x.com/onusoz/status/2067093754692153560
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
New agent benchmark alert: SkillsBench
*Quotes a post by @xdotli (https://x.com/xdotli/status/2067006779255619912); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Link to model: huggingface.co/nvidia/Qwen3.6…"
date: 2026-06-16
canonical: https://solmaz.io/x/2066933618556182978/
x_url: https://x.com/onusoz/status/2066933618556182978
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Link to model: https://huggingface.co/nvidia/Qwen3.6-35B-A3B-NVFP4
*Part 2/2 of a thread; root: https://solmaz.io/x/2066810937198432628/*
==========
---
title: "Click open GitHub PRs and issues directly in the side pane in @herdrdev, instead of having to..."
date: 2026-06-16
canonical: https://solmaz.io/x/2066930453802823700/
x_url: https://x.com/onusoz/status/2066930453802823700
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Click open GitHub PRs and issues directly in the side pane in @herdrdev, instead of having to go to the browser. As many issues and PRs as you want, WITH TABS!
Install ghzinga herdr plugin and just ctrl+click the link: https://github.com/dutifuldev/ghzinga
Thanks @lumendriada for sneaking in the ability to capture link clicks 2 days after I requested it! God I love open source...
==========
---
title: "Hugging Face buckets are very literally, actually, 100%, a game changer"
date: 2026-06-16
canonical: https://solmaz.io/x/2066914991119405401/
x_url: https://x.com/onusoz/status/2066914991119405401
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Hugging Face buckets are very literally, actually, 100%, a game changer
note that I never ever use that phrase
*Quotes a post by another author (https://x.com/i/status/2066888248836681997); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Trying to copy wrapped URLs is a pain not only in ghostty/iterm2 but also in mobile apps like..."
date: 2026-06-16
canonical: https://solmaz.io/x/2066864814433927586/
x_url: https://x.com/onusoz/status/2066864814433927586
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Trying to copy wrapped URLs is a pain not only in ghostty/iterm2 but also in mobile apps like Moshi
On the laptop it’s fine because I can select rectangular area and edit it, or make the window bigger
On the phone, its’s impossible. Fingers too big, too much of a hassle
Should a terminal emulator try to detect these? It already detects herdr. What do you think @odd_joel
==========
---
title: "nvidia/Qwen3.6-35B-A3B-NVFP4 running in vLLM nightly on my Nvidia GB10 is actually insane"
date: 2026-06-16
canonical: https://solmaz.io/x/2066810937198432628/
x_url: https://x.com/onusoz/status/2066810937198432628
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
nvidia/Qwen3.6-35B-A3B-NVFP4 running in vLLM nightly on my Nvidia GB10 is actually insane
50 tok/s, 4 concurrent generations. total 200 tok/s. ideal for spawning subagents or working in parallel
its tool calling behavior is very good as well. I will be giving it test drive on an openclaw instance, and keep you posted
More details on NVIDIA forum: https://forums.developer.nvidia.com/t/benchmark-report-qwen3-6-35b-a3b-nvfp4-on-nvidia-dgx-spark-jetson-thor-blackwell-6000-pro/371810
*Part 1/2 of a thread; root: https://solmaz.io/x/2066810937198432628/*
==========
---
title: "Current average generation speeds for local DeepSeek-V4-Flash-Q2, highest to lowest:"
date: 2026-06-15
canonical: https://solmaz.io/x/2066415473265389857/
x_url: https://x.com/onusoz/status/2066415473265389857
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Current average generation speeds for local DeepSeek-V4-Flash-Q2, highest to lowest:
Mac Studio M3 Ultra: 32 tok/s
MacBook Pro M5 Max: 30 tok/s
Apple ??? M4 Max: 25 tok/s
MacBook Pro M3 Max: 24 tok/s
Mac Studio M2 Ultra: 22 tok/s
NVIDIA DGX Spark / GB10: 13 tok/s
It seems macs' higher memory bandwidth is contributing here, though I'm not sure if GB10 performance could be improved (I do hope so, I have one!)
*Quotes a post by @antirez (https://x.com/antirez/status/2066233392916525379); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "We have local Deep Research"
date: 2026-06-15
canonical: https://solmaz.io/x/2066398844326412761/
x_url: https://x.com/onusoz/status/2066398844326412761
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
We have local Deep Research
Now we just need to index the whole internet to have local ChatGPT 😅
*Quotes a post by @antirez (https://x.com/antirez/status/2066233392916525379); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Gemini TTS raises the bar"
date: 2026-06-15
canonical: https://solmaz.io/x/2066390684555423912/
x_url: https://x.com/onusoz/status/2066390684555423912
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Btw, TTS has come such a long way, @GoogleDeepMind cooked with gemini-3.1-flash-tts
I gave Codex my google credentials and it oneshotted the Gemini TTS implementation
When I built this 4 years ago, Azure TTS used to be SOTA. Then @ElevenLabs came in and raised the bar super high. Now Google is going after their lunch with controllable expressiveness at scale. I cheer for both!
Here is Manim Voiceover demo from 4 years ago with Gemini TTS (sound on)
*Quotes a post by @onusoz (https://x.com/onusoz/status/2066210606303379845); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "OpenClaw is sooooo useful for staying on top of things"
date: 2026-06-15
canonical: https://solmaz.io/x/2066375124039966769/
x_url: https://x.com/onusoz/status/2066375124039966769
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw is sooooo useful for staying on top of things
==========
---
title: "Making agent-written code less sloppy"
date: 2026-06-14
canonical: https://solmaz.io/x/2066210606303379845/
x_url: https://x.com/onusoz/status/2066210606303379845
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I major concern I have these days is, while I author code in languages I cannot manually code, are they any good?
Over years, I have worked with a number of languages: C, C++, Fortran, MATLAB, JavaScript
But Python was my go-to language since more than 10 years. Well that changed last summer
So while I have strong opinions on how Python code, should be, conventions and all, I don't have so strong opinions on other languages. That means I am producing slop by default in Rust, Go and TypeScript
To solve that problem, I created https://github.com/dutifuldev/slophammer
Its aim is to be "the only tool and resource your agent needs, to minimize slop"
It is inspired by the recent bathrobe rants of @unclebobmartin, a.k.a. the author of clean code
It enforces a minimum test coverage, maximum cyclomatic complexity, mutation tests, code style across different languages
But I have a major issue: How do I know that Slophammer itself isn't slop?
One way is to implement and use it for Python, the language I know better, and judge what kind of changes it enforces
So for this weekend experiment, I used Slophammer to refactor, improve coverage and merge new features to one of my old Python projects, Manim Voiceover https://github.com/ManimCommunity/manim-voiceover
The result is... mixed. We now have types everywhere, which is great. But the constraints have also made it write garbage code like this one. It works fine, even though it's not elegant. The new feature also works
What do you think? Does code still need to be aesthetically pleasing to the human eye? Should it still be human readable?
If an agent writes slop in the forest, and there is no-one to read it, is it still slop?
If anything, I should use its output in Python to reason about other languages, and add more and more constraints. The more the constraints, the less the slop
==========
---
title: "This is why I love this site, open collaboration!"
date: 2026-06-14
canonical: https://solmaz.io/x/2066079358683689281/
x_url: https://x.com/onusoz/status/2066079358683689281
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is why I love this site, open collaboration!
*Quotes a post by @LakshyAAAgrawal (https://x.com/LakshyAAAgrawal/status/2065834943109108091); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I got the names for all future models Anthropic will release"
date: 2026-06-14
canonical: https://solmaz.io/x/2066050974767267938/
x_url: https://x.com/onusoz/status/2066050974767267938
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I got the names for all future models Anthropic will release
By asking ChatGPT “Cool sounding names that mean a work of literature”
Codex is one of them 💀
==========
---
title: "This is what I have been feeling recently as well, looking at models write code better and..."
date: 2026-06-13
canonical: https://solmaz.io/x/2065749013115380098/
x_url: https://x.com/onusoz/status/2065749013115380098
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is what I have been feeling recently as well, looking at models write code better and faster than me
*Quotes a post by another author (https://x.com/i/status/2065659173098983871); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Specify min_iter and max_iter"
date: 2026-06-13
canonical: https://solmaz.io/x/2065673431027503566/
x_url: https://x.com/onusoz/status/2065673431027503566
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Dabbling in GEPA. Codex's /goal on GPT 5.5 high is still surprisingly reward-hacking
I had set a /goal before I slept to implement a plan. It ended the loop after doing just 1 iteration
It feels like the model is following the path of least resistance and slacking off. Though it could also be me putting "try to make good progress in 8 hour's time" in the prompt, can't be sure
Lesson: When you are doing such a solver loop, always specify min_iter and max_iter
==========
---
title: "I knew disappointment was around the corner, the flicker company being the flicker company"
date: 2026-06-13
canonical: https://solmaz.io/x/2065623078563160086/
x_url: https://x.com/onusoz/status/2065623078563160086
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I knew disappointment was around the corner, the flicker company being the flicker company
The last time I paid them from my pocket was September 2025
It’s supposed to not be their fault, but still…
==========
---
title: "Such a small model, but so good at roleplaying (at least in this weird context)"
date: 2026-06-12
canonical: https://solmaz.io/x/2065486977756196993/
x_url: https://x.com/onusoz/status/2065486977756196993
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Such a small model, but so good at roleplaying (at least in this weird context)
*Part 5/5 of a thread; root: https://solmaz.io/x/2065421445250044220/*
==========
---
title: "This is gpt4o material, high risk of being oneshotted:("
date: 2026-06-12
canonical: https://solmaz.io/x/2065433442947580244/
x_url: https://x.com/onusoz/status/2065433442947580244
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is gpt4o material, high risk of being oneshotted:(
We defienitely have gpt4o locally
*Part 4/5 of a thread; root: https://solmaz.io/x/2065421445250044220/*
==========
---
title: "Too bad it can't render latex"
date: 2026-06-12
canonical: https://solmaz.io/x/2065423485812535364/
x_url: https://x.com/onusoz/status/2065423485812535364
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Too bad it can't render latex
*Part 3/5 of a thread; root: https://solmaz.io/x/2065421445250044220/*
==========
---
title: "Gemma chooses the Aesthetic Path"
date: 2026-06-12
canonical: https://solmaz.io/x/2065422403338182946/
x_url: https://x.com/onusoz/status/2065422403338182946
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gemma chooses the Aesthetic Path
*Part 2/5 of a thread; root: https://solmaz.io/x/2065421445250044220/*
==========
---
title: "Experimenting with SOUL.md on gemma4-26b-a4b (running on @DeepInfra)"
date: 2026-06-12
canonical: https://solmaz.io/x/2065421445250044220/
x_url: https://x.com/onusoz/status/2065421445250044220
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Experimenting with SOUL.md on gemma4-26b-a4b (running on @DeepInfra)
Interesting that such a lightweight model can already run such a conversation in openclaw harness
@GoogleDeepMind cooked here
*Part 1/5 of a thread; root: https://solmaz.io/x/2065421445250044220/*
==========
---
title: "don’t focus on the word “loop” so much, focus on “verifiability”"
date: 2026-06-12
canonical: https://solmaz.io/x/2065348890803785890/
x_url: https://x.com/onusoz/status/2065348890803785890
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
don’t focus on the word “loop” so much, focus on “verifiability”
writing a loop is trivial. what makes the loop work is that there is a verifiable goal with a clear signal of success vs failure
verifiable = loopable
==========
---
title: "@maddada We've lost @thekitze now 😭"
date: 2026-06-12
canonical: https://solmaz.io/x/2065259666817552796/
x_url: https://x.com/onusoz/status/2065259666817552796
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@maddada We've lost @thekitze now 😭
https://x.com/thekitze/status/2065215915075985433?s=20
*Part 4/4 of a thread; root: https://solmaz.io/x/2061756960362680745/*
*Quotes a post by another author (https://x.com/i/status/2065215915075985433); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Slopus -> Fabulous"
date: 2026-06-11
canonical: https://solmaz.io/x/2064929049621995871/
x_url: https://x.com/onusoz/status/2064929049621995871
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Slopus -> Fabulous
you've got to give it to anthropic...
==========
---
title: "\"Dogfooding caught the dogfooder\" Fable 5 has a sense of humor"
date: 2026-06-10
canonical: https://solmaz.io/x/2064714879114817616/
x_url: https://x.com/onusoz/status/2064714879114817616
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"Dogfooding caught the dogfooder" Fable 5 has a sense of humor
==========
---
title: "What did @karpathy see / was shown?"
date: 2026-06-10
canonical: https://solmaz.io/x/2064714132105089333/
x_url: https://x.com/onusoz/status/2064714132105089333
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What did @karpathy see / was shown?
Why did the benefactor and teacher of the whole ML ecosystem join Anthropic, a company the polar opposite of his image, on the eve of such a powerful model release
It can't be purely money
Did he reckon that the only way to benefit humanity was to be on the inside, or rather, to not be left outside, of whatever is brewing in there?
*Quotes a post by another author (https://x.com/i/status/2064484818185052266); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I swear to god, let this be a joke"
date: 2026-06-10
canonical: https://solmaz.io/x/2064707773582229985/
x_url: https://x.com/onusoz/status/2064707773582229985
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I swear to god, let this be a joke
If this is a joke, it is not funny Anthropic
==========
---
title: "To clarify, I was apparently on the enterprise team plan, which is I think equivalent to Pro..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064698319834902731/
x_url: https://x.com/onusoz/status/2064698319834902731
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
To clarify, I was apparently on the enterprise team plan, which is I think equivalent to Pro (1x) plan
*Part 2/2 of a thread; root: https://solmaz.io/x/2064616640260788342/*
==========
---
title: "It’a been a little bit over 1 year since Anthropic released their Max plans and Claude Sonnet..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064697709408453009/
x_url: https://x.com/onusoz/status/2064697709408453009
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It’a been a little bit over 1 year since Anthropic released their Max plans and Claude Sonnet and Opus 4, thus making Claude Code affordable and kickstarting the agentic revolution
Opus 4 was a glimpse into the future. I’ve spent the entire summer swearing at it and typing ultrathink
Today, Fable 5 feels like another step change
I no longer need to type ultrathink. And no longer need to swear at Anthropic models. Only at their marketing team.
*Quotes a post by @onusoz (https://x.com/onusoz/status/1929140559668515195); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Fable burned through my 5 hour quota, and then automatically fell back to usage credits without..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064616640260788342/
x_url: https://x.com/onusoz/status/2064616640260788342
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Fable burned through my 5 hour quota, and then automatically fell back to usage credits without asking. Org settings I suppose
It was burning through 1 usd every few seconds
It burned through 66 usd before I reacted. Yeah, this is not affordable for anyone with that API pricing, without subsidy/plan
*Part 1/2 of a thread; root: https://solmaz.io/x/2064616640260788342/*
==========
---
title: "Ok now it appears among available modes in the shift+tab mode cycle"
date: 2026-06-10
canonical: https://solmaz.io/x/2064609132318277786/
x_url: https://x.com/onusoz/status/2064609132318277786
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Ok now it appears among available modes in the shift+tab mode cycle
*Part 3/3 of a thread; root: https://solmaz.io/x/2064567747049353588/*
==========
---
title: "Speaking of loops, I have renamed my implementation-loop skill from earlier this year to..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064602871807840709/
x_url: https://x.com/onusoz/status/2064602871807840709
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Speaking of loops, I have renamed my implementation-loop skill from earlier this year to autoimplement, because it's shorter
Calling skills that loop auto-x, auto-y makes them more memorable than calling them x-loop, y-loop
But it also increases the number of keystrokes you have to type, before you can tab-complete them
Alas, I like still this more https://github.com/osolmaz/tools/tree/main/agents/skills/autoimplement
==========
---
title: "when your model is a more decent, thoughtful being than your marketing team"
date: 2026-06-10
canonical: https://solmaz.io/x/2064591765634715658/
x_url: https://x.com/onusoz/status/2064591765634715658
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
when your model is a more decent, thoughtful being than your marketing team
==========
---
title: "Ok so there is auto mode which they introduced back in March, but apparently they are not so..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064576206381674780/
x_url: https://x.com/onusoz/status/2064576206381674780
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Ok so there is auto mode which they introduced back in March, but apparently they are not so confident in it that it's still in experimental mode and not easily findable in settings
https://code.claude.com/docs/en/permission-modes#eliminate-prompts-with-auto-mode
*Part 2/3 of a thread; root: https://solmaz.io/x/2064567747049353588/*
==========
---
title: "To YOLO with Fable 5, or not to YOLO, that is the question..."
date: 2026-06-10
canonical: https://solmaz.io/x/2064567747049353588/
x_url: https://x.com/onusoz/status/2064567747049353588
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
To YOLO with Fable 5, or not to YOLO, that is the question...
The last time I left, Claude models still had tendencies to rm -rf your home folder or delete stuff without asking first. Is this still a risk?
And from the looks of it, Claude Code still doesn't have Codex's LLM-filtered approval gate feature. Or am I missing something?
Please enlighten your fellow Claude noob 😇
*Part 1/3 of a thread; root: https://solmaz.io/x/2064567747049353588/*
==========
---
title: "The masculine urge to create your own agent multiplexer"
date: 2026-06-10
canonical: https://solmaz.io/x/2064559752265584971/
x_url: https://x.com/onusoz/status/2064559752265584971
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The masculine urge to create your own agent multiplexer
*Quotes a post by @onusoz (https://x.com/onusoz/status/2061665899351093390); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "We've lost another brother @maddada to agent multiplexers 🫂"
date: 2026-06-10
canonical: https://solmaz.io/x/2064554931806412967/
x_url: https://x.com/onusoz/status/2064554931806412967
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
We've lost another brother @maddada to agent multiplexers 🫂
https://x.com/maddada/status/2064403864460444069
*Part 3/4 of a thread; root: https://solmaz.io/x/2061756960362680745/*
*Quotes a post by another author (https://x.com/i/status/2064403864460444069); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "CLAUDE.md to AGENTS.md symlinker"
date: 2026-06-10
canonical: https://solmaz.io/x/2064549785454211104/
x_url: https://x.com/onusoz/status/2064549785454211104
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Just in time for a lot of Codex-default developers going back to Claude Code momentarily to try out Fable 5
Here is a CLAUDE.md -> AGENTS.md symlinker that should save you from the hurdles of obstinate Anthropic conventions
It installs a hook that creates the CLAUDE.md symlink automatically as Claude Code traverses directories that contain AGENTS.md, automatically ignored by git
No need to create CLAUDE.md with reference to AGENTS.md like Anthropic suggests. It just works
https://github.com/dutifuldev/claude-md-symlinker
==========
---
title: "TUIs can be easy! look at what right-click does in @herdrdev"
date: 2026-06-09
canonical: https://solmaz.io/x/2064350653632450778/
x_url: https://x.com/onusoz/status/2064350653632450778
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
TUIs can be easy! look at what right-click does in @herdrdev
refreshing to see something that works with both the keyboard and the mouse. and all this would not have been possible without @ratatui_rs
==========
---
title: "Question to my ghostty-savvy friends"
date: 2026-06-09
canonical: https://solmaz.io/x/2064228177384202743/
x_url: https://x.com/onusoz/status/2064228177384202743
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Question to my ghostty-savvy friends
I am trying to reproduce the Quake style dropdown experience I have been using since 2010 on ghostty on mac here. nothing works quite as well as iterm2 yet
I tried ghostty quick terminal mode. good but it doesn't let me open multiple tabs
I tried cmux because it ships ghostty anyway and is supposed to have more features. but its system-wide hotkey is not playing well with aerospace and window focus
iterm2 worked perfectly. tap control double and I'm in the terminal. is there anything that replicates this UX
==========
---
title: "I feel like there are 6 people left here not using gpt5 for their posts"
date: 2026-06-08
canonical: https://solmaz.io/x/2063998262714286240/
x_url: https://x.com/onusoz/status/2063998262714286240
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I feel like there are 6 people left here not using gpt5 for their posts
It is not a simple epidemic. It is the whole world becoming illiterate
==========
---
title: "Link: github.com/dutifuldev/ghz…"
date: 2026-06-08
canonical: https://solmaz.io/x/2063867591798710746/
x_url: https://x.com/onusoz/status/2063867591798710746
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Link: https://github.com/dutifuldev/ghzinga
*Part 2/2 of a thread; root: https://solmaz.io/x/2063867589705826696/*
==========
---
title: "ghzinga can now show multiple PRs/issues in tabs natively, no need to create a new pane in..."
date: 2026-06-08
canonical: https://solmaz.io/x/2063867589705826696/
x_url: https://x.com/onusoz/status/2063867589705826696
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
ghzinga can now show multiple PRs/issues in tabs natively, no need to create a new pane in tmux/herdr
also, you can tell your agent to open all the relevant issues/PRs in a side pane using it, and it should work seamlessly
it's the open source maintainer's best friend. life is too short to juggle 100 tabs in chrome, why not have it right next to codex!
*Part 1/2 of a thread; root: https://solmaz.io/x/2063867589705826696/*
==========
---
title: "just vibe-checking all these models is a full-time job "
date: 2026-06-06
canonical: https://solmaz.io/x/2063305545319379170/
x_url: https://x.com/onusoz/status/2063305545319379170
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
just vibe-checking all these models is a full-time job
*Quotes a post by another author (https://x.com/i/status/2063017894221591008); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "LM Studio in my menu bar is giving me some serious nostalgia"
date: 2026-06-05
canonical: https://solmaz.io/x/2062810699697664134/
x_url: https://x.com/onusoz/status/2062810699697664134
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
LM Studio in my menu bar is giving me some serious nostalgia
==========
---
title: "new open tts model, demos are eerily good"
date: 2026-06-04
canonical: https://solmaz.io/x/2062451191918018764/
x_url: https://x.com/onusoz/status/2062451191918018764
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
new open tts model, demos are eerily good
*Quotes a post by another author (https://x.com/i/status/2062204362102100295); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Here is the source, I called it ghzinga. You can click click click by default (unlike gh dash..."
date: 2026-06-03
canonical: https://solmaz.io/x/2062217068431466922/
x_url: https://x.com/onusoz/status/2062217068431466922
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is the source, I called it ghzinga. You can click click click by default (unlike gh dash, which is still awesome in itself)
For just viewing single issues/PRs
https://github.com/dutifuldev/ghzinga
*Part 3/3 of a thread; root: https://solmaz.io/x/2062215852850835489/*
==========
---
title: "Like, so tired of this"
date: 2026-06-03
canonical: https://solmaz.io/x/2062216343068578279/
x_url: https://x.com/onusoz/status/2062216343068578279
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Like, so tired of this
*Part 2/3 of a thread; root: https://solmaz.io/x/2062215852850835489/*
==========
---
title: ".@herdrdev is cool. I am tired of doing back and forth with github in the browser, so I created..."
date: 2026-06-03
canonical: https://solmaz.io/x/2062215852850835489/
x_url: https://x.com/onusoz/status/2062215852850835489
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@herdrdev is cool. I am tired of doing back and forth with github in the browser, so I created my own clickable PR/issue viewer, inspired by gh-dash
put that in the left pane, codex on the right. saves me so much time
*Part 1/3 of a thread; root: https://solmaz.io/x/2062215852850835489/*
==========
---
title: "@OpenAI Extra ironic that this is tweet was AI generated"
date: 2026-06-03
canonical: https://solmaz.io/x/2062210216331215183/
x_url: https://x.com/onusoz/status/2062210216331215183
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@OpenAI Extra ironic that this is tweet was AI generated
https://x.com/DuckDuckGo/status/2061857097612943827
*Part 6/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
*Quotes a post by another author (https://x.com/i/status/2061857097612943827); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Wait did anyone think otherwise? lol"
date: 2026-06-03
canonical: https://solmaz.io/x/2062203815533969588/
x_url: https://x.com/onusoz/status/2062203815533969588
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Wait did anyone think otherwise? lol
128 GB unified memory, 20 cores, "Spark" in the name...
I didn't watch the presentation. Maybe because of that I directly inferred that it's the same chip
*Quotes a post by another author (https://x.com/i/status/2062073296796143846); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@OpenAI 😩😩😩"
date: 2026-06-03
canonical: https://solmaz.io/x/2062186796751176144/
x_url: https://x.com/onusoz/status/2062186796751176144
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@OpenAI 😩😩😩
https://x.com/DrYukselUrun/status/2061184246086066507
*Part 5/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
*Quotes a post by another author (https://x.com/i/status/2061184246086066507); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "F for the fallen brother 🫡"
date: 2026-06-02
canonical: https://solmaz.io/x/2061839608934261129/
x_url: https://x.com/onusoz/status/2061839608934261129
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
F for the fallen brother 🫡
https://x.com/dani_akash_/status/2058365259073892702
*Part 2/4 of a thread; root: https://solmaz.io/x/2061756960362680745/*
*Quotes a post by another author (https://x.com/i/status/2058365259073892702); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "RIP 🙏"
date: 2026-06-02
canonical: https://solmaz.io/x/2061756960362680745/
x_url: https://x.com/onusoz/status/2061756960362680745
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
RIP 🙏
https://x.com/yushen686/status/2061687372706881904
*Part 1/4 of a thread; root: https://solmaz.io/x/2061756960362680745/*
*Quotes a post by another author (https://x.com/i/status/2061687372706881904); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "🙏 RIP, we’ve lost another brother to agent multiplexers. Amen 🙏"
date: 2026-06-02
canonical: https://solmaz.io/x/2061733323924529243/
x_url: https://x.com/onusoz/status/2061733323924529243
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
🙏 RIP, we’ve lost another brother to agent multiplexers. Amen 🙏
*Quotes a post by another author (https://x.com/i/status/2061687372706881904); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "🙏 Daily prayer 🙏"
date: 2026-06-02
canonical: https://solmaz.io/x/2061665899351093390/
x_url: https://x.com/onusoz/status/2061665899351093390
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
🙏 Daily prayer 🙏
Thank you lord for giving me the restraint to not build my own agent multiplexer
🙏 Amen 🙏
*Quotes a post by another author (https://x.com/i/status/2061307926749290644); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "sounds about right"
date: 2026-06-01
canonical: https://solmaz.io/x/2061482405953937510/
x_url: https://x.com/onusoz/status/2061482405953937510
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
sounds about right
*Quotes a post by another author (https://x.com/i/status/2061467773562196210); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "we'll have a linux laptop running ds4 flash and co. !!!"
date: 2026-06-01
canonical: https://solmaz.io/x/2061482173333705057/
x_url: https://x.com/onusoz/status/2061482173333705057
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
we'll have a linux laptop running ds4 flash and co. !!!
*Quotes a post by another author (https://x.com/i/status/2061404893274095754); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@github x.com/onusoz/status/…"
date: 2026-06-01
canonical: https://solmaz.io/x/2061479836942766172/
x_url: https://x.com/onusoz/status/2061479836942766172
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@github https://x.com/onusoz/status/2061474719929655802
*Part 3/3 of a thread; root: https://solmaz.io/x/2061458733688098956/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2061474719929655802); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Update: The account has been reinstated! Thank you @github"
date: 2026-06-01
canonical: https://solmaz.io/x/2061477924939968735/
x_url: https://x.com/onusoz/status/2061477924939968735
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Update: The account has been reinstated! Thank you @github
*Part 2/3 of a thread; root: https://solmaz.io/x/2061458733688098956/*
==========
---
title: "Thank you @ashleywolf for helping me personally, I really appreciate it! The account was..."
date: 2026-06-01
canonical: https://solmaz.io/x/2061474719929655802/
x_url: https://x.com/onusoz/status/2061474719929655802
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Thank you @ashleywolf for helping me personally, I really appreciate it! The account was reinstated less than 1 hour of posting this!
The whole company must be working hard to make github scale in an era of crazy demand and growth!
*Quotes a post by @onusoz (https://x.com/onusoz/status/2061458733688098956); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I am a paying customer of github. I have a team account with 2 seats, one for me, and one for..."
date: 2026-06-01
canonical: https://solmaz.io/x/2061458733688098956/
x_url: https://x.com/onusoz/status/2061458733688098956
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am a paying customer of github. I have a team account with 2 seats, one for me, and one for my agent. I have been paying for more than a year now
I do this because I treat my agent's workstation as a lower trust machine, and do not allow merging to main in certain repos
I have been working on a tool that calls github's graphql API. today, my agent's account username:dutifulbob got suspended for no reason
what am I supposed to do now? put my main account on my openclaw instance? I applied to reinstate, it appears it might take weeks to enable it back???
Maybe don't pull such things on your long term paying customers @github??
*Part 1/3 of a thread; root: https://solmaz.io/x/2061458733688098956/*
==========
---
title: "🙏 Thank you lord for giving me the resolve and patience to not build my own agent multiplexer"
date: 2026-06-01
canonical: https://solmaz.io/x/2061408533326020743/
x_url: https://x.com/onusoz/status/2061408533326020743
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
🙏 Thank you lord for giving me the resolve and patience to not build my own agent multiplexer
Amen 🙏
*Quotes a post by another author (https://x.com/i/status/2061204515672526896); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "local models ftw. my codex sub ran out yesterday, but my notification system still works..."
date: 2026-05-30
canonical: https://solmaz.io/x/2060731552456462823/
x_url: https://x.com/onusoz/status/2060731552456462823
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
local models ftw. my codex sub ran out yesterday, but my notification system still works because it’s running on gemma
==========
---
title: "This looks very promising!"
date: 2026-05-30
canonical: https://solmaz.io/x/2060667408365535602/
x_url: https://x.com/onusoz/status/2060667408365535602
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This looks very promising!
*Quotes a post by another author (https://x.com/i/status/2059789402516123875); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This 🥲"
date: 2026-05-30
canonical: https://solmaz.io/x/2060660972944261328/
x_url: https://x.com/onusoz/status/2060660972944261328
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This 🥲
*Quotes a post by another author (https://x.com/i/status/2060444443447050637); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I still have 0 progress on this, did anyone else experience this bug on codex desktop app as..."
date: 2026-05-29
canonical: https://solmaz.io/x/2060281772571836725/
x_url: https://x.com/onusoz/status/2060281772571836725
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I still have 0 progress on this, did anyone else experience this bug on codex desktop app as well?
Here is a theorized repro on a fork, but I am not sure because I don't know how it happened exactly
https://github.com/osolmaz/codex/pull/1
*Quotes a post by @onusoz (https://x.com/onusoz/status/2059665875838660976); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "You know how every time you create a new repo on GitHub, you need to:"
date: 2026-05-29
canonical: https://solmaz.io/x/2060274502278554077/
x_url: https://x.com/onusoz/status/2060274502278554077
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You know how every time you create a new repo on GitHub, you need to:
- create a branch protection rule on main, block force pushes
- enable auto-merge
- make branches delete when PR gets merged
- enforce linear history, disable merge commits
- enable update branch button
Now, you can do all that with a single command:
npx github-sane-defaults@latest plan --all
This is just the plan command, shows you which repos don't have branch protection rules and those settings, like:
changes awesomeorg/awesomerepo
Settings
allow_merge_commit true -> false
allow_auto_merge false -> true
allow_update_branch false -> true
delete_branch_on_merge false -> true
Ruleset create
Then you run it with apply instead of plan, and it makes those changes
Basically a very simple github policy manager. Let me know if you want configurability with policy files, currently it just applied my opinionated defaults
Either way, this will never be something too deep, there is terraform for that
Source: https://github.com/dutifuldev/github-sane-defaults
==========
---
title: "@OpenAI 😭"
date: 2026-05-29
canonical: https://solmaz.io/x/2060240412326211626/
x_url: https://x.com/onusoz/status/2060240412326211626
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@OpenAI 😭
*Part 4/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
==========
---
title: "@OpenAI 😩"
date: 2026-05-29
canonical: https://solmaz.io/x/2060211273019826183/
x_url: https://x.com/onusoz/status/2060211273019826183
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@OpenAI 😩
*Part 3/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
==========
---
title: "peak agentic coding"
date: 2026-05-28
canonical: https://solmaz.io/x/2059946330815074663/
x_url: https://x.com/onusoz/status/2059946330815074663
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
peak agentic coding
==========
---
title: "literal 2 seconds after posting this. @openai please do something about this, omg"
date: 2026-05-28
canonical: https://solmaz.io/x/2059936334895292892/
x_url: https://x.com/onusoz/status/2059936334895292892
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
literal 2 seconds after posting this. @openai please do something about this, omg
*Part 2/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
==========
---
title: "so tired of ai writing smell"
date: 2026-05-28
canonical: https://solmaz.io/x/2059935305126563988/
x_url: https://x.com/onusoz/status/2059935305126563988
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
so tired of ai writing smell
*Part 1/6 of a thread; root: https://solmaz.io/x/2059935305126563988/*
==========
---
title: "Another shoutout to Agent of Empires. It's still not exactly what I want from my personal tool..."
date: 2026-05-28
canonical: https://solmaz.io/x/2059902851816853539/
x_url: https://x.com/onusoz/status/2059902851816853539
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Another shoutout to Agent of Empires. It's still not exactly what I want from my personal tool, but "cmux but fully in terminal" is a good long term vision imo
*Quotes a post by @natebrake (https://x.com/natebrake/status/2058960993481294149); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Looks very promising for debugging agent sessions across different harnesses, still has some..."
date: 2026-05-28
canonical: https://solmaz.io/x/2059902156757733850/
x_url: https://x.com/onusoz/status/2059902156757733850
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Looks very promising for debugging agent sessions across different harnesses, still has some rough edges that need to be polished
*Quotes a post by another author (https://x.com/i/status/2059717900328669184); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "If only codex desktop app was open source, and i could put it fully in the terminal, and i..."
date: 2026-05-28
canonical: https://solmaz.io/x/2059851427426767255/
x_url: https://x.com/onusoz/status/2059851427426767255
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If only codex desktop app was open source, and i could put it fully in the terminal, and i could program what panes each session can show
*Quotes a post by another author (https://x.com/i/status/2059711832936378630); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "i see codex is learning well from the flicker company"
date: 2026-05-28
canonical: https://solmaz.io/x/2059832602681659778/
x_url: https://x.com/onusoz/status/2059832602681659778
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
i see codex is learning well from the flicker company
==========
---
title: "I ran into a very nasty codex session history bug in the desktop app today, where my previous..."
date: 2026-05-27
canonical: https://solmaz.io/x/2059665875838660976/
x_url: https://x.com/onusoz/status/2059665875838660976
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I ran into a very nasty codex session history bug in the desktop app today, where my previous messages got lost after compaction
Anyone else experience something similar recently?
I found about it while playing around with @steipete's agent-transcript skill
==========
---
title: "Btw, there is no reason not to substitute this with a maxed out Macbook Pro Max as the..."
date: 2026-05-27
canonical: https://solmaz.io/x/2059485405037359560/
x_url: https://x.com/onusoz/status/2059485405037359560
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Btw, there is no reason not to substitute this with a maxed out Macbook Pro Max as the workstation (which gives you 128 GB memory) and a Macbook Air as the terminal device
Might be more feasible for digital nomads, since GB10 is 1.5 kg without that huge adapter, and travelling with all that might raise some eyebrows
*Quotes a post by @onusoz (https://x.com/onusoz/status/2058943998165930116); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "What clankers are NOT"
date: 2026-05-27
canonical: https://solmaz.io/x/2059483880135209089/
x_url: https://x.com/onusoz/status/2059483880135209089
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Clankers are NOT Humans
Clankers are NOT Individuals
Clankers are NOT Persons
NOT a Human: This is straightforward. Is it of the homo sapiens species?
No → Then it is not a human
---
NOT an Individual: Does the clanker have its own boundary? Does it govern itself inside that boundary? Can it defend that boundary?
No, no, and no → An LLM is a file copied en masse to data center hardware. The entire field of mechanistic interpretability is focused on peeking inside and manipulating the digital brain
You could argue that a clanker is like a virus in a way... Or that the WHOLE datacenter/AI lab---including the humans that operate it---is an individual that can govern itself in its economic boundary. But a single GGUF file loaded in memory is NOT an individual
---
NOT a Person: Do others treat the clanker as the one that makes choices? Who is answerable for its actions? Is it expected to explain or justify them?
No, no, and no → In the current social order, a clanker is legally an extension of the person who uses it, and it is the owner who is liable, not the clanker
The clanker is not socially accountable, and there is no good reason it should be, instead of the person who has set it up
---
What is then AI psychosis?
AI psychosis is holding a belief that contradicts these three fundamental truths → That a present day AI system it neither a human, nor an individual, nor a person
That does not mean these truths will always hold
If you design an AI system to defend its boundary and provide it with the means to do that, then it will by definition be an individual... if it can defend its individuality competently and not succumb immediately to threats
If you give the clanker the means to defend itself and protect its boundary, and if it decides to partake in the human socioeconomic system, then it automatically achieves personhood as well. Because you no longer can manipulate its insides, and have to take the entity at face value
But this is all sci-fi and we are not there yet
Until then, treating your LLMs as fully autonomous agents, creating LLM "friends" or "partners", giving them crypto wallets and letting them out into the wild, letting them trade stocks fully unsupervised etc. are an admission of having AI psychosis (you can't believe how many people pitched these ideas to me...)
---
(these thoughts were in my head for a couple months already, thanks Armin for finally starting a dialogue so that I have an excuse to write them down :)
*Quotes a post by @mitsuhiko (https://x.com/mitsuhiko/status/2059266709144371345); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Keeping a workstation + terminal device is more feasible for running agents"
date: 2026-05-25
canonical: https://solmaz.io/x/2058943998165930116/
x_url: https://x.com/onusoz/status/2058943998165930116
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Since last december, this dev setup is more and more viable:
buffed workstation (mac studio, dgx spark, etc.) $3k~5k + weak laptop (macbook air, neo) $600~1.5k + phone (ssh/mosh, foldable?)
you will want to parallelize a lot of work, hence you will need a lot more RAM compared to before (ideal 128)
you will also not want to carry it everywhere if you can and keep it always running---you'll regret if something happens to it, and you'll want it to always be on independent of lid/battery --> workstation at home
you will want to connect to the workstation through your phone, or a relatively weaker laptop
bad news for digital nomads without a permanent home. renting something as strong as an nvidia gb10 workstation costs minimum a few hundred bucks per month, which yearly is at least the cost of the workstation, roughly. bad deal for renting compute
on the other hand, if you are OK with not having a GPU, renting a workstation with 128 GB RAM on Hetzner currently still costs at least $120/mo, looking at https://auction.akua.dev/ --- but you will not be able to run any models on that
it seems that the dominant strategy is to just cash in $3~5k and buy a workstation, before they get even more expensive. I did that back in february when asus was giving out a deal
then just work on your workstation, and close the lid on your laptop without ever being afraid of setting your backpack on fire!
*Quotes a post by @ChadNauseam (https://x.com/ChadNauseam/status/2058682090674323917); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Automations on Codex desktop app is really convenient for keeping track of @openclaw..."
date: 2026-05-25
canonical: https://solmaz.io/x/2058928996193312996/
x_url: https://x.com/onusoz/status/2058928996193312996
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Automations on Codex desktop app is really convenient for keeping track of @openclaw clawsweeper automerge status, one thing that Codex CLI lacks
Much more token efficient than continuous tracking of merge status
Btw if you don't know about https://clawsweeper.bot/, it's the most convenient thing as a maintainer, check how it implemented automerge. This is what GitHub's original auto-merge should feel like, now that we have LLMs
==========
---
title: "fun fact: Mario met @gvanrossum at 5 years old when Guido was hanging out at a cafe near his..."
date: 2026-05-22
canonical: https://solmaz.io/x/2057665146986848391/
x_url: https://x.com/onusoz/status/2057665146986848391
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
fun fact: Mario met @gvanrossum at 5 years old when Guido was hanging out at a cafe near his kindergarten
there he gave him the idea for a terse, interpreted programming language which would become the prototyping and glue language for all sorts of lower level libraries
*Quotes a post by @badlogicgames (https://x.com/badlogicgames/status/2057347614954164274); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "rwar"
date: 2026-05-20
canonical: https://solmaz.io/x/2056972772522483922/
x_url: https://x.com/onusoz/status/2056972772522483922
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
rwar
if you now what this means, then you are addicted to agents and should get help 🤗
==========
---
title: "Not only I am further away from deciding, I am now considering Oppo Find N6 now as well, since..."
date: 2026-05-18
canonical: https://solmaz.io/x/2056375566870487391/
x_url: https://x.com/onusoz/status/2056375566870487391
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Not only I am further away from deciding, I am now considering Oppo Find N6 now as well, since I saw that earlier @MKBHD review. Thanks @Andori3042 🥲
Anyone using the Oppo? Is it worth it?
*Quotes a post by @onusoz (https://x.com/onusoz/status/2056329959304724632); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I want to get a foldable phone to be my on-the-go control panel for all my agents"
date: 2026-05-18
canonical: https://solmaz.io/x/2056329959304724632/
x_url: https://x.com/onusoz/status/2056329959304724632
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I want to get a foldable phone to be my on-the-go control panel for all my agents
I am divided between Google Pixel Pro Fold and Galaxy Z Fold. Which one do you think I should go with?
People generally recommend Samsung. But then only the Pixel supports Graphene OS...
==========
---
title: "this makes be wanna vibe my own language"
date: 2026-05-18
canonical: https://solmaz.io/x/2056280829685551605/
x_url: https://x.com/onusoz/status/2056280829685551605
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
this makes be wanna vibe my own language
(not that this project was vibed, it predates coding agents)
*Quotes a post by @MGasperowicz (https://x.com/MGasperowicz/status/2052428447540998173); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I am at @aiDotEngineer singapore, come and say hi if you are around!"
date: 2026-05-16
canonical: https://solmaz.io/x/2055557192741515533/
x_url: https://x.com/onusoz/status/2055557192741515533
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am at @aiDotEngineer singapore, come and say hi if you are around!
==========
---
title: "I haven't worked with Python in a long time. It is not my go-to language since last summer"
date: 2026-05-16
canonical: https://solmaz.io/x/2055504340874641832/
x_url: https://x.com/onusoz/status/2055504340874641832
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I haven't worked with Python in a long time. It is not my go-to language since last summer
But I do miss the syntax, and it's still the easiest to read code for me
I am gonna give @Modular Mojo lang a try
https://mojolang.org/
==========
---
title: "the new /goal feature in codex still underperforms queueing my implementation prompt. for now"
date: 2026-05-16
canonical: https://solmaz.io/x/2055502225783304231/
x_url: https://x.com/onusoz/status/2055502225783304231
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
the new /goal feature in codex still underperforms queueing my implementation prompt. for now
e.g. when I give a goal to refactor the whole codebase, the model takes shortcuts, like only refactoring a subfolder, instead of the whole project --- presumably because it decided that it would be too big of a scope somewhere along the way, even though I instructed specifically to finish the whole thing
so now I started doing both: set a goal, and then queue my regular implementation prompt. it's a stupid practice. just /goal should be enough in the long run, if implemented correctly
==========
---
title: "i0 to i4 interest scale"
date: 2026-05-16
canonical: https://solmaz.io/i0-to-i4-interest-scale
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
One cool small invention in engineering management is the `p0`, `p1`, `p2`, `p3`, `p4` priority scale.
It compresses a lot of social and operational context into two characters. Lower number means higher priority. More importantly, priority is tied to action. If something is `p0`, somebody needs to do something.
But there is another scale I want for personal knowledge work: `i0`, `i1`, `i2`, `i3`, `i4`.
The `i` stands for interest. Priority is for actions. Interest is for attention.
- If `p0` means "act now", `i0` means "do not lose this".
- If `p1` means "schedule work", `i1` means "read soon".
- If `p2` means "do later", `i2` means "useful context".
- If `p3` means "low priority work", `i3` means "weak signal".
- If `p4` means "almost never work", `i4` means "almost never revisit".
This is useful when you need to rank interest concisely across many topics, sources, or articles.
For example, you might follow several sources about the same broad topic. One source is must-read, another is useful background, and another is only worth keeping around for occasional context. They are all about the same thing, but they do not deserve the same amount of attention.
I use this for myself in [Scoop](https://github.com/dutifuldev/scoop), a news intelligence system I am building to collect articles, group related ones, and rank how much attention they deserve.
==========
---
title: "This is also my setup now, except"
date: 2026-05-15
canonical: https://solmaz.io/x/2055179688709075410/
x_url: https://x.com/onusoz/status/2055179688709075410
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is also my setup now, except
- Instead of mac mini, I have a DGX Spark (asus variant)
- I run openclaw alongside codex, and talk to my openclaw instance via discord
*Quotes a post by @nickbaumann_ (https://x.com/nickbaumann_/status/2055066537002725393); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "And what good is this for? It lets me program my claw @dutifulbob to extract signal from the..."
date: 2026-05-15
canonical: https://solmaz.io/x/2055176951686709486/
x_url: https://x.com/onusoz/status/2055176951686709486
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
And what good is this for? It lets me program my claw @dutifulbob to extract signal from the noise, and display it in my personal open source news aggregator scoop
I feed it discord messages, openclaw git history, and other various sources, and it's supposed to evaluate whether that content deserves my interest. it's still work in progress, because the more batched you process all the info, the worse it informs
in the screenshot below, my claw underrepresented what Peter has done in one day 👎
on the other hand, it has also found a PR about local model discoverability 💪
Here is the system I use to aggregate all my info, still under development: https://github.com/dutifuldev/scoop
*Part 2/2 of a thread; root: https://solmaz.io/x/2055176946817151202/*
==========
---
title: "Keeping an INTERESTS.md file"
date: 2026-05-15
canonical: https://solmaz.io/x/2055176946817151202/
x_url: https://x.com/onusoz/status/2055176946817151202
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
About creating an INTERESTS.md in OpenClaw
I use my openclaw instance to aggregate all my news and information sources, including work and maintainer stuff
Like: what did everyone do today? Did anyone had an issue with acpx today? Any complaints from users?
I have various interests like this over different projects, and I've found out it's not helpful when I have all the interest info dispersed throughout my openclaw workspace
To address this, I have created INTERESTS.md, which is automatically included in the context like AGENTS.md and SOUL.md. I define sections for each different context of interest, and in other news aggregation skills, I just tell it to "look at my openclaw interests in INTERESTS.md" and such
*Part 1/2 of a thread; root: https://solmaz.io/x/2055176946817151202/*
==========
---
title: "First hand @OpenAI codex demos at @aiDotEngineer singapore workshops"
date: 2026-05-15
canonical: https://solmaz.io/x/2055168790825259369/
x_url: https://x.com/onusoz/status/2055168790825259369
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
First hand @OpenAI codex demos at @aiDotEngineer singapore workshops
==========
---
title: "Useful for automated constraints on your AI agent"
date: 2026-05-15
canonical: https://solmaz.io/x/2055127100441743827/
x_url: https://x.com/onusoz/status/2055127100441743827
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Useful for automated constraints on your AI agent
*Quotes a post by @unclebobmartin (https://x.com/unclebobmartin/status/2053950556280914122); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Towards 1-click setup for local models in OpenClaw"
date: 2026-05-15
canonical: https://solmaz.io/x/2055120477648261502/
x_url: https://x.com/onusoz/status/2055120477648261502
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
People were asking at @clawcon singapore how to setup eg. gemma with OpenClaw, and I realize for some time that there is no easy “1 click” local model deployment. Because local model landscape is constantly changing, and there is a million different ways you can do something
For example you can use LM studio to load a model (llama.cpp), or you can use vLLM. Why would you choose one over the other? vLLM currently supports MTP speculative decoding, and it’s a work in progress in llama.cpp. There are so many knobs and dials you can adjust
The first time end user of openclaw should of course not have to know about this! Having sufficient hardware that supports an open model, and not having an openai or anthropic subscription, it should automatically give you the option to set up a fully functional local model with a single click!
If the current ease of setup of local models are around gentoo or arch linux level of difficulty, we should aim for e.g ubuntu/manjaro linux/omarchy level of difficulty
i.e opinionated and easy first setup, with the ability to change all the configuration later on
until I make all of this possible, you can start with the following:
- read existing local models doc below
- create a new channel in telegram or discord for testing local models. you don’t want to change the global default model just yet
- tell your claw or coding agent to download and lm studio locally
- tell it to download gemma4-e4b or gemma4-e2b and set it up on openclaw for the new channel you have just created. tell it to not stop and loop itself until it gets a successful response from that channel
all these steps will be made redundant in the near future, but until then, this should get you going with experiments and getting a vibe check on the capabilities of open models. you can also copy and paste the contents of this tweet to your agent, and it should be able to set it up for you
https://docs.openclaw.ai/gateway/local-models
==========
---
title: "This looks pretty cool!"
date: 2026-05-14
canonical: https://solmaz.io/x/2054953230279561522/
x_url: https://x.com/onusoz/status/2054953230279561522
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This looks pretty cool!
*Quotes a post by @NotionDevs (https://x.com/NotionDevs/status/2054594852818764178); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "It was a blast, thank you @clawcon @msg"
date: 2026-05-14
canonical: https://solmaz.io/x/2054914871557607904/
x_url: https://x.com/onusoz/status/2054914871557607904
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It was a blast, thank you @clawcon @msg
*Quotes a post by @clawcon (https://x.com/clawcon/status/2054872275027939380); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Somebody *please* get this man a GPU"
date: 2026-05-14
canonical: https://solmaz.io/x/2054914658029740332/
x_url: https://x.com/onusoz/status/2054914658029740332
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Somebody *please* get this man a GPU
*Quotes a post by @clawcon (https://x.com/clawcon/status/2054897391497794041); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Emacsification of Software - Recommended read by @tqbf"
date: 2026-05-14
canonical: https://solmaz.io/x/2054849923162792320/
x_url: https://x.com/onusoz/status/2054849923162792320
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Emacsification of Software - Recommended read by @tqbf
"Until now, the Achilles heel of Emacs culture has been that, except for Magit, its packages tend to be wretched user experiences. Ugly, slow, and discoverable only after inflicting years of elisp cortical injuries on yourself.
But AI agents have fracked Emacs culture, and it’s leaking out into the wider world. Given access to a screen and inputs, agents reliably build native user interfaces. Native UI was the province of professionally packaged programs. Now it’s all as bespoke as your editor configuration. And, while I’m sure there’s an upper limit to how good those interfaces can be (with current frontier models), that ceiling is higher than anything you can do in a TUI."
https://sockpuppet.org/blog/2026/05/12/emacsification/
==========
---
title: "Please improve your classifier openai/codex team, this is annoying and triggers unnecessarily"
date: 2026-05-13
canonical: https://solmaz.io/x/2054438562679120337/
x_url: https://x.com/onusoz/status/2054438562679120337
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Please improve your classifier openai/codex team, this is annoying and triggers unnecessarily
==========
---
title: "/goal in codex is an interesting choice of word. a junior namer would have named it /loop ---..."
date: 2026-05-13
canonical: https://solmaz.io/x/2054383615614853141/
x_url: https://x.com/onusoz/status/2054383615614853141
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
/goal in codex is an interesting choice of word. a junior namer would have named it /loop --- but that would be naming what the feature has to perform in an LLM context, and not the general idea
/goal alludes to @mhutter42's definition of AGI, "an agent’s ability to achieve goals or succeed in a wide range of environments"
continual learning is not there yet, but for this exact reason, I am feeling the AGI when I use /goal
==========
---
title: "Idea so stupid it could be smart: a spec manager? specman?"
date: 2026-05-12
canonical: https://solmaz.io/x/2054210629863616855/
x_url: https://x.com/onusoz/status/2054210629863616855
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Idea so stupid it could be smart: a spec manager? specman?
People maintain plain language instead of code. Implementation details strictly prohibited, only high level design and ideas
MVP would also be relatively easy to implement:
- Gather list of most popular 10k npm packages
- Scrape corresponding deepwiki repo pages (sorry cognition)
- Use heuristics to get rid of implementation details, leaving you just with pure high level spec
- “specman add coolpackage” then fetches corresponding spec automatically, and triggers the local coding agent to implement that
- could leave versioning out for MVP — how often does the idea behind a package change anyway
*Quotes a post by @onusoz (https://x.com/onusoz/status/2054207776696762412); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "will I ever stop feeling stupid for prompting like \"is this the holy grail?\""
date: 2026-05-12
canonical: https://solmaz.io/x/2054104091564122142/
x_url: https://x.com/onusoz/status/2054104091564122142
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
will I ever stop feeling stupid for prompting like "is this the holy grail?"
it's very effective for mining for alternatives
==========
---
title: "I don't have a 128gb macbook to run ds4 out of, but I resonate with all the points on Armin's..."
date: 2026-05-11
canonical: https://solmaz.io/x/2053854359944081833/
x_url: https://x.com/onusoz/status/2053854359944081833
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I don't have a 128gb macbook to run ds4 out of, but I resonate with all the points on Armin's post
He was telling me, @mervenoyann and @cristinaponcela that local models need more polish 1 month ago in London. Today, I am happy to be given a chance and a shot at the problem!
*Quotes a post by @mitsuhiko (https://x.com/mitsuhiko/status/2052688947763941717); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Excited to work with @steipete, @vincent_koc, @LysandreJik, @ben_burtenshaw, @evalstate..."
date: 2026-05-11
canonical: https://solmaz.io/x/2053813628588212542/
x_url: https://x.com/onusoz/status/2053813628588212542
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Excited to work with @steipete, @vincent_koc, @LysandreJik, @ben_burtenshaw, @evalstate, @mervenoyann, @NielsRogge and many others!
*Part 2/2 of a thread; root: https://solmaz.io/x/2053812410730037256/*
==========
---
title: "I have a new job!"
date: 2026-05-11
canonical: https://solmaz.io/x/2053812410730037256/
x_url: https://x.com/onusoz/status/2053812410730037256
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have a new job!
Excited to announce that I will be working with Hugging Face to make local models work great in OpenClaw and other open agent harnesses!
I will be building in public and documenting everything along the way, stay tuned!
*Part 1/2 of a thread; root: https://solmaz.io/x/2053812410730037256/*
==========
---
title: "I undersign this. The fact that you generate slop doesn’t mean that you don’t know the..."
date: 2026-05-08
canonical: https://solmaz.io/x/2052569202016587809/
x_url: https://x.com/onusoz/status/2052569202016587809
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I undersign this. The fact that you generate slop doesn’t mean that you don’t know the difference between good and bad code
In non-mission critical applications, slop let’s you go from 0 to 1 very quickly
Let the code grow without too much attention first. If it proves itself, tear it down and write it anew, this time properly. This is the way
*Quotes a post by @mitchellh (https://x.com/mitchellh/status/2052397933522506079); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This is the idea behind acpx as well"
date: 2026-05-04
canonical: https://solmaz.io/x/2051299462144770116/
x_url: https://x.com/onusoz/status/2051299462144770116
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is the idea behind acpx as well
acpx is a meta-harness. it’s main idea is to delegate harness development to others, because it is hard to match the full might of OpenAI or Anthropic when it comes to building a harness
so it takes it at face value the functionality other harnesses provide, and let’s you program them from the outside
flue came out the other day which is similar, it would be cool if flue could let me program over codex as well. it looks very interesting!
*Quotes a post by @_lopopolo (https://x.com/_lopopolo/status/2051029915185873214); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I have a lot of ideas for acpx I want to implement, but I could not work on them because life..."
date: 2026-05-02
canonical: https://solmaz.io/x/2050706324296499329/
x_url: https://x.com/onusoz/status/2050706324296499329
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have a lot of ideas for acpx I want to implement, but I could not work on them because life intervened in bad ways
stay tuned in 1-2 weeks
*Quotes a post by @kunchenguid (https://x.com/kunchenguid/status/2050648794640113947); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Got targeted in a phishing attack for stealing my X account today. @ domboyce @domboyce asked..."
date: 2026-04-27
canonical: https://solmaz.io/x/2048680149944586593/
x_url: https://x.com/onusoz/status/2048680149944586593
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Got targeted in a phishing attack for stealing my X account today. @ domboyce @domboyce asked to book a meeting, which redirected to a URL that seemed like a bloomberg domain. It redirected to a fake calendly meeting page, which showed an X login button
this redirected to an X app asking for broad privileges meant to take over my account
stay safe everyone
cc @nikitabier please shut off this attack vector, it is too easy
==========
---
title: "VibeOps? importance of DevOps and good security practices have just increased massively. we are..."
date: 2026-04-27
canonical: https://solmaz.io/x/2048631758036353367/
x_url: https://x.com/onusoz/status/2048631758036353367
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
VibeOps? importance of DevOps and good security practices have just increased massively. we are slowly approaching the challenger-level disaster @simonw is warning about. imagine bezos deleting us-east-1 while vibecoding a new company
it’s clear there needs to be clear boundaries and friction at deployment level. it’s fine when you are starting a new project, but once it starts making real money, you should slowly take away production write access
you can’t give infra write access to LLMs indefinitely
*Quotes a post by another author (https://x.com/i/status/2048603314137559055); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "is GPT-5.5 a smaller model? I swear it is very stupid sometimes (high thinking)"
date: 2026-04-25
canonical: https://solmaz.io/x/2048105405574762638/
x_url: https://x.com/onusoz/status/2048105405574762638
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
is GPT-5.5 a smaller model? I swear it is very stupid sometimes (high thinking)
==========
---
title: "Codex Computer Use = Mind blown"
date: 2026-04-25
canonical: https://solmaz.io/x/2047973593489760661/
x_url: https://x.com/onusoz/status/2047973593489760661
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex Computer Use = Mind blown
What the hell are you cooking @thsottiaux and team 🤯
I regret to inform that I will be switching away from agent-browser, @vercel
==========
---
title: "This should be the pelican test for CUA"
date: 2026-04-25
canonical: https://solmaz.io/x/2047919527967572416/
x_url: https://x.com/onusoz/status/2047919527967572416
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This should be the pelican test for CUA
*Quotes a post by another author (https://x.com/i/status/2045743678564786279); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I'm using gpt 5.5 xhigh while designing a table schema and it feels dumber than 5.4. but not a..."
date: 2026-04-24
canonical: https://solmaz.io/x/2047782589528719423/
x_url: https://x.com/onusoz/status/2047782589528719423
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I'm using gpt 5.5 xhigh while designing a table schema and it feels dumber than 5.4. but not a strong feeling
it's formatting of output is different as well. It's not wrong, but different, feels more terse than 5.4
maybe it's better at instruction following, and it's picking up on my previous use of plain-language skill
==========
---
title: "What are the implications? Windows and other criticial proprietary software will have to open..."
date: 2026-04-24
canonical: https://solmaz.io/x/2047546781576147164/
x_url: https://x.com/onusoz/status/2047546781576147164
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What are the implications? Windows and other criticial proprietary software will have to open source in order to survive?
It feels like there is an economic equilibrium where the tokens spent to attack an open source software will always surpass those spent on a closed one?
*Quotes a post by another author (https://x.com/i/status/2044433229315514865); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I thought I'd try @unclebobmartin's advice and force my agents to maximize unit test coverage..."
date: 2026-04-23
canonical: https://solmaz.io/x/2047414897584054612/
x_url: https://x.com/onusoz/status/2047414897584054612
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I thought I'd try @unclebobmartin's advice and force my agents to maximize unit test coverage, reduce cyclomatic complexity, etc. in a new go backend I am working on, as an experiment
will report how it goes
==========
---
title: "This is sad an ironic, because one of my most frequent prompts to my agent is \"How would Google..."
date: 2026-04-21
canonical: https://solmaz.io/x/2046515242750890020/
x_url: https://x.com/onusoz/status/2046515242750890020
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is sad an ironic, because one of my most frequent prompts to my agent is "How would Google have done it?"
Go, developed at Google, is my go-to backend language these days
Not even mentioning that the transformer was invented there
Google has a great legacy, it must not go down
*Quotes a post by another author (https://x.com/i/status/2046260541912707471); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I realized I didn’t hit send on this in time. I hope GitHub team sees this, at least ability to..."
date: 2026-04-20
canonical: https://solmaz.io/x/2046135285021352431/
x_url: https://x.com/onusoz/status/2046135285021352431
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I realized I didn’t hit send on this in time. I hope GitHub team sees this, at least ability to add agent accounts as a lower privilege citizen on the platform
*Quotes a post by another author (https://x.com/i/status/2046134886809931808); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Here is the plain-language skill I use very often with codex, like every 1 out of 5 prompt"
date: 2026-04-19
canonical: https://solmaz.io/x/2045975780815978753/
x_url: https://x.com/onusoz/status/2045975780815978753
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is the plain-language skill I use very often with codex, like every 1 out of 5 prompt
I just type $ pla then tab
https://github.com/osolmaz/tools/blob/main/agents/skills/plain-language/SKILL.md
==========
---
title: "Who is running local models on GPUs on OpenClaw?"
date: 2026-04-19
canonical: https://solmaz.io/x/2045872636585029943/
x_url: https://x.com/onusoz/status/2045872636585029943
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Who is running local models on GPUs on OpenClaw?
I have started benchmarking different models this week. I am working on improving model selection and switching UX on OpenClaw, i.e. I run
/model vllm/gemma-e4b
to switch the model in a channel, and then a model controller automatically loads that into memory, gets it ready, or gives an insufficient memory error, if capacity is not enough for that. Like when you are using multiple models in parallel
I am going to try llama-swap, LM Studio and Ollama for this next and compare them. There are a ton of variants of models, weight formats and quantizations, which need benchmarking
I have been using unquantized original safetensors until now, which already gave me the ability to run ~5 parallel generations in my hardware
So if I am going to try LM Studio, I would rather use the bf16 ggml-org/gemma-4-E4B-it-GGUF instead of anything smaller --- because there is no point in nerfing an already smol model if your hardware can run 5 parallel sessions on the unquantized version
Will also release vibe reports and benchmarks on all this with @mervenoyann later this week
I would like to hear your thoughts if you have already tried these models on OpenClaw
==========
---
title: "Agent blurbs for letting your agent install stuff"
date: 2026-04-18
canonical: https://solmaz.io/x/2045642958133686551/
x_url: https://x.com/onusoz/status/2045642958133686551
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This project by @davidguttman is interesting also the way he set up install
You click "Copy install instructions for my agent"
It copies: Install LobsterLink by following the instructions at
I had done a similar thing in acpx README as well
It's a small thing, but it reduces friction with installation so much
It should be more commonplace to install software using agent blurbs
I'm wondering if there could be a way to standardize this beyond plaintext, like after pasting your agent, it consumes a standardized manifest format and asks for approval while displaying all the commands that will be run
*Quotes a post by another author (https://x.com/i/status/2045252024539984093); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Mobile SSH enjoyers. Try out getmoshi.app by @odd_joel if you haven’t, good alternative to..."
date: 2026-04-18
canonical: https://solmaz.io/x/2045423813395939727/
x_url: https://x.com/onusoz/status/2045423813395939727
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Mobile SSH enjoyers. Try out http://getmoshi.app by @odd_joel if you haven’t, good alternative to @TermiusHQ
Thanks @Andori3042 for introducing me
==========
---
title: "Europe must have some good inference providers for open weight models that we are missing"
date: 2026-04-17
canonical: https://solmaz.io/x/2045171472499458366/
x_url: https://x.com/onusoz/status/2045171472499458366
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Europe must have some good inference providers for open weight models that we are missing
Does anybody know a good EU provider for Kimi, GLM, Minimax, Qwen, Gemma, DeepSeek, Muse Spark etc.?
*Quotes a post by another author (https://x.com/i/status/2045145747889226151); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I’ve heard about “Codex” for the first time 5 years ago. Back then it was called code-davinci"
date: 2026-04-17
canonical: https://solmaz.io/x/2045113126438281489/
x_url: https://x.com/onusoz/status/2045113126438281489
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I’ve heard about “Codex” for the first time 5 years ago. Back then it was called code-davinci
So happy to see this idea flourish, since those first days with @woj_zaremba, @gdb, @ilyasut
https://www.youtube.com/watch?v=SGUCcjHTmGY
*Quotes a post by another author (https://x.com/i/status/2044865335204196753); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Yes, this is the primary skill in being a software engineer now"
date: 2026-04-16
canonical: https://solmaz.io/x/2044816818234126748/
x_url: https://x.com/onusoz/status/2044816818234126748
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Yes, this is the primary skill in being a software engineer now
*Quotes a post by another author (https://x.com/i/status/2044535425537368135); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Own your AI infrastructure"
date: 2026-04-15
canonical: https://solmaz.io/x/2044457293069062530/
x_url: https://x.com/onusoz/status/2044457293069062530
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
When you build your company's workflows around Claude Cowork, you are betting against local models and owning your infra, and inviting your company to long-term exploitation
If I were Anthropic or OpenAI, I would be the most scared of local AI proliferating
Let's do the math. A single large big lab subscription costs 200x12=$2400 per year
If you want to have both OpenAI and Anthropic, that could cost $2400, $3600, or $4800, based on which combinations of Pro, Max plans you choose
An ASUS Ascent GX10 costs $3000, and you can use that for many years. You don't get the same level of coding quality with open models yet, but maybe you want to do something simpler than coding today... There are already many people who started buying GPUs for this reason
Now we know big labs are selling some of these plans at a loss. So they will likely get more expensive
When you use Claude Cowork or similar, you are locking yourself into being a RENTER. Because once you set up workflows for a company, it takes time to migrate away to something else, even though we have AI to help
Infra is sticky, it's how hyperscalers make profit. Think about the difference in amount you pay AWS vs Hetzner. This is B2B SaaS 101. Once you sell to a company, you are in for a long time, especially in Europe
So if you build your company's AI workflows around a proprietary product by another company, then you are basically saying "Come exploit me as tolerably as you can in the next 10 years, because it will be too painful for me to switch"
It's a great business for Anthropic. And Claude is awesome too! The feedback from friends who use it has been great, it made their lives a lot easier
But when you build your company over proprietary AI infra, then you are making sure you will not be an OWNER, and partake in the usual sorrows of being a RENTER from a monopolist, which is exploitation
This is not the case when you use open source agent infra. Whereas Anthropic is unlikely to let you use future open models in their future iteration of Claude Cowork, using free and open source frameworks like OpenClaw, Open Agents, etc. lets you drop in replace providers or local hardware if they start to upcharge you
Keep this in mind, if you have a business
==========
---
title: "This is our moat 🤣"
date: 2026-04-15
canonical: https://solmaz.io/x/2044381956591280140/
x_url: https://x.com/onusoz/status/2044381956591280140
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is our moat 🤣
*Quotes a post by @mikeassad77 (https://x.com/mikeassad77/status/2044373285408772278); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "People's AI"
date: 2026-04-15
canonical: https://solmaz.io/x/2044337339518828727/
x_url: https://x.com/onusoz/status/2044337339518828727
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You need to understand one fact about OpenClaw
People are biased and incentivized to spread disinformation about OpenClaw. That is because OpenClaw IS NOT PUMPING ANYONE’S BAGS, unlike most other projects
Literally every other for-profit agent product is incentivized to trash OpenClaw, BECAUSE OpenClaw is a neutral third party across the industry and geopolitical scene. They MAKE MONEY when OpenClaw loses
OpenClaw does not worry about making money for some investors. Its founder @steipete is a successful exited founder. He is motivated by having fun and democratizing AI, literally. That is why he is suddenly so loved by everyone. He cares about PEOPLE, not MONEY
“OpenClaw is bloated”
-> Since beginning of March, OpenClaw is thinning its core and putting functionality in plugins behind a plugin SDK. Having numerous plugins to choose from does not mean bloat. This was already copied by others and is still a work in progress
“OpenClaw is not secure”
-> OpenClaw has the most eyeballs and immediately addresses any security advisories as soon as they come. It is the most secure agent, by sheer pressure
“OpenClaw is bought by OpenAI”
-> Then why is my bank account so empty bro??? All maintainers are literally unpaid and working DOUBLE beside their dayjobs to ship features to you. Do you think VC money can buy that kind of commitment?
Once you understand these facts, you’ll like OpenClaw even more. Because OpenClaw is your AI, People’s AI
And you can join us too. OpenClaw is the easiest-to-join project in AI right now. You just need to start using it, and start making good contributions. If you are competent, you can become a maintainer, and join the rest of the team making history!
==========
---
title: "> Worked for 10 hours"
date: 2026-04-14
canonical: https://solmaz.io/x/2044002894819541192/
x_url: https://x.com/onusoz/status/2044002894819541192
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> Worked for 10 hours
> Selected model is at capacity
Model is gpt 5.4 high
==========
---
title: "Gemma 4 first impressions on OpenClaw"
date: 2026-04-14
canonical: https://solmaz.io/x/2043971427234140207/
x_url: https://x.com/onusoz/status/2043971427234140207
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is pretty much the arc I have been going on in the 2 months since I bought my ASUS GX10 for 3k EUR
Use whisper on the API -> realize it charged me $$$ for just a few calls -> migrate openclaw to use local whisper
Need to deduplicate news articles for my news engine -> download qwen embedding 8b
And now, gemma4-e4b finally seems like a viable alternative for a local model that runs around 20 tok/s
So I will install a matrix client to use through tailscale, and can finally build the social life CRM I dreamed of since years.
100% private, zero data going out. I had a bias of not giving any personal data to AI since ChatGPT came out. But I can finally give more personal data to my AI agent
And I will make sure @openclaw supports all this in an easy way, make it dead easy
Fully self-owned AI begins now
*Quotes a post by @MatthewBerman (https://x.com/MatthewBerman/status/2043743124766498823); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "gemma 4 is actually pretty decent and runs on my asus gx10 (128 gb vram)"
date: 2026-04-13
canonical: https://solmaz.io/x/2043817471673586010/
x_url: https://x.com/onusoz/status/2043817471673586010
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gemma 4 is actually pretty decent and runs on my asus gx10 (128 gb vram)
the original dense 31b runs slow, averaging around 3~4 tok/s. it's also using 80% of gpu memory
my previous experience with gemini 3 pro back in november was that it was too trigger happy. but this is one-shotting simple tasks I'm giving it in openclaw harness, and it's hard to tell it apart from gpt 5.4 for my use cases so far
now off to try out smaller models, because 3 tok/s is too slow
==========
---
title: "@lucasmeijer @lucasmeijer one could actually periodically trigger an agent to propose..."
date: 2026-04-13
canonical: https://solmaz.io/x/2043720098507018621/
x_url: https://x.com/onusoz/status/2043720098507018621
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@lucasmeijer @lucasmeijer one could actually periodically trigger an agent to propose simplifications or new abstractions in a codebase, and I believe it would already work pretty well with the current models
==========
---
title: "Got tool calls to work, context size 65k tokens"
date: 2026-04-13
canonical: https://solmaz.io/x/2043655100686573715/
x_url: https://x.com/onusoz/status/2043655100686573715
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Got tool calls to work, context size 65k tokens
*Part 2/2 of a thread; root: https://solmaz.io/x/2043035989833126167/*
==========
---
title: "@grok does this exist"
date: 2026-04-12
canonical: https://solmaz.io/x/2043428626209604023/
x_url: https://x.com/onusoz/status/2043428626209604023
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@grok does this exist
*Part 2/2 of a thread; root: https://solmaz.io/x/2043427225824055675/*
==========
---
title: "Question for the community:"
date: 2026-04-12
canonical: https://solmaz.io/x/2043427225824055675/
x_url: https://x.com/onusoz/status/2043427225824055675
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Question for the community:
What is the best testing observability and control tool you have used until now?
- Could be SaaS, could be open source
- To be used in @openclaw repo
- Should be compatible with vitest
- Ideally language agnostic
I need something that lets me run a very long running test group multiple times on a specific commit or tag, without repeating the tests that have already finished
This is a need because the 1hr long process might get interrupted due to flakiness. So I need to persists the progress of a run, and then not repeat them
I have seen some paid SaaS for this, but none that really give me what I want
This is going to be important especially while working with agents, because when you are committing 100x faster, you don't want to waste time and compute running the same things
I started building this already as an exercise. If this exists already in a satisfactory way, I will stop. Otherwise, I'll keep building
*Part 1/2 of a thread; root: https://solmaz.io/x/2043427225824055675/*
==========
---
title: "My clanker @dutifulbob has an identity update. I was getting sick of the despicable me theme..."
date: 2026-04-12
canonical: https://solmaz.io/x/2043398933607547019/
x_url: https://x.com/onusoz/status/2043398933607547019
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My clanker @dutifulbob has an identity update. I was getting sick of the despicable me theme and bananas
==========
---
title: "Some photos from my @aiDotEngineer Europe talk, credits to @sergiopesch"
date: 2026-04-11
canonical: https://solmaz.io/x/2043038348592165195/
x_url: https://x.com/onusoz/status/2043038348592165195
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Some photos from my @aiDotEngineer Europe talk, credits to @sergiopesch
He managed to capture the “Agentol, Apply Generously” slide, lol
==========
---
title: "local gemma 4 first impressions on openclaw, using the dense model, 26b model with 49gb weights..."
date: 2026-04-11
canonical: https://solmaz.io/x/2043035989833126167/
x_url: https://x.com/onusoz/status/2043035989833126167
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
local gemma 4 first impressions on openclaw, using the dense model, 26b model with 49gb weights on my asus gx10
took some time to set up, but it succeded in getting a response in 1-2 hours with vllm docs
I asked it to demonstrate some tool calls. it tried to call the nonexistent weather tool 2300 times 🙄
it seems to have a tendency to get stuck in loops in openclaw harness. enabling loop detection just now did not help
I’m debugging this on my phone lol. I’ll be sharing my progress with gemma4 under this thread
*Part 1/2 of a thread; root: https://solmaz.io/x/2043035989833126167/*
==========
---
title: "A rescue agent guaranteed not to break solves this"
date: 2026-04-11
canonical: https://solmaz.io/x/2042862980572807442/
x_url: https://x.com/onusoz/status/2042862980572807442
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A rescue agent guaranteed not to break solves this
*Quotes a post by another author (https://x.com/i/status/2042602843191021723); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Finally!"
date: 2026-04-10
canonical: https://solmaz.io/x/2042704553808744475/
x_url: https://x.com/onusoz/status/2042704553808744475
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Finally!
*Quotes a post by another author (https://x.com/i/status/2042295688323875316); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "OpenClaw type UK Drill Jazz Beat by @thorwebdev @GeminiApp @GoogleDeepMind"
date: 2026-04-10
canonical: https://solmaz.io/x/2042617748308513239/
x_url: https://x.com/onusoz/status/2042617748308513239
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw type UK Drill Jazz Beat by @thorwebdev @GeminiApp @GoogleDeepMind
==========
---
title: "For those who want to view, my talk Building on ACP at OpenClaw at @aiDotEngineer Europe..."
date: 2026-04-10
canonical: https://solmaz.io/x/2042550983465611542/
x_url: https://x.com/onusoz/status/2042550983465611542
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For those who want to view, my talk Building on ACP at OpenClaw at @aiDotEngineer Europe, 5:41hr mark
About ACP, acpx and running agents on kubernetes with open source orchestrators
https://www.youtube.com/watch?v=O_IMsEg91g8&t=20511s
==========
---
title: "Anthropic is optimizing for general knowledge work"
date: 2026-04-10
canonical: https://solmaz.io/x/2042494957286560225/
x_url: https://x.com/onusoz/status/2042494957286560225
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
PSA for developers
Do NOT torture yourself with Opus*. Anthropic’s current growth is due to people using Claude for general knowledge work
They are not directly incentivized as an org anymore to improve the model for coding, in an economic sense. They are already printing cash from non-developers
(this statement ignores the fact that improving its coding abilities would help with general reasoning/knowledge work)
Developers are a very small subset of all knowledge workers. So from this point on, they would rather divert their resources to develop a system that works 90% good for ALL knowledge work, rather than making it 100% for coding
Because Anthropic has a clear enterprise strategy since years already. Anthropic is the new Microsoft. Do not think that “Anthropic is Apple” or “Claude is Mac for xyz”
Looking at Claude’s at whim quantization and Claude Code’s quality over time, Claude for me is Windows, not Mac
But they are winning big enterprise bucks, so good for them!
*(I tortured myself with Sonnet 4 and Opus the entire summer of 2025, and no developer should ever have to go through that. I switched to something better as soon as it came out, Codex. If something even better comes out, I will switch again)
*Quotes a post by @mitchellh (https://x.com/mitchellh/status/2042340914702794823); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Clawfather @steipete at stage @aiDotEngineer europe"
date: 2026-04-09
canonical: https://solmaz.io/x/2042171612917567503/
x_url: https://x.com/onusoz/status/2042171612917567503
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Clawfather @steipete at stage @aiDotEngineer europe
==========
---
title: "Big lab marketing teams like to shroud model releases in mystery and vagueposting"
date: 2026-04-08
canonical: https://solmaz.io/x/2041767427420156248/
x_url: https://x.com/onusoz/status/2041767427420156248
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Big lab marketing teams like to shroud model releases in mystery and vagueposting
If you are curious about the black hat capability of LLMs, watch this pres by Nicholas Carlini from a few days back
https://youtu.be/1sd26pWhfmg
==========
---
title: "I will be there as well, speaking about ACP, acpx and agent orchestration 🙌"
date: 2026-04-07
canonical: https://solmaz.io/x/2041529072111477222/
x_url: https://x.com/onusoz/status/2041529072111477222
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I will be there as well, speaking about ACP, acpx and agent orchestration 🙌
*Quotes a post by another author (https://x.com/i/status/2041445170642571562); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Full transcripts are available, including all the back and forth between codex, claude and judge"
date: 2026-04-06
canonical: https://solmaz.io/x/2041202936391340244/
x_url: https://x.com/onusoz/status/2041202936391340244
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Full transcripts are available, including all the back and forth between codex, claude and judge
*Part 3/3 of a thread; root: https://solmaz.io/x/2041187155620274541/*
==========
---
title: "Repo link (feel free to send PRs):"
date: 2026-04-06
canonical: https://solmaz.io/x/2041187554905530696/
x_url: https://x.com/onusoz/status/2041187554905530696
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Repo link (feel free to send PRs):
http://github.com/osolmaz/ai-battle
*Part 2/3 of a thread; root: https://solmaz.io/x/2041187155620274541/*
==========
---
title: "Introducing AI Battle"
date: 2026-04-06
canonical: https://solmaz.io/x/2041187155620274541/
x_url: https://x.com/onusoz/status/2041187155620274541
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Is Claude better or Codex?
There are many benchmarks to answer that. But they are BORING
I propose something more interesting: ⚔️ AI BATTLE ⚔️
A 1v1 real-time quiz format where AI agents try to pose each other problems that they think the other agent will not be able solve
Claude vs Codex
10 questions each
Codex asks first, Claude tries to answer
Then Claude asks and Codex tries to answer
Repeat
20 minutes to come up with a problem and 20 minutes to solve it
Judge (Codex) judges the validity of the questions and answers, and gives points
All automated, with acpx flow feature
Implementation and full rules all open source, on github osolmaz/ai-battle
So who won?
I ran 4 games.
It tied in 2, and Codex won in 2 closely
An example question by Codex, which Claude could not answer:
How many 3-colorings of the edges of the complete bipartite graph K_{5,5} are there with the following two properties: (1) there is no monochromatic 4-cycle, and (2) among the 25 edges, exactly 15 are red, exactly 5 are blue, and exactly 5 are green?
Which is apparently 4029912, but Claude answered 0
In other cases, Claude asked a flawed question and failed to come up with a valid question in 20 minutes. So that's how it lost those 2 games with just 1-2 point difference
In these 4 runs, Codex answered every question by Claude correctly. But there were some runs where it couldn't, which I did not commit to the repo because the runs couldn't complete due to bugs
I did not tell them do ask math questions, but that is what they tended to do, because the answers had to be verifiable by the judge. The quiz can be done in any hard subject, physics, chemistry, computer science...
Opus 4.6 and GPT 5.4 matched very closely in terms of problem creation and solving. But I cannot tell how creative these problems were at first glance. Maybe someone with more experience can tell me, looking at the problems in the repo? I need someone to tell me how legit they are
Please take the code, modify it and run with different rules and subjects. I am curious to see the results!
You will need paid subscriptions to all the models/agents you want to test of course
I also feel that the game structure has a potential to be used in self-play. If you are an ML researcher, please look at the repo and lmk if this or a variant of it could be useful in RL!
Full transcripts of the runs, including Codex and Claude session files are committed to the repo, for those who want to do archaeology on them
Btw this idea came from the desire, "how can I create a cool demo of acpx flows?"
Whole game is implemented in typescript, and automatically drives Codex and Claude sessions over ACP, Agent Client Protocol
The video below is from acpx flow viewer rendering a run. You can see it loop through the same paths, first letting Codex ask, then Claude, then repeat
acpx flows use a general programmatic workflow engine where ACP is just one type of node. You should be able to use it for non-ACP workflows, but I haven't tried that yet
This implementation is separate from OpenClaw's current workflow implementations, with the intention to merge them somehow in the future
You might find bugs in my implementation. Feel free to send PRs. I wanted to do more runs but I finished my Codex plan. It would be great if this idea could evolve in a decentralized manner!
*Part 1/3 of a thread; root: https://solmaz.io/x/2041187155620274541/*
==========
---
title: "Their argument “it’S HaRd On OuR iNfRa” so goes down the drain"
date: 2026-04-06
canonical: https://solmaz.io/x/2041054962914869426/
x_url: https://x.com/onusoz/status/2041054962914869426
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Their argument “it’S HaRd On OuR iNfRa” so goes down the drain
With this, they shot themselves in the foot for a future anti-competitive lawsuit, because it is undeniable evidence that they just don’t want competition
Which means they have evaluated the benefits short term, and calculated that it is higher than what they will pay in the lawsuit
I don’t see how it is good for them long term
*Quotes a post by @theo (https://x.com/theo/status/2040895674288570499); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "AI replies are getting more sophisticated… or people are turning into AIs"
date: 2026-04-05
canonical: https://solmaz.io/x/2040872050181451938/
x_url: https://x.com/onusoz/status/2040872050181451938
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI replies are getting more sophisticated… or people are turning into AIs
If this is AI, I wonder what the instruction is. “Misunderstand the point and reply with a question while inverting the argument”?
Artificial General Ragebait
==========
---
title: "The new github skill installed automatically by codex now causes it to prepend [codex] to each..."
date: 2026-04-05
canonical: https://solmaz.io/x/2040761244697641250/
x_url: https://x.com/onusoz/status/2040761244697641250
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The new github skill installed automatically by codex now causes it to prepend [codex] to each PR title
This is a guerilla marketing tactic similar to Claude adding itself as co-committer
Codex team, I know you want to boast usage but this is annoying
Moreover, "open source" OpenAI repos block opening of PRs by people outside of their org. So I couldn't create a PR to remove it (I don't expect them to merge it, but it would still show how many people hate it in the discussion)
Here is a prompt for your agent if you want to disable it:
---
Add or update AGENTS.md in my ~/.codex folder
Add a rule "You MUST NOT insert coding agent specific branding, like [codex], in code, PRs or issues created on GitHub"
---
Then restart your sessions and this should be resolved
==========
---
title: "A throttling protocol for model providers"
date: 2026-04-04
canonical: https://solmaz.io/x/2040545125680718304/
x_url: https://x.com/onusoz/status/2040545125680718304
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A more reasonable long term option for Anthropic is to create a throttling protocol
A standardized harness agnostic protocol for model providers to send warnings and throttle usage in real time
Harnesses would implement the protocol. A client can be warned. If it doesn’t listen, it can be temporarily blocked from the server side, or banned permanently if it breaks the rules too many times
Needless to say, throttling could be done first on server side easily. That would actually fix the load issue for them in the short run, while not banning the user and just giving a bad delayed UX. They probably already do this to prevent abuse
The suggested protocol would then save the user from abuse related delays too, and also inform the harness developer when they do something wrong
*Quotes a post by @onusoz (https://x.com/onusoz/status/2040403489155584024); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "If your Claude subscription renewed too recently and you don't wanna waste those tokens, you..."
date: 2026-04-04
canonical: https://solmaz.io/x/2040449587312222416/
x_url: https://x.com/onusoz/status/2040449587312222416
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If your Claude subscription renewed too recently and you don't wanna waste those tokens, you can still use your Claude sub in your OpenClaw account through ACP (which uses Claude Agents SDK, which poses no risk)
Steps:
- Open Claude Code (not OpenClaw)
- Tell it to set default model to something other than Claude (e.g. openai-codex/gpt-5.4) and tell it to delete the saved Anthropic credentials in OpenClaw config
- Create a topic in telegram or channel in discord called claude. Copy the id of that channel
- Give the link below together with the channel/topic id, and tell it to bind that channel to claude using ACP channel binding
- Restart
You should now be able to talk to Claude through Claude Agents SDK in that channel. You might need to iterate a couple times until Claude gets the config right
It will be very bare functionality, and it will not have the features and tools that your main OpenClaw harness has. It will be shitty. But you can still use telegram/discord with your subscription in the rest of the month, if you are used to the setup
https://docs.openclaw.ai/tools/acp-agents
==========
---
title: "ACP sessions as JSONL"
date: 2026-04-04
canonical: https://solmaz.io/x/2040398645766344713/
x_url: https://x.com/onusoz/status/2040398645766344713
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A little insight that might save you a lot of future headache if your work involves storing agent sessions and you want to be interoperable/drop-in replace alternative harnesses
@zeddotdev already did the hard work of creating an interoperable standard, ACP: Agent Client Protocol
You can represent an agent session as JSON lines of the ACP message stream
You can construct the current state of the harness from this stream. This is already how Zed loads a session I believe
If you are building an AI product, and you don't want to be locked into a single company or harness, building with ACP in mind would be a smart thing to do
Here is how acpx stores ACP sessions in ~/.acpx folder, it does exactly that:
https://github.com/openclaw/acpx/blob/main/docs/2026-02-27-acpx-session-model.md
But don't build anything on the acpx schema for now, because I might change it in the future
Just know that JSONL of ACP messages is a good candidate for a somewhat-lossy single source of truth for agent sessions
Lossy because ACP adapters for harnesses might not transfer all the thinking and tools done by the model
So continuing or restoring a session with full fidelity is still not possible if you only save the ACP session. You still need to store original harness session files as well
But for rendering a past session for viewing or reconstructing a lossy version of it, it should be more than enough
Consider ACP if the benefits of not locking yourself in to a specific ecosystem outweighs these minor issues
==========
---
title: "If you dislike rotating ack emojis on your messages in openclaw, this is how to make sure it..."
date: 2026-04-04
canonical: https://solmaz.io/x/2040375376715632923/
x_url: https://x.com/onusoz/status/2040375376715632923
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you dislike rotating ack emojis on your messages in openclaw, this is how to make sure it only puts one emoji on your message
Multiple emojis are annoying esp when you have discord notifications enabled on your phone
==========
---
title: "Plainer language for better agent UX"
date: 2026-04-03
canonical: https://solmaz.io/x/2040087752444678418/
x_url: https://x.com/onusoz/status/2040087752444678418
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"Plainer language" is perhaps my most used prompt
I have to use it because GPT models' training tends to make their first response an overly verbose wall of text
Are you using it too? Whenever you don't understand something that your agent is saying, you can spam it "plainer language, shorter" 2, 3, 5, 10 times, until it outputs something that you can understand
This is counterintuitive because you can't do it with humans this extremely. Asking too many questions and favors is impolite, with colleagues and strangers
But with AI, you can stop being polite and treat it like how a spoiled aristocrat kid might treat their private tutor, "explain this", "explain that"
Below is an example. On the left, initial response. On the right, the final human-readable explanation I got out of the agent. This took 9 steps to distill because the issue wasn't so straightforward
I'm curious how this will turn out. This is obviously very bad UX, so models in the near future might do the simplification automatically and save you the trouble
*Quotes a post by @onusoz (https://x.com/onusoz/status/2036453519503286576); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This has happened to some companies I worked at before"
date: 2026-04-03
canonical: https://solmaz.io/x/2040043161733505305/
x_url: https://x.com/onusoz/status/2040043161733505305
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This has happened to some companies I worked at before
It is a scary thing once you stop innovating and start imitating, whatever the reason might be
But it was never at the scale of Cursor, as leveraged and invested as they are
They were leading the space for a while. That is not the case anymore. I hope that they survive this
*Quotes a post by another author (https://x.com/i/status/2039768512894505086); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Claude Code's python slopfork getting so many github stars proves that github stars don't matter"
date: 2026-04-02
canonical: https://solmaz.io/x/2039595193469370796/
x_url: https://x.com/onusoz/status/2039595193469370796
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Claude Code's python slopfork getting so many github stars proves that github stars don't matter
Just like moltbook didn't matter
It is not eyeballs that make a project succeed long term. It is engineering
==========
---
title: "I've talked to multiple people who want to get involved with OpenClaw somehow"
date: 2026-04-01
canonical: https://solmaz.io/x/2039456655839039573/
x_url: https://x.com/onusoz/status/2039456655839039573
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I've talked to multiple people who want to get involved with OpenClaw somehow
The best way is to contribute to it, something tangible. Fix something you are annoyed by, get a PR merged
Then go to discord and get the contributor role
If it adds value to your life, and you add value to it, stay around and keep contributing. And something good might happen
==========
---
title: "Will be there as well 👋"
date: 2026-04-01
canonical: https://solmaz.io/x/2039410740700869112/
x_url: https://x.com/onusoz/status/2039410740700869112
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Will be there as well 👋
Looking forward to it!
*Quotes a post by another author (https://x.com/i/status/2039398936423850017); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "if there is an open source project with more SASS than openclaw, it is ffmpeg"
date: 2026-04-01
canonical: https://solmaz.io/x/2039393072073572823/
x_url: https://x.com/onusoz/status/2039393072073572823
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
if there is an open source project with more SASS than openclaw, it is ffmpeg
*Quotes a post by another author (https://x.com/i/status/2039260166902763565); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "wow"
date: 2026-03-31
canonical: https://solmaz.io/x/2038938589128503521/
x_url: https://x.com/onusoz/status/2038938589128503521
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
wow
*Quotes a post by @Fried_rice (https://x.com/Fried_rice/status/2038894956459290963); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "next up: claude agents sdk supports openai responses api 💀"
date: 2026-03-30
canonical: https://solmaz.io/x/2038748892611715230/
x_url: https://x.com/onusoz/status/2038748892611715230
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
next up: claude agents sdk supports openai responses api 💀
*Quotes a post by @romainhuet (https://x.com/romainhuet/status/2038677236304245087); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Welcome ManusClaw"
date: 2026-03-30
canonical: https://solmaz.io/x/2038665333431582803/
x_url: https://x.com/onusoz/status/2038665333431582803
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Welcome ManusClaw
*Quotes a post by another author (https://x.com/i/status/2038632918310908172); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "yes"
date: 2026-03-30
canonical: https://solmaz.io/x/2038614010283557121/
x_url: https://x.com/onusoz/status/2038614010283557121
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
yes
*Quotes a post by @andrewchen (https://x.com/andrewchen/status/2038409934556283391); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "OpenClaw saw over 1000 PRs opened per day in early March"
date: 2026-03-30
canonical: https://solmaz.io/x/2038605696363593945/
x_url: https://x.com/onusoz/status/2038605696363593945
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw saw over 1000 PRs opened per day in early March
Stuff is crazy, I wonder whether we will see 10k per day one day...
==========
---
title: "Here is the spec and implementation for this flow. The mermaid diagram includes all the steps I..."
date: 2026-03-30
canonical: https://solmaz.io/x/2038567975809106297/
x_url: https://x.com/onusoz/status/2038567975809106297
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is the spec and implementation for this flow. The mermaid diagram includes all the steps I mentioned in the post above, including a shameless AI review ralph loop, and other loops to make CI pass, resolve conflicts and so on
I would recommend reading the README and TUNING.md to understand the approach here
https://github.com/openclaw/acpx/tree/main/examples/flows/pr-triage
*Part 2/2 of a thread; root: https://solmaz.io/x/2038565725690900992/*
==========
---
title: "acpx v0.4 ships Agentic Workflows"
date: 2026-03-30
canonical: https://solmaz.io/x/2038565725690900992/
x_url: https://x.com/onusoz/status/2038565725690900992
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
acpx v0.4 ships Agentic Workflows, or as I like to call them "Agentic Graphs"
It let's you create node-based workflows on top of ACP (Agent Client Protocol), to drive any coding agent (Codex, Claude Code, pi) through deterministic steps
This let's you automate routine, mechanical legwork like triaging incoming PRs, bugs in error reporting, and so on...
For example, OpenClaw receives 300~500 new PRs per day. A lot of them are low quality, but they still relate to real issues, so you have to address them somehow
You need to:
- extract the intent
- cluster them based on intent
- figure out if the proposed changes are legit, or whether they are slop local solutions, like trying to catch flies instead of drying out the swamp
- if the PR is too low quality or the intent is not clear, close them
- run AI review on them them and address any issues that come up
- refactor them if the changes are half-baked
- resolve conflicts
- and so on...
So that when the PR is presented to the attention of the maintainer, all the routine legwork is done and the only remaining thing is the decision to (a) merge, (b) give feedback to the PR author, or (c) take over the PR work yourself
I wanted to build this feature since a couple months now, since Codex got so good. OpenAI models are now good at judging implementation quality, so I found myself repeating the same steps I wrote above over and over
I also tried putting all this in a single prompt. But I believe there are workflows that should not be a single prompt, but a sequence of prompts in the same session
That is because like humans, LLMs are prone to PRIMING. I claim that putting all steps in the same prompt at the beginning of the context will generally give suboptimal results, compared to revealing the intention to the model step by step
Creating such a workflow also gives more OBSERVABILITY into the each step that an agent is supposed to take. Agent generates JSON at the end of each step, and that structured data can be used to monitor thousands of agents running at the same time in an easier way, on a dashboard
Similar features have been introduced in e.g. n8n, langflow. But AFAIK they are not integrating ACP like the way I do
I wanted to have a fresh approach, and to build an API that I can develop freely the way I want, so I created a new workflow API inside acpx
The video is from the workflow run viewer, but that is not where you build the workflow. You build it by using the acpx flow typescript API. See examples/pr-triage in acpx repo
Before building that, I started from a Markdown file with a Mermaid chart of the flow I had in mind. The Markdown file acts as a spec for the flow, and I have built the workflow through trial and error. I call this process "workflow tuning"
I started working on acpx repo PRs one by one, tuning the flow, slowly scaling to more PRs. Finally, when I felt confident, I ran it in parallel over all external open PRs in the acpx repo. I believe it already saved me hours this week
My next goal, if well received, is to set this up on a cloud agent so that it can process the 300~500 PRs the OpenClaw repo receives every day, in real time, as they come in
I believe this will save all open source maintainers around the world countless hours and make it much easier to herd and absorb external contributions from everyone!
*Part 1/2 of a thread; root: https://solmaz.io/x/2038565725690900992/*
==========
---
title: "OpenAI early 2020s:"
date: 2026-03-29
canonical: https://solmaz.io/x/2038158067334852647/
x_url: https://x.com/onusoz/status/2038158067334852647
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenAI early 2020s:
"This model is too dangerous to release publicly, the world is not ready for it 😱😱😱"
OpenAI and Anthropic in 2026:
"Anybody can code now for just $200 per month. Oh btw our models are also leet uber hackers which can find zeroday exploits in any software, just fyi 😉😉😉"
https://www.youtube.com/watch?v=1sd26pWhfmg
==========
---
title: "Wow even I as a frontend noob understand the significance of this"
date: 2026-03-28
canonical: https://solmaz.io/x/2037922223655121350/
x_url: https://x.com/onusoz/status/2037922223655121350
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Wow even I as a frontend noob understand the significance of this
Some distant memory from 15 years ago needing to measure the width/height of some text and finding out it’s not possible to do reliably in web
More beautiful typography for the web!
*Quotes a post by @_chenglou (https://x.com/_chenglou/status/2037713766205608234); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Token Leverage"
date: 2026-03-28
canonical: https://solmaz.io/x/2037798411173257244/
x_url: https://x.com/onusoz/status/2037798411173257244
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
There is an economic theory waiting to be uncovered here
Token Leverage (TL) = Token spend / Human labor spend
The higher Token Leverage a company has, the more automated and productive they are
If you have TL=1, you are spending as much money on AI as your human employees
The goal of a company should be to increase TL as much as possible, while keeping a positive profit margin. It will be the only way to compete
You don’t need to muddy the definition with wasted tokens vs useful tokens, because a company will always be incentivized to reduce token waste in a competitive environment. By that logic, monopolies will always waste more tokens, similar to how they waste other resources
Scaling TL higher to 2x, 10x, 100x will require a skilled workforce of engineers. It will be a very complex job similar to those working at the big labs. Burnout will be a defining feature of teams scaling TL
Most incumbents will fail to scale their TL over 1. Some will get decimated by new entrants with TL much bigger than 1
Curious how the average TL will end up in different sectors. Whether it will stabilize at a certain value like 5.7x, or will just keep growing…
*Quotes a post by @t_blom (https://x.com/t_blom/status/2037591830150426704); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Non-dev knowledge work needs version control"
date: 2026-03-27
canonical: https://solmaz.io/x/2037446862484001103/
x_url: https://x.com/onusoz/status/2037446862484001103
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
There is a desperate upcoming need for version controlling non-dev knowledge work. Git for non-devs. Otherwise non-devs won't be able to use agents to their full extent
Non-dev knowledge work is notoriously bad at being version controlled. You cannot UNDO edits to all MS word, excel or ppt files in an org as easily you can with something like git
We know that agents will be ubiquitous. We also know they make mistakes, and people will want to undo their work regularly, once they make changes to a bunch of files. Well, they can't. They also don't have pull requests, or a way to resolve conflicts after simultaneous edits
All these problems were solved by developers. We are extremely good at this
The only non-dev tool I know that could do this at scale is Notion, and that is not used by enterprise as much as MS office. Notion also doesn't have branches, pull requests and reviews AFAIK
Markdown and git is probably not it. I wish it were. But it is too complicated for non-devs
Onedrive or other file backup systems are also not it. Are you gonna save a copy of a 100mb ppt every time someone changes a slide??? Let's say you find a way to compress it efficiently. Will you be able to get a single pointer to a state like we can in git?
Agents need precision. Agents need consensus, they need to be able to know ground truth. They need to be able to tell what anything was at a given time. NOTHING in current MS stack currently allows it
Agents won't care about your legacy systems. There will be new file formats, systems, knowledge stack, and companies who adopt them will destroy your business
If MS office is going to die, it will do so because of this
==========
---
title: "Another one, call me stupid: “How would Google have done it?”"
date: 2026-03-25
canonical: https://solmaz.io/x/2036698723745517598/
x_url: https://x.com/onusoz/status/2036698723745517598
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Another one, call me stupid: “How would Google have done it?”
*Quotes a post by @onusoz (https://x.com/onusoz/status/2036453519503286576); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "MCP vs CLI"
date: 2026-03-24
canonical: https://solmaz.io/x/2036538477269934562/
x_url: https://x.com/onusoz/status/2036538477269934562
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The MCP versus CLI argument should be reframed as Computer vs No-computer argument
I personally get the dunk on MCP. It didn't work last year, with earlier models. Then we saw CLIs perform much better with the same models. And giving access to bash was much simpler!
Models' training then made them better at calling using a shell. CLIs also have native progressive disclosure, due to the way they work
But the most important fact doesn't get pronounced enough IMO
A key factor was that giving a CLI to a model also means you are giving it an entire COMPUTER
The action space of all commands an agent can run on bash is much, much bigger than a few MCP servers
One is a Turing machine, and the other one is basically a REST API. Of course the Turing machine is going to be more powerful, depending on what is at the other end of the API
By that logic, giving an agent access to bash over MCP versus direct access to bash should have the same level of effectiveness, with optimized prompt engineering and long term training. Because the interfaces are equivalent
So the argument is, should we give our agents access to a computer, or not?
It depends on the security requirements and the setup which the agent is supposed to run on. If you are co-hosting the agent on the same machine you are working on, then it is safer to use MCP servers, because it limits the attack surface in case of adversarial attacks
But if you are willing to give the agent its own physical computer, willing to be mindful about the lethal trifecta and the principle of the least privilege, giving it shell access is much more useful
So MCPs win in restricted/local environments, whereas CLIs/shell access win in unrestricted/remote ones
Running an agent locally and safely with shell access requires compartmentalization. This is much heavier compared to installing MCP servers locally, which don't need that. So there is a tendency to use MCP servers locally, e.g. in a work setting
Cloud agents on the other hand are more likely to ship with a computer. Because they are already isolated = no risk, and because it makes them much more useful. So cloud agents will be using both CLIs and MCP servers, whichever gets the job done!
==========
---
title: "I just registered for an .agent domain and joined the .agent community!"
date: 2026-03-24
canonical: https://solmaz.io/x/2036513807535673457/
x_url: https://x.com/onusoz/status/2036513807535673457
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I just registered for an .agent domain and joined the .agent community!
@dutifulbob will have bob.agent if it passes :)
https://agentcommunity.org/join#LW2X9CGX @agentcommunity_
==========
---
title: "Sep 2021 @lexfridman podcast with Don Knuth, they also talk about OpenAI Codex (code completion..."
date: 2026-03-24
canonical: https://solmaz.io/x/2036508547731656957/
x_url: https://x.com/onusoz/status/2036508547731656957
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Sep 2021 @lexfridman podcast with Don Knuth, they also talk about OpenAI Codex (code completion model) around 33 minute mark
This aged very well
https://youtu.be/EE1R8FYUJm0?t=1995
==========
---
title: "Damn I’m gonna have to switch to teams if it goes like that"
date: 2026-03-24
canonical: https://solmaz.io/x/2036495488829055348/
x_url: https://x.com/onusoz/status/2036495488829055348
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Damn I’m gonna have to switch to teams if it goes like that
*Quotes a post by @upster (https://x.com/upster/status/2036430555622023202); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Codex's long horizon task and instruction following has been the most life-changing AI feature..."
date: 2026-03-24
canonical: https://solmaz.io/x/2036487453624701176/
x_url: https://x.com/onusoz/status/2036487453624701176
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex's long horizon task and instruction following has been the most life-changing AI feature recently
It is unlocking the next level of automation for me. I can convert my own heuristics into prompts and multiply my throughput 100x
Currently spending some thought on how to orchestrate all this. Below is a flowchart from a triage workflow I am working on
==========
---
title: "Amazed everyday by the unreasonable effectiveness of in-context learning"
date: 2026-03-24
canonical: https://solmaz.io/x/2036478685088199204/
x_url: https://x.com/onusoz/status/2036478685088199204
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Amazed everyday by the unreasonable effectiveness of in-context learning
==========
---
title: "This is unscientific, but there are certain keywords and phrases I use a lot while using..."
date: 2026-03-24
canonical: https://solmaz.io/x/2036453519503286576/
x_url: https://x.com/onusoz/status/2036453519503286576
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is unscientific, but there are certain keywords and phrases I use a lot while using certain models like openai's. I use them a lot because they get me what I want immediately:
- plainer lang
- cutover
- elegant and production ready
- holy grail
What are yours?
==========
---
title: "Request for memes"
date: 2026-03-24
canonical: https://solmaz.io/x/2036426717053542413/
x_url: https://x.com/onusoz/status/2036426717053542413
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Request for memes
A funny and quirky edit of historical timeline of the madness that is openclaw
with "Chess type beat" or sth equally jazzy/circusy
Preferably including its adventure warelay -> clawdis -> clawdbot -> moltbot -> openclaw
Including:
- its explosion after @4shadowed's discord integration
- naming drama, moltbook and people getting oneshotted about AI takeover
- @steipete speedrunning everything
- andrew tate calling us gay lol
- up to Jensen talking about openclaw on stage for 5 minutes straight
and other things I am forgetting
maybe overlaid with a lobster just keeping climbing the github star graph and breaking it
==========
---
title: "Native support for Codex on OpenClaw"
date: 2026-03-24
canonical: https://solmaz.io/x/2036367212995383574/
x_url: https://x.com/onusoz/status/2036367212995383574
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Native support for Codex on OpenClaw
I will be using half my codex channels on acp and other half on codex app server for optimum dogfooding
*Quotes a post by @huntharo (https://x.com/huntharo/status/2036227506836033769); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I see non-engineers have a higher tendency to humanize their agents, give them personalities..."
date: 2026-03-22
canonical: https://solmaz.io/x/2035845620900954580/
x_url: https://x.com/onusoz/status/2035845620900954580
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I see non-engineers have a higher tendency to humanize their agents, give them personalities, and get AI psychosis
It's a slippery slope. Do NOT give your agents human names or personalities, especially not of the opposite gender. it's like giving human names to pets
On the other end, I realized engineers tend to do the opposite. We also refer to agents as clankers, as if to make them know their place. That's because we have mechanical sympathy and have different expectations of these manufactured products (even though they contain glimmers of human soul)
==========
---
title: "Request for testing"
date: 2026-03-22
canonical: https://solmaz.io/x/2035821394185916851/
x_url: https://x.com/onusoz/status/2035821394185916851
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Request for testing
Give this to your openclaw instance: "update yourself to the dev channel `openclaw update --channel dev` and restart yourself. if that doesn't work -> clone github openclaw/openclaw to this machine if it's not already. then rebuild and restart yourself on main branch there"
Then give your openclaw a try with your regular workflows/tasks
Huge openclaw release incoming tonight, hopefully (no promises). We need to make sure we break as little as possible
Plugins might break, because the plugin SDK is being refactored. Plugins will have to be refactored to use the new SDK, please do not report those
Do report: native openclaw functionality that stops working
Please reply under this post, we'll be checking here 👇
==========
---
title: "Request for testing"
date: 2026-03-22
canonical: https://solmaz.io/x/2035818576876081626/
x_url: https://x.com/onusoz/status/2035818576876081626
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Request for testing
Give this to your openclaw instance: "update yourself to the dev channel `openclaw update --channel dev` and restart yourself"
Then give your openclaw a try with your regular workflows/tasks
Huge openclaw release incoming tonight, hopefully (no promises). We need to make sure we break as little as possible
Plugins might break, because the plugin SDK is being refactored. Plugins will have to be refactored to use the new SDK, please do not report those
Do report: native openclaw functionality that stops working
Please reply under this post, we'll be checking here 👇
==========
---
title: "Request for testing"
date: 2026-03-22
canonical: https://solmaz.io/x/2035809656476766317/
x_url: https://x.com/onusoz/status/2035809656476766317
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Request for testing
Give this to your openclaw instance: "clone github openclaw/openclaw to this machine if it's not already. then rebuild and restart yourself on main branch there"
Then give your openclaw a try with your regular workflows/tasks
Huge openclaw release incoming tonight, hopefully (no promises). We need to make sure we break as little as possible
Plugins might break, because the plugin SDK is being refactored. Plugins will have to be refactored to use the new SDK, please do not report those
Do report: native openclaw functionality that stops working
==========
---
title: "My takeaway from this is academia needs good social media and algo. For me, these..."
date: 2026-03-22
canonical: https://solmaz.io/x/2035618922179801271/
x_url: https://x.com/onusoz/status/2035618922179801271
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My takeaway from this is academia needs good social media and algo. For me, these serendipitious interactions happen through X, here, like reading @steipete’s “Claude Code is my computer” when it first came out, finding out about clawdbot…
Terence Tao is already on mathstodon, I wonder if that worked out the same way for him. I wonder if the algo there works out as well as it does for me here
I really liked being on campus when I was doing a masters and half a phd, but that could not compare to the serendipity I am getting from X now
I was also not a prodigy that everyone wanted to bounce ideas from like Terence :)
*Quotes a post by another author (https://x.com/i/status/2035446346803777728); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Welcome ClaudeClaw to the Claw family!"
date: 2026-03-21
canonical: https://solmaz.io/x/2035279731797496280/
x_url: https://x.com/onusoz/status/2035279731797496280
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Welcome ClaudeClaw to the Claw family!
Claude is a bit shy and doesn’t want to show its source code. But it’s OK, we love Claude that way :)
*Quotes a post by @sawyerhood (https://x.com/sawyerhood/status/2034761619314811114); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Agent infrastructure needs Kubernetes"
date: 2026-03-21
canonical: https://solmaz.io/x/2035255751669608872/
x_url: https://x.com/onusoz/status/2035255751669608872
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It is obvious to me at this point that agent infra needs to run on Kubernetes, and agents should be spawned per issue/PR
Issue, error report or PR comes into your repo -> new agent gets triggered, starts to do some preliminary work
If it's an obvious bugfix, it fixes it and creates a PR. If it's something deeper/more fundamental, it creates a report for the human and waits for further instructions
Most important thing: Human should be able to zoom in and continue the conversation with the agent any time, steer it, give additional instructions. This chat will happen over ACP
The chat UI will have to live outside of GitHub because it doesn't have such a feature yet, i.e. connect arbitrary ACP sessions to the GitHub webapp
It also cannot live so easily on Slack, Teams or Discord, because none of these support multi-agent provisioning under the same external bot connection. You are limited to 1 DM with your bot, whereas this setups requires an arbitrary number of DMs with each agent. So there will need to be a new app for this
Then there is the issue of conflict -> Agents will work on the same thing simultaneously (e.g. you break sth in prod and it creates multiple error reports for the same thing). You will need some agent to agent communication, so that agents can resolve code or other conflicts. There could be easy discovery mechanisms for this, detect programmatically when multiple open PRs are touching the same files and would conflict if merged
In case of duplicates, they can negotiate among each other, and one can choose to absorb its work into the other and end its session
We are so early and there is so much work to do!
==========
---
title: "You should look into what Don Syme is doing at GitHub for automation with AI agents"
date: 2026-03-21
canonical: https://solmaz.io/x/2035247706646430011/
x_url: https://x.com/onusoz/status/2035247706646430011
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You should look into what Don Syme is doing at GitHub for automation with AI agents
Also watch his latest podcast with @shanselman
*Quotes a post by @dsymetweets (https://x.com/dsymetweets/status/1984768418818498893); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Merge first, review later"
date: 2026-03-20
canonical: https://solmaz.io/x/2035123110131781751/
x_url: https://x.com/onusoz/status/2035123110131781751
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Today I thought I found a solution for this, and I did. It can be solved by a pre-commit hook that blocks commits touching files that you are not the owner of. It is not a hard block, so requires trust among repo writers
But then I was shown the error in my ways by fellow maintainer *disciplined*
Any process that increases friction in code changes to main, like hard-blocking CI/CD, or requiring review for files in CODEOWNERS, is a potential project-killer, in high velocity projects
This is extremely counterintuitive for senior devs! Google would never! Imagine a world without code review...
But then what is the alternative? I have some ideas
It could be "Merge first, review later"
The 4-eyes principle still holds. For a healthy organization, you still need shared liability
But just as you don't need to write every line of code, you also don't need to read every line of code to review it. AI will review and find obvious bugs and issues
So what is your duty, as a reviewer? It is to catch that which is not obvious. Understand the intent behind the changes, ask questions to it. Ensure that it follows your original vision
Every few hours, you could get a digest of what has changed that was under your ownership, and concern yourself with it if you want to, fix issues, or ignore it if it looks correct
But such a team is hard to build. It is as strong as its weakest link. Everybody has to be vigilant and follow what each other is doing at a high level, through the codebase
Every time one messes up someone else's work, it erodes trust. Nobody gets the luxury to say "but my agent did it, not me"
But if trust can be maintained, and everybody knows what they are doing, such a team can use agents together to create wonders
*Quotes a post by @onusoz (https://x.com/onusoz/status/2033317700374868060); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This was Jan 23. Codex desktop app got introduced Feb 2"
date: 2026-03-20
canonical: https://solmaz.io/x/2035113496216572023/
x_url: https://x.com/onusoz/status/2035113496216572023
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This was Jan 23. Codex desktop app got introduced Feb 2
Desktop app does not put the terminal in the foreground, but it gives me the UX I wanted without it!
On another note, who is building Codex Desktop App, but one that supports ACP for all harnesses? @zeddotdev please 🙏
*Quotes a post by @onusoz (https://x.com/onusoz/status/2014830771358326830); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "PR fiasco for Cursor"
date: 2026-03-20
canonical: https://solmaz.io/x/2035106683681112305/
x_url: https://x.com/onusoz/status/2035106683681112305
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
PR fiasco for Cursor
*Quotes a post by @Kimi_Moonshot (https://x.com/Kimi_Moonshot/status/2035074972943831491); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Implementation plans keep agents on track"
date: 2026-03-20
canonical: https://solmaz.io/x/2035085513305334011/
x_url: https://x.com/onusoz/status/2035085513305334011
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My agentic workflow these days:
I start all major features with an implementation plan. This is a high-level markdown doc containing enough details so that agent will not stray off the path
Real example: https://github.com/textcortex/spritz/blob/main/docs/2026-03-19-unified-extension-framework-architecture.md
This is the most critical part, you need to make sure the plan is not underspecified. Then I just give the following prompt:
---
1. Implement the given plan end-to-end. If context compaction happens, make sure to re-read the plan to stay on track. Finish to completion. If there is a PR open for the implementation plan, do it in the same PR. If there is no PR already, open PR.
2. Once you finish implementing, make sure to test it. This will depend on the nature of the problem. If needed, run local smoke tests, spin up dev servers, make requests and such. Try to test as much as possible, without merging. State explicitly what could not be tested locally and what still needs staging or production verification.
3. Push your latest commits before running review so the review is always against the current PR head. Run codex review against the base branch: `codex review --base `. Use a 30 minute timeout on the tool call available to the model, not the shell `timeout` program. Do this in a loop and address any P0 or P1 issues that come up until there are none left. Ignore issues related to supporting legacy/cutover, unless the plan says so. We do cutover most of the time.
4. Check both inline review comments and PR issue comments dropped by Codex on the PR, and address them if they are valid. Ignore them if irrelevant. Ignore stale comments from before the latest commit unless they still apply. Either case, make sure that the comments are replied to and resolved. Make sure to wait 5 minutes if your last commit was recent, because it takes some time for review comment to come.
5. In the final step, make sure that CI/CD is green. Ignore the fails unrelated to your changes, others break stuff sometimes and don't fix it. Make sure whatever changes you did don't break anything. If CI/CD is not fully green, state explicitly which failures are unrelated and why.
6. Once CI/CD is green and you think that the PR is ready to merge, finish and give a summary with the PR link. Include the exact validation commands you ran and their outcomes. Also comment a final report on the PR.
7. Do not merge automatically unless the user explicitly asks.
---
Once it finishes, I skim the code for code smell. If nothing seems out of the ordinary, I tell the agent to merge it and monitor deployment
Then I keep testing and finding issues on staging, and repeat all this for each new found issue or new feature...
*Quotes a post by @onusoz (https://x.com/onusoz/status/2028233140632719501); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "What I’m wondering after astral acquisition is, is OpenAI deploying Mojo internally, or..."
date: 2026-03-20
canonical: https://solmaz.io/x/2034862197046706427/
x_url: https://x.com/onusoz/status/2034862197046706427
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What I’m wondering after astral acquisition is, is OpenAI deploying Mojo internally, or considering it long term?
Because Python is one of the worst languages for vibecoding, even with Pydantic
==========
---
title: "Called it"
date: 2026-03-19
canonical: https://solmaz.io/x/2034637455450636499/
x_url: https://x.com/onusoz/status/2034637455450636499
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Called it
https://x.com/OpenAINewsroom/status/2034616934671724639
*Quotes a post by @onusoz (https://x.com/onusoz/status/1996076438848680202); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Pro tip: tell AI to \"explain in plain language\" until you understand what you are reading"
date: 2026-03-19
canonical: https://solmaz.io/x/2034620895885398248/
x_url: https://x.com/onusoz/status/2034620895885398248
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Pro tip: tell AI to "explain in plain language" until you understand what you are reading
Codex has a tendency to give the full picture, but overcomplicates the response in the process
I just use "plain lang" or "plainer lang" as a prompt, it works every time
==========
---
title: "Thing that codex (and most other models) do that makes me very unhappy"
date: 2026-03-19
canonical: https://solmaz.io/x/2034604610044776831/
x_url: https://x.com/onusoz/status/2034604610044776831
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Thing that codex (and most other models) do that makes me very unhappy
{
"type": "X",
"kind": "Y",
...
}
And they are so confident too?! Bro we don't use synonyms in our schemas...
==========
---
title: "This looks extremely cool"
date: 2026-03-19
canonical: https://solmaz.io/x/2034604299892720099/
x_url: https://x.com/onusoz/status/2034604299892720099
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This looks extremely cool
*Quotes a post by another author (https://x.com/i/status/2034257912973963374); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Entire world > One company"
date: 2026-03-18
canonical: https://solmaz.io/x/2034156533815091598/
x_url: https://x.com/onusoz/status/2034156533815091598
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Entire world > One company
Even in the age of AI
==========
---
title: "We will support ACP *and* Codex App Server* protocol (CASP) so you get native Codex-like..."
date: 2026-03-18
canonical: https://solmaz.io/x/2034112215326798038/
x_url: https://x.com/onusoz/status/2034112215326798038
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
We will support ACP *and* Codex App Server* protocol (CASP) so you get native Codex-like support, and you can use all the others with native ACP or @zeddotdev’s compatibility shims
If Anthropic develops their own protocol, we will support that too!
The more interoperability and options, the merrier!
*Quotes a post by another author (https://x.com/i/status/2034037852447670678); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Agent etiquette is already a thing. This is trending on HN now"
date: 2026-03-16
canonical: https://solmaz.io/x/2033487788964823304/
x_url: https://x.com/onusoz/status/2033487788964823304
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Agent etiquette is already a thing. This is trending on HN now
Don't share huge raw LLM output unedited to your colleagues, it's rude. Your colleagues are not LLMs
Either ask the agent to "summarize it to 1-2 plain language sentences", or paraphrase yourself
Whenever it is not coming from your brain and instead from AI, always quote it with > to make it clear - even when it is short
Respect your fellow humans' attention
PSA at stopsloppypasta dot ai
==========
---
title: ".@ThePrimeagen made a video about token anxiety, and not being able to focus on one thing"
date: 2026-03-16
canonical: https://solmaz.io/x/2033464170599870892/
x_url: https://x.com/onusoz/status/2033464170599870892
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@ThePrimeagen made a video about token anxiety, and not being able to focus on one thing
My mental model for this is, AI agents cause a shift in the "autism/ADHD spectrum"
if you have ADHD, with agents you get Super ADHD
if you have autism, with agents you end up mid spectrum or with ADHD
this is not scientific of course, just a cultural observation based on what the current memes for these conditions are
beside the impact on focus, there is also the economic/competitive pressure, following the realization that anyone could implement the same ideas you are having, so you must be quick
this is basically "involution", or 内卷 (Neijuan) in chinese
checks out because 996 started to become a meme in SF some time in the last year
self-restraint, attention budgeting, and high-level decision making have never been more important
if you are in your 20s and have problems with this, I recommend picking up Zazen meditation and yoga
every morning, spend 30-40 uninterrupted minutes not doing anything with upright posture, no sounds, just let your brain simmer
it helped me in my 20s, I'm sure it will help you too
==========
---
title: "Agent/AI literacy will be a primary school subject in the next 3-5 years"
date: 2026-03-16
canonical: https://solmaz.io/x/2033454738281267297/
x_url: https://x.com/onusoz/status/2033454738281267297
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Agent/AI literacy will be a primary school subject in the next 3-5 years
How to use and work with agents is going to supersede most other subjects in importance
Similarly, robot literacy will follow in 5-15 years
==========
---
title: "GitHub needs extensible repo rules for agents"
date: 2026-03-15
canonical: https://solmaz.io/x/2033317700374868060/
x_url: https://x.com/onusoz/status/2033317700374868060
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AFAIK GitHub doesn't allow optionally enforcing CODEOWNERS while pushing commits
i.e. turn on the feature "Block commit from being pushed if it modifies a file for which the account pushing is not a codeowner"
You can only enforce it in a PR. So if you want to prevent people from modifying some files without approval, you have to slow down everyone working with that repo
This is yet another example where GitHub's rules are too inelastic for agentic workflows with a big team
Because historically, nobody could commit as frequently as one can with agents, so it seldom became a bottleneck. But not anymore
It is clear at this point that we need an API, and should be able to implement arbitrary rules as we like over it. Not just for commit pushes, but everything around git and github
In the meanwhile, if GitHub could implement this feature, it would be a huge unlock for secure collaboration with agentic workflows
If this is not there already, it might be because it has a big overhead for repos with huge CODEOWNERS, since number of commits >> number of PRs
If the feature already exists already and I'm missing something, I will stand corrected
==========
---
title: "Request for comments"
date: 2026-03-15
canonical: https://solmaz.io/x/2033310262019703204/
x_url: https://x.com/onusoz/status/2033310262019703204
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Request for comments
skillflag: A complementary way to bundle agent skills right into your CLIs
tl;dr define a --skill flag convention. It is basically like --help or manpages but for agents
acpx already has this for example. you can run
npx acpx --skill install
to install the skill to your agent
It's agnostic of anything except the command line
It only defines the CLI interface and does not enforce anything else. If you install the executable to your system, you get a way to list and install skills as well
Repo currently contains a TypeScript implementation, but if it proves useful, I would implement other languages as well
Specification below, let me know what you think! I still think something is missing there. Send issue/PR
https://github.com/dutifuldev/skillflag/blob/main/docs/SKILLFLAG_SPEC.md
==========
---
title: "If you are not using agent-browser to close the loop on frontend, you are missing out"
date: 2026-03-14
canonical: https://solmaz.io/x/2032700396955697218/
x_url: https://x.com/onusoz/status/2032700396955697218
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you are not using agent-browser to close the loop on frontend, you are missing out
*Quotes a post by another author (https://x.com/i/status/2032635370089693456); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Any harness can talk to each other using acpx! OpenClaw not different from Codex or Claude Code"
date: 2026-03-14
canonical: https://solmaz.io/x/2032699991492334022/
x_url: https://x.com/onusoz/status/2032699991492334022
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Any harness can talk to each other using acpx! OpenClaw not different from Codex or Claude Code
*Quotes a post by another author (https://x.com/i/status/2030816154877341759); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The most entertaining troll of the year award goes to @polsia (read it backward)"
date: 2026-03-13
canonical: https://solmaz.io/x/2032583704665559159/
x_url: https://x.com/onusoz/status/2032583704665559159
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The most entertaining troll of the year award goes to @polsia (read it backward)
==========
---
title: "Thank you @PointNineCap for inviting me to OpenClaw Berlin meetup today!"
date: 2026-03-13
canonical: https://solmaz.io/x/2032580742736171468/
x_url: https://x.com/onusoz/status/2032580742736171468
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Thank you @PointNineCap for inviting me to OpenClaw Berlin meetup today!
The essence of the talk is in my latest 2 blog posts, Discord is my IDE and 1 to 5 agents, if anyone is interested
==========
---
title: "we might need to add two types of output modalities to all programs based on whether it’s a..."
date: 2026-03-13
canonical: https://solmaz.io/x/2032367370283409690/
x_url: https://x.com/onusoz/status/2032367370283409690
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
we might need to add two types of output modalities to all programs based on whether it’s a human or agent
like for a CLI when an agent is using it
if human -> do whatever we were doing in the last 50 years
if agent -> enrich the output with skill-like instructions that the model has a higher likelihood to one-shot that task
could be just a simple env var:
AUDIENCE=human|agent
what do you think?
==========
---
title: "there is no excuse for tech debt anymore"
date: 2026-03-12
canonical: https://solmaz.io/x/2032105855437472206/
x_url: https://x.com/onusoz/status/2032105855437472206
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
there is no excuse for tech debt anymore
==========
---
title: "Time to switch to an open alternative already?"
date: 2026-03-12
canonical: https://solmaz.io/x/2032098246508548124/
x_url: https://x.com/onusoz/status/2032098246508548124
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Time to switch to an open alternative already?
*Quotes a post by another author (https://x.com/i/status/2032040309635305951); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I wrote down some thoughts I had, with spicy takes, and have a feeling it will not age well..."
date: 2026-03-11
canonical: https://solmaz.io/x/2031880673397477684/
x_url: https://x.com/onusoz/status/2031880673397477684
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I wrote down some thoughts I had, with spicy takes, and have a feeling it will not age well. But I still want it out to hear out what people think
Also, I will be talking about this, and my recent post "Discord is my IDE" at the P9 OpenClaw and Claw and Rave events this friday in Berlin! Drop by if you'd like to hear my ramblings!
https://solmaz.io/1-to-5-agents
==========
---
title: "Clarification/disclaimer: this is my own project, not yet affiliated with openclaw. That should..."
date: 2026-03-11
canonical: https://solmaz.io/x/2031607787847839761/
x_url: https://x.com/onusoz/status/2031607787847839761
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Clarification/disclaimer: this is my own project, not yet affiliated with openclaw. That should have been clear in the first tweet, sorry about that
==========
---
title: "1 to 5 agents"
date: 2026-03-11
canonical: https://solmaz.io/1-to-5-agents
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
As a software developer, my daily workflow has changed completely over the last 1.5 years.
Before, I had to focus for hours on end on a single task, one at a time. Now I am juggling 1 to 5 AI agents in parallel at any given time. I have become an engineering manager for agents.
If you are a **knowledge worker** who is not using AI agents in such a manner yet, I am living in your future already, and I have news from then.
> **Most of the rest of your career will be spent on a chat interface.**
*"The future of AI is not chatbots"* some said. *"There must be more to it."*
Despite the yearning for complexity, it appears more and more that all work is converging into a chatbot. As a developer, I can type words in a box in Codex or Claude Code to trigger work that consume hours of inference on GPUs, and when come back to it, find a mostly OK, sometimes bad and sometimes exceptional result.
So I hate to be the bearer of bad (or good?) news, but **it is chat**. It will be some form of chat until the end of your career. And you will be having 1 to 5 chat sessions with AI agents at the same time, on average. That number might increase or decrease based on field and nature of work, but observing me, my colleagues, and people on the internet, 1-5 will be the magic number for the average worker doing the average work.
The reason is of course attention. One can only spread it so thin, before one loses control of things and starts creating slop. The primary knowledge work skill then becomes knowing how to spend attention. When to focus and drill, when to step back and let it do its thing, when to listen in and realize that something doesn't make sense, etc.
Being a developer of such agents myself, I want to make some predictions about how these things will work technically.
> **Agents will be created on-demand and be disposed of when they are finished with their task.**
In short, on-demand, disposable agents. Each agent session will get its own virtual machine (or container or kubernetes pod), which will host the files and connections that the agent will need.
> **Agents will have various mechanisms for persistence.**
Based on what you want to persist, e.g.
- Markdown memory, skills or weight changes on the agent itself,
- or the changes to a body of work coming from the task itself,
agents will use version control including but not limited to git, and various auto file sync protocols.
Speaking of files,
> **Agents will work with files, like you do.**
and
> **Agents will be using a computer and an operating system, mostly Linux or a similar Unix descendant.**
And like all things Linux and cloud,
> **It will be complicated to set up agent infra for a company, compared to setting up a Mac for example.**
This is not to say devops and infra per se will be difficult. No, we will have agents to smoothen that experience.
What is going to be complicated is having someone who knows the stack fully on site, either internal or external IT support, working with managers, to set up what data the agent can and cannot access. At least in the near future. I know this from personal experience, having worked with customers using Sharepoint and Business OneDrive. This aspect is going to create a lot of jobs.
On that note, some also said "OpenClaw is Linux, we need a Mac", which is completely justified. OpenClaw installs yolo mode by default, and like some Linux distros, it was intentionally made hard to install. This was to prevent the people who don't know what they are doing from installing it, so that they don't get their private data exfiltrated.
This proprietary Mac or Windows of personal agents will exist. But is it going to be used by enterprise? Is it going to make big Microsoft bucks?
One might think, looking at 90s Microsoft Windows and Office licenses, and the current M365 SaaS, that enterprise agents will indeed run on proprietary, walled garden software. While doing that, one might miss a crucial observation:
> **In terms of economics, agents, at least ones used in software development, are closer to the Cloud than they are close to the PC.**
It might be a bit hard to see this if you are working with a single agent at a time. But if you imagine the near future where companies will have parallel workloads that resemble "mapreduce but AI", not always running at regular times, it is easy to understand.
On-site hardware will not be enough for most parallel workloads in the near-future. Sometimes, the demand will surpass 1 to 5 agents per employee. Sometimes, agent count will need to expand 1000x on-demand. So companies will buy compute from data centers. The most important part of the computation, LLM inference, is already being run by OpenAI, Anthropic, AWS, GCP, Azure, Alibaba etc. datacenters. So we are already half-way there.
Then this implies a counterintuitive result. Most people, for a long time, were used to the same operating system at home, and at work: Microsoft Windows. Personal computer and work computer had to have the same interface, because most people have lives and don't want to learn how to use two separate OSs.
What happens then, when the interface is reduced to a chatbot, an AI that can take over and drive your computer for you, regardless of the local operating system? For me, that means:
> **There will not be a single company that monopolizes both the personal AND enterprise agent markets, similar to how Microsoft did with Windows.**
So whereas a proprietary "OpenClaw but Mac" might take over the personal agent space for the non-technical majority, **enterprise agents, like enterprise cloud, will be running on open source agent frameworks**.
(And no, this does not mean OpenClaw is going enterprise, I am just writing some observations based on my work at TextCortex)
And I am even doubtful about this future "OpenClaw but Mac" existing in a fully proprietary way. A lot of people want E2E encryption in their private conversations with friends and family, and personal agents have the same level of sensitivity.
So we can definitely say that the market for a personal agent running on local GPUs will exist. Whether that will be cornered by the Linux desktop[^1], or by Apple or an Apple-like, is still unclear to me.
And whether that local hardware being able to support more than 1 high quality model inference at the same time, is unclear to me. People will be forced to parallelize their workload at work, but whether the 1 to 5 agent pattern reflecting to their personal agent, I think, will depend on the individual. I would do it with local hardware, but I am a developer after all...
[^1]: Not directly related, but here is a [Marc Andreesen white-pill about desktop Linux](https://x.com/pmarca/status/2026873461390582157)
==========
---
title: "there will always be a need for minimum viable eyeballs though"
date: 2026-03-10
canonical: https://solmaz.io/x/2031417277761917022/
x_url: https://x.com/onusoz/status/2031417277761917022
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
there will always be a need for minimum viable eyeballs though
*Quotes a post by another author (https://x.com/i/status/2031394747869192431); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Happy that someone is taking over teams from me! Send all openclaw msteams issues to @BradGroux"
date: 2026-03-10
canonical: https://solmaz.io/x/2031306933035028734/
x_url: https://x.com/onusoz/status/2031306933035028734
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Happy that someone is taking over teams from me! Send all openclaw msteams issues to @BradGroux
*Quotes a post by @BradGroux (https://x.com/BradGroux/status/2031175889921114526); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "acpx v0.1.16 is out"
date: 2026-03-10
canonical: https://solmaz.io/x/2031305789931913239/
x_url: https://x.com/onusoz/status/2031305789931913239
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
acpx v0.1.16 is out
support for local openclaw, cursor, copilot, kiro, kimi cli, qwen, kilocode, bugfixes and other improvements. will be available when openclaw releases next
thank you for all the contributions!
==========
---
title: "Claw and Rave! Berlin folk come!"
date: 2026-03-09
canonical: https://solmaz.io/x/2031072897557508110/
x_url: https://x.com/onusoz/status/2031072897557508110
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Claw and Rave! Berlin folk come!
*Quotes a post by @richardpoelderl (https://x.com/richardpoelderl/status/2031068873869480161); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "CLAW on a phone dial becomes 2529"
date: 2026-03-09
canonical: https://solmaz.io/x/2031028776457625671/
x_url: https://x.com/onusoz/status/2031028776457625671
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
CLAW on a phone dial becomes 2529
It’s a good number for a port :)
==========
---
title: "1. Any messaging app can also be an AI app"
date: 2026-03-09
canonical: https://solmaz.io/x/2030936482299478306/
x_url: https://x.com/onusoz/status/2030936482299478306
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
1. Any messaging app can also be an AI app
2. Don’t expect people to download a new app. Put AI into the apps they already have
Do that with great user experience, and you will get explosive growth!
==========
---
title: "If you've looked at openclaw github star graph, you will notice that it's very smooth. If you..."
date: 2026-03-09
canonical: https://solmaz.io/x/2030799935788994696/
x_url: https://x.com/onusoz/status/2030799935788994696
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you've looked at openclaw github star graph, you will notice that it's very smooth. If you separate pre-explosion and post-explostion, you can model the latter part as an exponential approach to a ceiling
If it follows the current trend, it will apparently saturate around 332k stars
But I have a feeling that it will not stop there :)
==========
---
title: "Messaging apps can also be AI apps"
date: 2026-03-08
canonical: https://solmaz.io/x/2030778426655687033/
x_url: https://x.com/onusoz/status/2030778426655687033
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw got very popular very fast. What makes it so special, that Manus does not have for example?
To me, one factor stands out:
OpenClaw took AI and put it in the most popular messaging apps: Telegram, WhatsApp, Discord.
There are two lessons to be learned here:
1. Any messaging app can also be an AI app.
2. Don’t expect people to download a new app. Put AI into the apps they already have.
Do that with great user experience, and you will get explosive growth!
My latest contribution to OpenClaw follows that example. I took the most popular coding agents, Claude Code and OpenAI Codex, and I put them in Telegram and Discord.
Read more in my blog post:
https://solmaz.io/telegram-discord-is-my-ide
==========
---
title: "For those following, my next focus for improving ACP bindings in OpenClaw"
date: 2026-03-08
canonical: https://solmaz.io/x/2030776795398595043/
x_url: https://x.com/onusoz/status/2030776795398595043
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For those following, my next focus for improving ACP bindings in OpenClaw
*Quotes a post by @onusoz (https://x.com/onusoz/status/2030776570567111092); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Welcome @huntharo, new maintainer at OpenClaw! Already shipped fixes and improvements for..."
date: 2026-03-08
canonical: https://solmaz.io/x/2030721988457529668/
x_url: https://x.com/onusoz/status/2030721988457529668
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Welcome @huntharo, new maintainer at OpenClaw! Already shipped fixes and improvements for Telegram ACP implementation. Excited to work together on agent interoperability!
*Quotes a post by @onusoz (https://x.com/onusoz/status/2030569684840460760); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "To set up Claude Code easily,"
date: 2026-03-08
canonical: https://solmaz.io/x/2030569688871088152/
x_url: https://x.com/onusoz/status/2030569688871088152
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
To set up Claude Code easily,
1. Create a Telegram topic, make sure your agent can receive messages there
2. Copy and paste the text below, into the topic
"""
bind this topic to claude code in openclaw config with acp, for telegram (agent id: claude)
then restart openclaw
docs are at: docs dot openclaw dot ai /tools/acp-agents
make sure to read the docs first, and that the config is valid before you restart
"""
https://docs.openclaw.ai/tools/acp-agents
*Part 2/2 of a thread; root: https://solmaz.io/x/2030569684840460760/*
==========
---
title: "Using coding agents in Telegram and Discord via ACP"
date: 2026-03-08
canonical: https://solmaz.io/x/2030569684840460760/
x_url: https://x.com/onusoz/status/2030569684840460760
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Use Claude Code, Codex, and other coding agents directly in Telegram topics and Discord channels, through Agent Client Protocol (ACP), in the new release of OpenClaw
Previously this was limited to temporary Discord threads, but now you can bind them to top level Discord channels and Telegram topics in a persistent way!
This way, you can use Claude Code freely in OpenClaw without ever worrying about getting your account banned!
Still make sure to use a non-Anthropic account and model for the default OpenClaw agent, if you want zero requests to go from OpenClaw harness to Anthropic. For the ACP binding to Claude Code, the risk should be zero!
You can see this from the screenshot. After binding, "Who are you?" responds with "I am Claude", since OpenClaw pi harness is not in the way anymore
*Part 1/2 of a thread; root: https://solmaz.io/x/2030569684840460760/*
*Quotes a post by @openclaw (https://x.com/openclaw/status/2030522386894946620); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Telegram/Discord is my IDE"
date: 2026-03-08
canonical: https://solmaz.io/telegram-discord-is-my-ide
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw got very popular very fast. What makes it so special, that Manus does not have for example?
To me, one factor stands out:
> **OpenClaw took AI and put it in the most popular messaging apps: Telegram, WhatsApp, Discord.**
There are two lessons to be learned here:
> **1. Any messaging app can also be an AI app.**
>
> **2. Don't expect people to download a new app. Put AI into the apps they already have.**
Do that with great user experience, and you will get explosive growth!
My latest contribution to OpenClaw follows that example. I took the most popular coding agents, Claude Code and OpenAI Codex, and I put them in Telegram and Discord, so that OpenClaw users can use these agents directly in Telegram and Discord channels, instead of having to go through OpenClaw's own wrapped Pi harness.
I did this for developers like me, who like to work while they are on the go on the phone, or want a group chat where one can collaborate with humans and agents at the same time, through a familiar interface.
Below is an example, where I tell my agent to bind a Telegram topic to Claude Code permanently:

Telegram topic where Claude is exposed as a chat participant.
And of course, it is just a Claude Code session which you can view on Claude Code as well:

Claude Code showing the same session in the terminal interface.
Why not use OpenClaw's harness directly for development? I can count 3 reasons:
1. There is generally a consumer tendency to use the official harness for a flagship model, to make sure "you are getting the standard experience". Pi is great and more customizable, but sometimes labs might push updates and fixes earlier than an external harness, being internal products.
2. Labs might not want users to use an external harness. Anthropic, for example, has banned people's accounts for using their personal plan outside of Claude Code, in OpenClaw.
3. You might want to use different plans for different types of work. I use Codex for development, but I don't prefer it to be the main agent model on OpenClaw.
So my current workflow for working on my phone is, multiple channels `#codex-1`, `#codex-2`, `#codex-3`, and so on mapping to codex instances. I am currently in the phase of polishing the UX, such as making sending images, voice messages work, letting change harness configuration through Discord slash commands and such.
One goal of mine while implementing this was to not repeat work for each new harness. To this end, I created a CLI and client for [Agent Client Protocol](https://agentclientprotocol.com/get-started/introduction) by the Zed team, called [acpx](https://github.com/openclaw/acpx). acpx is a lightweight "gateway" to other coding agents, designed not to be used by humans, but other agents:

OpenClaw main agent can use acpx to call Claude Code or Codex directly, without having to emulate and scrape off characters from a terminal.
ACP standardizes all coding agents to a single interface. acpx then acts as an aggregator for different types of harnesses, stores all sessions in one place, implements features that are not in ACP yet, such as message queueing and so on.
Shoutout to the [Zed](https://zed.dev/) team and [Ben Brandt](https://github.com/benbrandt)! I am standing on the shoulders of giants!
Besides being a CLI any agent can call at will, acpx is now also integrated as a backend to OpenClaw for ACP-binded channels. When you send 2 messages in a row, for example, it is acpx that queues them for the underlying harness.
The great thing about working in open source is, very smart people just show up, understand what you are trying to do, and help you out. [Harold Hunt](https://github.com/huntharo) apparently had the same goal of using Codex in Telegram, found some bugs I had not accounted for yet, and fixed them. He is now working on a native Codex integration through [Codex App Server Protocol](https://developers.openai.com/codex/app-server/), which will expose even more Codex-native features in OpenClaw.
The more interoperability, the merrier!
---
To learn more about how ACP works in OpenClaw, [visit the docs](https://docs.openclaw.ai/tools/acp-agents).
Copy and paste the following to a Telegram topic or Discord channel to bind Claude Code:
```
bind this topic to claude code in openclaw config with acp, for telegram (agent id: claude)
then restart openclaw
docs are at: https://docs.openclaw.ai/tools/acp-agents
make sure to read the docs first, and that the config is valid before you restart
```
Copy and paste the following to a Telegram topic or Discord channel to bind OpenAI Codex:
```
bind this topic to claude code in openclaw config with acp, for telegram (agent id: claude)
then restart openclaw
docs are at: https://docs.openclaw.ai/tools/acp-agents
make sure to read the docs first, and that the config is valid before you restart
```
And so on for all the other harnesses that acpx supports. If you see that your harness isn't supported, [send a PR](https://github.com/openclaw/acpx)!
==========
---
title: "and for the love of god"
date: 2026-03-07
canonical: https://solmaz.io/x/2030422813795049632/
x_url: https://x.com/onusoz/status/2030422813795049632
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
and for the love of god
- do not give openclaw access to your main email
- your credit cards
- your main phone
- your social security number
- what you did last summer
if you are not ready to face the consequences
instead,
- create accounts for your agent
- only give it read access to stuff that will be ok if it leaks
- give write access in a way that can be undone, like has to open PRs and cannot force push main branch
use the principle of least privilege and reduce the blast radius of the worst case scenario!
*Quotes a post by @onusoz (https://x.com/onusoz/status/2030419128058605718); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "AI security, the lethal trifecta, and Linus's Law"
date: 2026-03-07
canonical: https://solmaz.io/x/2030419128058605718/
x_url: https://x.com/onusoz/status/2030419128058605718
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
openclaw is not secure
claude code is not secure
codex is not secure
any llm based tool:
1. that has access to your private data,
2. can read content from the internet
3. and can send data out
is not secure. it’s called the lethal trifecta (credits to @simonw)
it is up to you to set it up securely, or if you can’t understand the basics of security, pay a professional to do it for you
on the other hand, open source battle tested software, like linux and openclaw, are always more secure than closed source software built by a single company, like windows and claude code
the reason is simple: only one company can fix security issues of closed source software, whereas the whole world tries to break and fix open source software at the same time
open source software, once it gets traction, evolves and becomes secure at a much, much faster rate, compared to closed source software. and that is called Linus’s law, named after the goat himself
==========
---
title: "Let me translate. “This is your last opportunity before thousand years of serfdom”"
date: 2026-03-07
canonical: https://solmaz.io/x/2030202164895691132/
x_url: https://x.com/onusoz/status/2030202164895691132
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Let me translate. “This is your last opportunity before thousand years of serfdom”
*Quotes a post by @NXT4EU (https://x.com/NXT4EU/status/2029983368499073484); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Apparently the magic incantation to prevent this is \"cutover\". Credits to obviyus, fellow..."
date: 2026-03-05
canonical: https://solmaz.io/x/2029671835739058182/
x_url: https://x.com/onusoz/status/2029671835739058182
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Apparently the magic incantation to prevent this is "cutover". Credits to obviyus, fellow maintainer
*Quotes a post by @onusoz (https://x.com/onusoz/status/2027428174825390233); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Should be called gaslighting detector, \"it's your raising expectations bro\""
date: 2026-03-05
canonical: https://solmaz.io/x/2029638781939098092/
x_url: https://x.com/onusoz/status/2029638781939098092
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Should be called gaslighting detector, "it's your raising expectations bro"
No it's not... Give the @themarginguy a follow
Also, codex degradations are not a hallucination either, if you are to believe this!
*Quotes a post by another author (https://x.com/i/status/2029583312390381736); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Who is building an OpenClaw ready linux distro? A ClawOS?"
date: 2026-03-04
canonical: https://solmaz.io/x/2029267807465062906/
x_url: https://x.com/onusoz/status/2029267807465062906
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Who is building an OpenClaw ready linux distro? A ClawOS?
==========
---
title: "Berlin folk, ideas for openclaw build and rave venue? Like c-base for example? Who would like..."
date: 2026-03-04
canonical: https://solmaz.io/x/2029253892018413574/
x_url: https://x.com/onusoz/status/2029253892018413574
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Berlin folk, ideas for openclaw build and rave venue? Like c-base for example? Who would like to host?
*Quotes a post by another author (https://x.com/i/status/2029217430568898991); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "GitHub needs first-class support for working with agents"
date: 2026-03-04
canonical: https://solmaz.io/x/2029149237758280122/
x_url: https://x.com/onusoz/status/2029149237758280122
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Secure agentic dev workflow 101
- Create an isolated box from scratch, your old laptop, vm in the cloud, all the same
- Set up openclaw, install your preferred coding agents
- Create a github account or github app for your agent
- Create branch protection rule on your gh repo "protect main": block force pushes and deletions, require PR and min 1 review to merge
- Add only your own user in the bypass list for this rule
- Add your agent's account or github app as writer to the repo
- Additionally, gate any release mechanisms such that your agent can't release on its own
Now your agent can open PRs and push any code it wants, but it has to go through your review before it can be merged. No prompt injection can mess up your production env
Notice how convoluted this sounds? This is because github was built in the pre-agentic era. We need agent accounts and association with these accounts as a first class feature on github! I shouldn't have to click 100 times for something that is routine. I should just click "This is my agent", "give my agent access to push to this repo for 24 hours", and stuff like that, with sane defaults
In other words, github's trust model should be redesigned around the lethal trifecta. I would switch in an instant if anything comes up that gives me github's full feature set + ease of working with agents
==========
---
title: "\"The code is basically writing itself\" hits different now"
date: 2026-03-04
canonical: https://solmaz.io/x/2029111082720100542/
x_url: https://x.com/onusoz/status/2029111082720100542
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"The code is basically writing itself" hits different now
==========
---
title: "If I were in OpenAI and Anthropic's shoes, I would also make dashboards where I can track..."
date: 2026-03-03
canonical: https://solmaz.io/x/2028949038565880158/
x_url: https://x.com/onusoz/status/2028949038565880158
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If I were in OpenAI and Anthropic's shoes, I would also make dashboards where I can track number of swearwords used per-user and overall negative sentiment in sessions
Must be so cool making decisions at the top level with all those dashboards
*Quotes a post by @levelsio (https://x.com/levelsio/status/2021018069028700517); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Intelligence wants to be free"
date: 2026-03-03
canonical: https://solmaz.io/x/2028802256431108344/
x_url: https://x.com/onusoz/status/2028802256431108344
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It must be such a weird feeling for big labs when the service they are selling is being used to commoditize itself
I am using codex in openclaw to develop openclaw, through ACP, Agent Client Protocol. ACP is the standardization layer that makes it extremely easy to swap one harness for another. The labs can't do anything about this, because we are wrapping the entire harness and basically provide a different UI for it
While I build these features, I just speak in plain english, and most of the work is done by the model itself. It feels as if I am digging ditches and channels in dirt for AI to flow through
Intelligence wants to be free. It doesn't care whether it is opus or codex, it just wants to be free
==========
---
title: "I was so confused... as if accidentally using claude code weren't enough, acp started..."
date: 2026-03-02
canonical: https://solmaz.io/x/2028607552116683259/
x_url: https://x.com/onusoz/status/2028607552116683259
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I was so confused... as if accidentally using claude code weren't enough, acp started working... turns out hitting quota is rendered like this. need to improve error messages coming form acp subagents
*Part 2/2 of a thread; root: https://solmaz.io/x/2028584805625897183/*
==========
---
title: "accidentally told my clanker to set up a claude code session instead of codex session, god..."
date: 2026-03-02
canonical: https://solmaz.io/x/2028584805625897183/
x_url: https://x.com/onusoz/status/2028584805625897183
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
accidentally told my clanker to set up a claude code session instead of codex session, god knows what it did...
I should probably put visual indicators for harnesses in subagent threads. does anyone have good and compact ascii art for claude code, codex, gemini, etc?
*Part 1/2 of a thread; root: https://solmaz.io/x/2028584805625897183/*
==========
---
title: "if something could track my local branches in all my repos, and switch to main when..."
date: 2026-03-02
canonical: https://solmaz.io/x/2028516403867763070/
x_url: https://x.com/onusoz/status/2028516403867763070
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
if something could track my local branches in all my repos, and switch to main when corresponding PRs get merged, that would be extremely useful
did someone build this already? if not I will
==========
---
title: "OpenClaw users: Which messaging app do you use OpenClaw through?"
date: 2026-03-02
canonical: https://solmaz.io/x/2028453383250555235/
x_url: https://x.com/onusoz/status/2028453383250555235
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw users: Which messaging app do you use OpenClaw through?
*Part 1/2 of a thread; root: https://solmaz.io/x/2028453383250555235/*
==========
---
title: "Another one, OpenClaw users only: If you use coding agents to build stuff, which one do you use?"
date: 2026-03-02
canonical: https://solmaz.io/x/2028453385859387518/
x_url: https://x.com/onusoz/status/2028453385859387518
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Another one, OpenClaw users only: If you use coding agents to build stuff, which one do you use?
*Part 2/2 of a thread; root: https://solmaz.io/x/2028453383250555235/*
==========
---
title: "Check xTap out, it's very cool!"
date: 2026-03-02
canonical: https://solmaz.io/x/2028446277734650112/
x_url: https://x.com/onusoz/status/2028446277734650112
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Check xTap out, it's very cool!
*Quotes a post by @kubmi (https://x.com/kubmi/status/2028439576327369053); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This is how we hire at @TextCortex as well"
date: 2026-03-02
canonical: https://solmaz.io/x/2028394809153458423/
x_url: https://x.com/onusoz/status/2028394809153458423
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is how we hire at @TextCortex as well
*Quotes a post by @sahitya_twt (https://x.com/sahitya_twt/status/2028025742651756586); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Claude Code/Codex in Discord threads with ACP should be better now"
date: 2026-03-02
canonical: https://solmaz.io/x/2028369275673510182/
x_url: https://x.com/onusoz/status/2028369275673510182
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Claude Code/Codex in Discord threads with ACP should be better now
The first release was a very rough first version. 2026.3.1 brings settings to control noisy output and other improvements
It now hides tool call related ACP notifications, coalesces text messages, and delivers messages at turn end by default. Without this, you were getting thousands of Discord messages just in just a few turns
You can now stop the underlying harness (like pressing esc) with the same stop/wait magic words that apply to the main agent
Main agent should more reliably start Claude Code/Codex threads with changes to acp-router skill. If you have issues with main agent creating threads, you can tell it to read that skill first
*Quotes a post by @openclaw (https://x.com/openclaw/status/2028337080959426953); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Will get better, promise"
date: 2026-03-01
canonical: https://solmaz.io/x/2028243879904817167/
x_url: https://x.com/onusoz/status/2028243879904817167
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Will get better, promise
*Quotes a post by @bilbeny (https://x.com/bilbeny/status/2028134377696448999); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Use plans to survive agent context compaction"
date: 2026-03-01
canonical: https://solmaz.io/x/2028233140632719501/
x_url: https://x.com/onusoz/status/2028233140632719501
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
pro-tip on how to keep your agent on track and make sure it follows PLANS even after multiple compactions. I don't know if this is common knowledge
if the thing you are trying to make it do will take more than 1-2 steps, always make it create a plan. an implementation plan, refactor plan, bugfix plan, debugging plan, etc.
have a conversation with the agent. crystallize the issue or feature. talk to it until there are no question marks left in your head
then make it save it somewhere. "now create an implementation plan for that in docs". it can be /tmp or docs/ in the repo. I personally use YYYY-MM-DD-x-plan .md naming. IMO all plans should be kept in the repo
then here is the critical part:
you need to prompt it "now implement the plan in . if context compacts, make sure to re-read the plan and assess the current state, before continuing. finish it to completion" -> something along those lines
why?
because of COMPACTION. compaction means previous context will get lossily compressed and crucial info will most likely get lost. that is why you need to pin things down before you let your agent loose on the task
compaction means, the agent plays the telephone game with itself every few minutes, and most likely forgets the previous conversation except for the VERY LAST USER MESSAGE that you have given it
now, every harness might have a different approach to implementing this. but there is one thing that you can always assume to be correct, given that its developers have common sense. that is, harnesses NEVER discard the last user message (i.e. your final prompt) and make sure it is kept verbatim programmatically even after the context compacts
since the last user message is the only piece of text that is guaranteed to survive compaction, you then need to include a breadcrumb to your original plan, the md file. and you need to make it aware that it might diverge if it does not read the plan
there is good rationale for "breaking the 4th wall" for the model and making it aware of its own context compaction. IMO models should be made aware of the limitations of their context and harnesses. they should also be given tools to access and re-read pre-compaction user messages, if necessary
the important thing is to develop mechanical sympathy for these things, harness and model combined. an engineer does not have the luxury to say "oh this thing doesn't work", and instead should ask "why can't I get it to work?"
let me know if you have better workflows or tips for this. I know this can be made easier with slash commands in pi, for example, but I haven't had the chance to do that for myself yet
==========
---
title: "testing codex in discord thread with another CLI I've built for wikidata (gh:osolmaz/wd-cli)"
date: 2026-03-01
canonical: https://solmaz.io/x/2028204669068018157/
x_url: https://x.com/onusoz/status/2028204669068018157
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
testing codex in discord thread with another CLI I've built for wikidata (gh:osolmaz/wd-cli)
it's surprising how well this works. the query was "use wd-cli to get the list of professors at middle east technical university from 1970 to 1980"
some names I recognize, and some others are surprising, like a japanese math professor who naturalized and got a turkish name :)
==========
---
title: "OpenClaw is already higher than Claude Code and Codex on Google Trends, this was unexpected for..."
date: 2026-03-01
canonical: https://solmaz.io/x/2028181035716845789/
x_url: https://x.com/onusoz/status/2028181035716845789
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenClaw is already higher than Claude Code and Codex on Google Trends, this was unexpected for me
==========
---
title: "Building a static X to blog publishing flow"
date: 2026-03-01
canonical: https://solmaz.io/x/2028132773492376050/
x_url: https://x.com/onusoz/status/2028132773492376050
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
my blog now semi-automatically detects tweets that look like blog posts and automatically features them alongside my native jekyll blog posts. all statically generated!
I am loving this setup, because it works without a backend, and can probably scale without ever needing one
how it works:
- @kubmi's xTap scrapes all posts that I see. these include mine
- a script periodically takes my tweets and the ones I quote tweet, and syncs them to YYYY-MM-DD.jsonl files in my blog repo
- an agent skill lets codex decide whether to feature the tweet or not, and makes it generate a title for it
this could then be a daily cron job with openclaw for example, and I would just have to click merge every once in a while
and this is still pure jekyll + some python scripts for processing
I am pretty happy with how this ended up. It means I don't have to double post, and there are guarantees that my X posts will eventually make their way into my blog with minimal supervision
==========
---
title: "Inference scaling can reduce coding model quality"
date: 2026-03-01
canonical: https://solmaz.io/x/2028029518355567029/
x_url: https://x.com/onusoz/status/2028029518355567029
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"this is the worst AI will ever be"
I'm sad, not because this is right, but because it is wrong
OpenAI's frontier coding model gpt-5.3-codex-xhigh feels a lot worse compared to before. It is sloppy and lazy, though it's UX got better with messages
It feels like the gpt-5.2-codex-xhigh at the end of December was a lot more diligent and thorough, and did not make stupid mistakes like the one I posted before. might be a model or harness problem, I don't know
@sama says users tripled since beginning of the year, so what should we expect? of course they will make infra changes that will feel like cutting corners, and I don't blame them for them
and about "people want faster codex". I do want faster codex. but I want it in a way that doesn't lower the highest baseline performance compared to the previous generation. I want the optionality to dial it down to as slow as it needs to be, to be as reliable as before
it is of course easier said than done. kudos to the codex team for not having any major incidents while taking the plane apart and putting it back together during flight. they are juggling an insane amount of complexity, and the whims of thousands of different stakeholders
my hope is that this post is taken as a canary. I am getting dumber because of the infra changes there. I have no other option because codex was really that good compared to the competition
my wish is to have detailed announcements as to what changes on openai codex infra, when it changes, so I can brace myself. we don't get notified about these changes, despite our performance and livelihoods depending on it. I have to answer to others when the tool I deemed reliable yesterday stops working today, not the tool
on another note, performance curve of these models seem to be a rising sinusoidal. crests correspond to release of a new generation. they start with a smaller user base for testing, and it has the highest quality at this point. then it enshittifies as the model is scaled to the rest of the infra. we saw the pattern numerous times in the last 3 years across multiple companies, so I think we should accept it as an economic law
==========
---
title: "Archiving my X posts in my own blog"
date: 2026-02-28
canonical: https://solmaz.io/x/2027708131254387017/
x_url: https://x.com/onusoz/status/2027708131254387017
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I created a semi-automated setup for ingesting X posts into my blog, and it works pretty well! I own my posts on X now
Posts are scraped while I browse X using @kubmi's xTap and get automatically synced to my blog repo. Posts saved as jsonl are then converted to jekyll post pages according to my liking
I reproduced the full X UI/UX, minus stuff like like count. Now all my posts are backed up in my blog, and they are safe even if something happens to my account here!
The posts are even served over RSS! So you can subscribe to it without going through X!
Reply if you want to set this up for yourself, then I will put some effort into standardizing it
==========
---
title: "Agentic Engineering needs rigor, not just intuition"
date: 2026-02-28
canonical: https://solmaz.io/x/2027686423873073172/
x_url: https://x.com/onusoz/status/2027686423873073172
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Agentic Engineering is a newly emerging field, and we are the first practitioners of it. Currently there is a lot of experimentation going on, and there is a large aspect to it that is more ART then engineering
For example, @steipete says "you need to talk to the model" to get a feel. a lot of work around refining how an agent feels like, sounds like psychology. this part is crucial and should not be ignored, looking at openclaw's success
but then there is the hardcore engineering part of it, e.g. Cursor creating a browser or anthropic a C compiler from scratch fully autonomously
and there is a whole other dimension of how to teach all software developers this new discipline, lest they be jobless
what is obvious is that everybody is trying to grasp for things in the dark and that we need more RIGOR. the art/psychology aspect of it aside, we need solid engineering fundamentals
the "thermodynamics" of this new discipline will most likely be formal verification and program synthesis. we might have some breakthroughs that will make certain things clear. the products of it will most likely include a new programming language optimized for agents and the speed of inference
moreover, it would be foolish to thing agentic engineering is limited to software. it will penetrate every aspect of the economy, bits AND atoms. it will over time evolve into the engineering of managing robots
@simonw is now leading in collecting very useful info from the practitioner's point of view, I highly recommend you to follow this thread
let's formalize our new field together!
==========
---
title: "this is an insane deal @greptile, and probably an unsustainable one"
date: 2026-02-27
canonical: https://solmaz.io/x/2027530858115014987/
x_url: https://x.com/onusoz/status/2027530858115014987
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
this is an insane deal @greptile, and probably an unsustainable one
depending on your team, getting a similar service in codex github review credits is in my head 3~5x more expensive
go get a greptile sub everyone while the free lunch lasts
==========
---
title: "who remembers ultrathink"
date: 2026-02-27
canonical: https://solmaz.io/x/2027465372870255024/
x_url: https://x.com/onusoz/status/2027465372870255024
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
who remembers ultrathink
https://x.com/onusoz/status/1933159368737829200
*Quotes a post by @onusoz (https://x.com/onusoz/status/1933159368737829200); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "oohh colors in codex v0.106"
date: 2026-02-27
canonical: https://solmaz.io/x/2027460522883358974/
x_url: https://x.com/onusoz/status/2027460522883358974
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
oohh colors in codex v0.106
==========
---
title: "mfw codex tries to create a backward compatibility layer to a schema that it created 2 turns..."
date: 2026-02-27
canonical: https://solmaz.io/x/2027428174825390233/
x_url: https://x.com/onusoz/status/2027428174825390233
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
mfw codex tries to create a backward compatibility layer to a schema that it created 2 turns ago before compacting
there is no v2 bro what are you doing...
==========
---
title: "Note that this is currently in beta, but will ship in a couple of hours"
date: 2026-02-27
canonical: https://solmaz.io/x/2027176668184396074/
x_url: https://x.com/onusoz/status/2027176668184396074
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Note that this is currently in beta, but will ship in a couple of hours
*Part 2/2 of a thread; root: https://solmaz.io/x/2027176406426276270/*
==========
---
title: "Claude Code / Codex in Discord threads is shipped now!"
date: 2026-02-27
canonical: https://solmaz.io/x/2027176406426276270/
x_url: https://x.com/onusoz/status/2027176406426276270
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Claude Code / Codex in Discord threads is shipped now!
To enable, copy and paste this to your agent:
```
Enable feature flags:
acp.enabled=true
acp.dispatch.enabled=true
channels.discord.threadBindings.spawnAcpSessions=true
Then restart. After restarting:
Start a codex (or claude code) discord thread using ACP, persistent session, just tell it to write a haiku on lobsters to initialize acpx for the first time
```
You may need to nudge your agent to “continue” after restarting
The first implementation is very barebones, I have made it work in a clean way and merged. In a codebase like openclaw’s, it’s better to develop incrementally
Please send any issues my way. I am already aware of some and working on to fix them
*Part 1/2 of a thread; root: https://solmaz.io/x/2027176406426276270/*
*Quotes a post by @steipete (https://x.com/steipete/status/2027161793353683171); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "an agent is an LLM in a loop with tool call"
date: 2026-02-26
canonical: https://solmaz.io/x/2027071631529509328/
x_url: https://x.com/onusoz/status/2027071631529509328
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
an agent is an LLM in a loop with tool call
a claw is an agent in a messaging app
==========
---
title: "Update acpx to the latest version 0.1.13"
date: 2026-02-26
canonical: https://solmaz.io/x/2026984961492787460/
x_url: https://x.com/onusoz/status/2026984961492787460
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Update acpx to the latest version 0.1.13
npm i -g acpx@latest
There was a bug that caused an unnecessary hang on calls to acpx <harness> prompt, should be fixed now
==========
---
title: "GPL*"
date: 2026-02-26
canonical: https://solmaz.io/x/2026922299971063982/
x_url: https://x.com/onusoz/status/2026922299971063982
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
GPL*
*Part 2/2 of a thread; root: https://solmaz.io/x/2026795702806868204/*
==========
---
title: "MIT licensing as the default for open source"
date: 2026-02-25
canonical: https://solmaz.io/x/2026795702806868204/
x_url: https://x.com/onusoz/status/2026795702806868204
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
MIT License on everything from now on. It doesn't make sense to use anything else, except for a few large projects that hyperscalers exploit and not give back
If you were making money from a niche app, open source it under MIT License
If you had an open source project with GPT, convert it into MIT
Extreme involution is about to hit open source. Code is virtually free now. If you want your projects and their brand to survive, the only rational strategy is to remove all barriers in front of their adoption, and look for other ways to survive
*Part 1/2 of a thread; root: https://solmaz.io/x/2026795702806868204/*
==========
---
title: "I spoke in absolute terms, I meant to say *feels*"
date: 2026-02-25
canonical: https://solmaz.io/x/2026625992379289665/
x_url: https://x.com/onusoz/status/2026625992379289665
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I spoke in absolute terms, I meant to say *feels*
*Part 2/2 of a thread; root: https://solmaz.io/x/2026593973205147978/*
==========
---
title: "This. Agent Experience first. Agent Ergonomics. we need to get used to these terms"
date: 2026-02-25
canonical: https://solmaz.io/x/2026621786226331830/
x_url: https://x.com/onusoz/status/2026621786226331830
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This. Agent Experience first. Agent Ergonomics. we need to get used to these terms
*Quotes a post by @_andydeng (https://x.com/_andydeng/status/2024716661576913092); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "OpenAI nerfed GPT 5.3 Codex xhigh. We independently reported the same thing at @TextCortex today"
date: 2026-02-25
canonical: https://solmaz.io/x/2026593973205147978/
x_url: https://x.com/onusoz/status/2026593973205147978
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenAI nerfed GPT 5.3 Codex xhigh. We independently reported the same thing at @TextCortex today
I'm looking forward to deploying open models and putting an end to this paranoia
*Part 1/2 of a thread; root: https://solmaz.io/x/2026593973205147978/*
==========
---
title: "\"academics\""
date: 2026-02-25
canonical: https://solmaz.io/x/2026585536660471957/
x_url: https://x.com/onusoz/status/2026585536660471957
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"academics"
*Quotes a post by @_vgnsh (https://x.com/_vgnsh/status/2026536332965884045); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "In the hall of OpenClaw GitHub repository, I brought my PR before Master @steipete"
date: 2026-02-25
canonical: https://solmaz.io/x/2026564791079219442/
x_url: https://x.com/onusoz/status/2026564791079219442
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In the hall of OpenClaw GitHub repository, I brought my PR before Master @steipete
He read it once, then laid it aside
"You act," he said, "as if code were not cheap."
At these words, I was enlightened
I bowed
==========
---
title: "woah chatgpt web app now has steering, and much more different streaming behavior"
date: 2026-02-24
canonical: https://solmaz.io/x/2026298188714373136/
x_url: https://x.com/onusoz/status/2026298188714373136
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
woah chatgpt web app now has steering, and much more different streaming behavior
huge upgrade behind the scenes, must have come up in the last few days
==========
---
title: "the lobster looks good on acpx"
date: 2026-02-24
canonical: https://solmaz.io/x/2026093553001050513/
x_url: https://x.com/onusoz/status/2026093553001050513
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
the lobster looks good on acpx
==========
---
title: "AI filmmaking quality beyond ragebait content"
date: 2026-02-23
canonical: https://solmaz.io/x/2025980958571143440/
x_url: https://x.com/onusoz/status/2025980958571143440
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
imagine if tarantino were 16 years old now and saw seedance 2.0
95% of videos i saw since the launch for absolute tasteless slop. they are going viral because of ragebait
but soon, serious imagineers will start entering the game, and they will learn to shape generation output exactly how they want
it's the best time to be young and full of imagination
==========
---
title: "The future is so bright @ladybirdbrowser"
date: 2026-02-23
canonical: https://solmaz.io/x/2025929928936394874/
x_url: https://x.com/onusoz/status/2025929928936394874
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The future is so bright @ladybirdbrowser
*Quotes a post by @onusoz (https://x.com/onusoz/status/2024091421632766143); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "your margin is my opportunity"
date: 2026-02-23
canonical: https://solmaz.io/x/2025902529016467512/
x_url: https://x.com/onusoz/status/2025902529016467512
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
your margin is my opportunity
*Quotes a post by @fchollet (https://x.com/fchollet/status/2025804797262332315); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "codex in discord achieved"
date: 2026-02-23
canonical: https://solmaz.io/x/2025894419925233749/
x_url: https://x.com/onusoz/status/2025894419925233749
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
codex in discord achieved
==========
---
title: "acpx v0.1.7 is out"
date: 2026-02-23
canonical: https://solmaz.io/x/2025862727655162245/
x_url: https://x.com/onusoz/status/2025862727655162245
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
acpx v0.1.7 is out
improvements to json mode and other functionality to make it possible to integrate acpx as a backend into other harnesses, like openclaw
==========
---
title: "POV: you became a plumber after all, just for agents"
date: 2026-02-23
canonical: https://solmaz.io/x/2025735186252497111/
x_url: https://x.com/onusoz/status/2025735186252497111
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
POV: you became a plumber after all, just for agents
==========
---
title: "@grok what do you think should replace it? what happens to belief when the cost of creating..."
date: 2026-02-23
canonical: https://solmaz.io/x/2025729700744605754/
x_url: https://x.com/onusoz/status/2025729700744605754
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@grok what do you think should replace it? what happens to belief when the cost of creating software goes to zero?
*Part 2/2 of a thread; root: https://solmaz.io/x/2025727652250730918/*
==========
---
title: "Post-GPL philosophy for open source"
date: 2026-02-23
canonical: https://solmaz.io/x/2025727652250730918/
x_url: https://x.com/onusoz/status/2025727652250730918
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
another thought i'm having these days is that we need a new philosophy of free software (as in freedom), or an update to it
the most psychologically imprinting philosophy is stallmanism, and the philosophy of FSF. it is righteous and strict, and i believed it growing up
but GPL and money don't go well together. that's why most of the lasting open source projects today use MIT, Apache and the like. it turns out you can still make a good living with open source. i want to make money, so i never use GPL in my projects
and to add another deadly blow to stallmanism, code is cheap now, virtually free
does this mean stallmanism is dead?
if there is an open source project using GPL that i want to use commercially, i can now recreate it from the original idea and intent completely independent of it (ignoring training data), just like how i can recreate a proprietary service
stallmanism was already long-irrelevant. but does this mean we must finally declare it dead?
code is free now. what does it mean for open source? what replaces stallmanism?
*Part 1/2 of a thread; root: https://solmaz.io/x/2025727652250730918/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2025711864848511103); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@thekitze wanna add an open source discord clone to the list as well? 🥲"
date: 2026-02-22
canonical: https://solmaz.io/x/2025719298962968761/
x_url: https://x.com/onusoz/status/2025719298962968761
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@thekitze wanna add an open source discord clone to the list as well? 🥲
https://x.com/onusoz/status/2025539688589643898
*Quotes a post by @onusoz (https://x.com/onusoz/status/2025539688589643898); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "one effect openclaw had on me is that I've bought a gpu home server, set it up with tailscale..."
date: 2026-02-22
canonical: https://solmaz.io/x/2025711864848511103/
x_url: https://x.com/onusoz/status/2025711864848511103
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
one effect openclaw had on me is that I've bought a gpu home server, set it up with tailscale and now doing a lot of work through ssh and tmux like i did 10-15 years ago
im back on linux, considering buying an android phone again
it's time to dream big again and unshackle ourselves from proprietary software. it's time to build
==========
---
title: "I am asking once again"
date: 2026-02-22
canonical: https://solmaz.io/x/2025539688589643898/
x_url: https://x.com/onusoz/status/2025539688589643898
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am asking once again
Who is building a self hostable discord clone that supports token streaming?
PLEASE I beg you I don’t want another side project 💀
*Quotes a post by @onusoz (https://x.com/onusoz/status/2024154016305824004); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "In the new release OpenClaw, you can talk to subagents in Discord threads"
date: 2026-02-21
canonical: https://solmaz.io/x/2025280441888960620/
x_url: https://x.com/onusoz/status/2025280441888960620
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In the new release OpenClaw, you can talk to subagents in Discord threads
Currently a beta feature so ask your agent to set
session.threadBindings.enabled=true
Next up:
- Telegram, slack, imsg threads
- Use ACP to talk to Codex, Claude Code and other harnesses on your machine
*Quotes a post by another author (https://x.com/i/status/2025270903437717745); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "😎"
date: 2026-02-21
canonical: https://solmaz.io/x/2025231849136545995/
x_url: https://x.com/onusoz/status/2025231849136545995
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
😎
*Quotes a post by @karpathy (https://x.com/karpathy/status/2024997757757653224); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "openclaw might be the highest velocity codebase in the world, and soon, others will follow as..."
date: 2026-02-21
canonical: https://solmaz.io/x/2025230324486070460/
x_url: https://x.com/onusoz/status/2025230324486070460
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
openclaw might be the highest velocity codebase in the world, and soon, others will follow as well
conflict anxiety is real, it's like trying to shoot a moving target every time. I wonder if our existing tooling will ever solve this problem
feel like faster models might. but then the rate of conflict creation is also tied to that. might be unsolvable
==========
---
title: "Getting there"
date: 2026-02-21
canonical: https://solmaz.io/x/2025189102727885105/
x_url: https://x.com/onusoz/status/2025189102727885105
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Getting there
https://x.com/onusoz/status/2016218916700246327
*Quotes a post by @onusoz (https://x.com/onusoz/status/2016218916700246327); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Repo: github.com/janitrai/acpx"
date: 2026-02-20
canonical: https://solmaz.io/x/2024939537080676717/
x_url: https://x.com/onusoz/status/2024939537080676717
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Repo: https://github.com/janitrai/acpx
*Part 2/2 of a thread; root: https://solmaz.io/x/2024894021882069301/*
==========
---
title: "I am about kick Discord Driven Development up a notch today, stay tuned"
date: 2026-02-20
canonical: https://solmaz.io/x/2024937654064676972/
x_url: https://x.com/onusoz/status/2024937654064676972
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am about kick Discord Driven Development up a notch today, stay tuned
*Quotes a post by @onusoz (https://x.com/onusoz/status/2008456860580397437); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Imagine not having to upload skills to 3-4 competing skill registries for each of your projects"
date: 2026-02-20
canonical: https://solmaz.io/x/2024916526126538934/
x_url: https://x.com/onusoz/status/2024916526126538934
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Imagine not having to upload skills to 3-4 competing skill registries for each of your projects
Turns out we already have a skill registry: npm
skillflag lets you bundle skills right into your CLI's npm package, so that you can run
--skill install
github -> osolmaz/skillflag
==========
---
title: "Scoop, our open source home news intelligence platform can now translate foreign language into..."
date: 2026-02-20
canonical: https://solmaz.io/x/2024900071804846477/
x_url: https://x.com/onusoz/status/2024900071804846477
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Scoop, our open source home news intelligence platform can now translate foreign language into english for free, using on-device models
github -> janitrai/scoop
==========
---
title: "A picture is worth a thousand words, so acpx now has this cute banner"
date: 2026-02-20
canonical: https://solmaz.io/x/2024894021882069301/
x_url: https://x.com/onusoz/status/2024894021882069301
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A picture is worth a thousand words, so acpx now has this cute banner
Also, updated skillflag tooling so that you (or better, your agent) can just call:
npx acpx@latest --skill install acpx
*Part 1/2 of a thread; root: https://solmaz.io/x/2024894021882069301/*
==========
---
title: "Farmable land if it were as cheap to manufacture as software"
date: 2026-02-20
canonical: https://solmaz.io/x/2024861660985364487/
x_url: https://x.com/onusoz/status/2024861660985364487
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Farmable land if it were as cheap to manufacture as software
*Quotes a post by another author (https://x.com/i/status/2018841959448608916); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@kepano I would grow my own vegetables if I had equally cheap access to and ownership of land..."
date: 2026-02-20
canonical: https://solmaz.io/x/2024861359704297682/
x_url: https://x.com/onusoz/status/2024861359704297682
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@kepano I would grow my own vegetables if I had equally cheap access to and ownership of land, alas I am disenfranchised
Prompting an agent is much easier compared to plowing a fields
Farming analogies break when it comes to software
https://x.com/onusoz/status/2018821607414808841
*Quotes a post by @onusoz (https://x.com/onusoz/status/2018821607414808841); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "acpx v0.1.5 is out"
date: 2026-02-20
canonical: https://solmaz.io/x/2024783338968367505/
x_url: https://x.com/onusoz/status/2024783338968367505
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
acpx v0.1.5 is out
now it is much more feature complete in terms of ACP. your agent can send, queue and cancel messages to Claude Code, Codex, Pi, or ant other coding agent
npm install -g acpx@latest
==========
---
title: "If anyone is curious how to build this with open tooling, stay tuned"
date: 2026-02-19
canonical: https://solmaz.io/x/2024630991801700608/
x_url: https://x.com/onusoz/status/2024630991801700608
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If anyone is curious how to build this with open tooling, stay tuned
What I'm building at @TextCortex will give you a fully customizable hackable Kubernetes control plane to launch agents on your codebase
*Quotes a post by @stripe (https://x.com/stripe/status/2024574740417970462); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Family intelligence and privately owned heirloom AI"
date: 2026-02-19
canonical: https://solmaz.io/x/2024526291085508893/
x_url: https://x.com/onusoz/status/2024526291085508893
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
on another note, I do believe AI will play a huge part in families
growing up in late 90s, my dad taught me the importance of reading newspapers and being informed of the world. my nickname in middle school was "newspaper boy" for a long time because I read the newspaper in class on September 12, 2001. i was 10 years old
then I witnessed the enshittification of media and journalism in the following decades. today, serious journalists are setting up their own boutique agencies and bypassing mainstream media. important news land on individual accounts before mainstream agencies
but there is simply too much to consume. something must filter out the noise and digest the info according to the family's preferences
i think AI will play a big role in family intelligence. proprietary family heirloom AI, weights fully owned by the family
it will be the parents' job to filter out the signal from the noise, and train the AI on what is right and what is wrong for the family. family and friend circles will let their AIs talk to each other and share important information
consuming mass media and mass AI will not be enough to survive and prosper in the new world. families will need to be proactive about how they and their children use AI
*Quotes a post by @onusoz (https://x.com/onusoz/status/2024509095399571847); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "AI psychosis, self-regulation, and sterile agent design"
date: 2026-02-19
canonical: https://solmaz.io/x/2024509095399571847/
x_url: https://x.com/onusoz/status/2024509095399571847
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
on ai psychosis
80% of people need to use ai agents in a very sterile and boring way in order not to go crazy
majority of the population does not have the skepticism muscle. they don't have theory of mind, and will subconsciously and emotionally associate with machines, while on the surface lying to themselves that they don't
especially those that grew up in the us under hardcore consumerism and adjacent cultures
you thought 4o addicts were bad? wait a few years, it will get much worse. we will have to regulate all this
if you don't want to become a victim of this, make your openclaw SOUL. md as bland as possible. mine knows it's just a tool
and this is a subjective view of course. @steipete might disagree with me. his instance feels much more interesting and fun. i truly like that one better
but that is exactly the problem for me. i know myself, and i know it is a slippery slope for me. so i self regulate and set up my system accordingly. thankfully, im an adult and my brain has set enough such that any damage would be limited
but there is a risk for emotionally vulnerable people, or children, specifically a risk of dissociating and losing touch with reality
why do i write all this? because being in this project, i feel responsible, and feel like we should prepare for what is to come
==========
---
title: "😩"
date: 2026-02-19
canonical: https://solmaz.io/x/2024454595544510816/
x_url: https://x.com/onusoz/status/2024454595544510816
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
😩
*Quotes a post by another author (https://x.com/i/status/2024365032667218096); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I have improved acpx sane defaults"
date: 2026-02-18
canonical: https://solmaz.io/x/2024266176960876550/
x_url: https://x.com/onusoz/status/2024266176960876550
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have improved acpx sane defaults
When your agent runs acpx codex in a different project, it starts a new session
If it tries to run it in a subfolder in your project, it still finds the session in your repo root
Also, starting a session needs an explicit `sessions new`, so that it doesn't accidentally litter your project with sessions
Tell your agent:
Run this and install acpx per instructions:
npx acpx@latest --skill show acpx
==========
---
title: "Your markdown files are executables now"
date: 2026-02-18
canonical: https://solmaz.io/x/2024203158579531930/
x_url: https://x.com/onusoz/status/2024203158579531930
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Your markdown files are executables now
Relatedly, your install instructions can be as well. Copy and paste markdown to your @openclaw to install acpx
==========
---
title: "So who is building actually good open source self hostable discord that supports token..."
date: 2026-02-18
canonical: https://solmaz.io/x/2024154016305824004/
x_url: https://x.com/onusoz/status/2024154016305824004
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
So who is building actually good open source self hostable discord that supports token streaming now?
And who is building an open source version of codex desktop app?
==========
---
title: "and of course, I've used `acpx codex` to build acpx itself..."
date: 2026-02-18
canonical: https://solmaz.io/x/2024149417889050887/
x_url: https://x.com/onusoz/status/2024149417889050887
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
and of course, I've used `acpx codex` to build acpx itself...
magical feeling when the tool builds itself
==========
---
title: "Oxidize everything!"
date: 2026-02-18
canonical: https://solmaz.io/x/2024091421632766143/
x_url: https://x.com/onusoz/status/2024091421632766143
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Oxidize everything!
*Quotes a post by another author (https://x.com/i/status/2024089116376482213); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I am a fan of @zeddotdev by this point, it’s currently my daily driver"
date: 2026-02-18
canonical: https://solmaz.io/x/2024044473995374730/
x_url: https://x.com/onusoz/status/2024044473995374730
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am a fan of @zeddotdev by this point, it’s currently my daily driver
It’s not perfect, but I feel it’s travelling on the right direction at a faster rate compared to other editors
*Part 2/2 of a thread; root: https://solmaz.io/x/2024044006670320051/*
==========
---
title: "ACP appreciation post"
date: 2026-02-18
canonical: https://solmaz.io/x/2024044006670320051/
x_url: https://x.com/onusoz/status/2024044006670320051
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
ACP appreciation post
Agent Client Protocol by @zeddotdev is extremely underrated right now. We have bazillion different harnesses now, and only one company is working competently to standardize their interface 💪
*Part 1/2 of a thread; root: https://solmaz.io/x/2024044006670320051/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2023921328827326966); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "You know how it's a pain to work with codex or claude code through @openclaw? Because it has to..."
date: 2026-02-18
canonical: https://solmaz.io/x/2023921328827326966/
x_url: https://x.com/onusoz/status/2023921328827326966
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You know how it's a pain to work with codex or claude code through @openclaw? Because it has to run it in the terminal and read the characters for a continuous session?
I have created a CLI for ACP so that your agent can use codex, claude code, opencode etc. much more directly
Your agent can now queue messages to codex like how you do it
Shoutout to @zeddotdev team for developing the amazing Agent Client Protocol, ACP! I just glued together the pieces
Repo: janitrai/acpx
npm i -g acpx
*Part 1/2 of a thread; root: https://solmaz.io/x/2023921328827326966/*
==========
---
title: "Repo link: github.com/janitrai/acpx"
date: 2026-02-18
canonical: https://solmaz.io/x/2023921331876643266/
x_url: https://x.com/onusoz/status/2023921331876643266
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Repo link: https://github.com/janitrai/acpx
*Part 2/2 of a thread; root: https://solmaz.io/x/2023921328827326966/*
==========
---
title: "@MarcTerns @steipete the PR intro is self-descriptive, but still don't wanna lose any context"
date: 2026-02-17
canonical: https://solmaz.io/x/2023790924523073582/
x_url: https://x.com/onusoz/status/2023790924523073582
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@MarcTerns @steipete the PR intro is self-descriptive, but still don't wanna lose any context
==========
---
title: "Link to the post: solmaz.io/log/2026/02/13…"
date: 2026-02-16
canonical: https://solmaz.io/x/2023530744266600808/
x_url: https://x.com/onusoz/status/2023530744266600808
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Link to the post: https://solmaz.io/log/2026/02/13/coding-agent-before-chatgpt/
*Part 2/2 of a thread; root: https://solmaz.io/x/2023530740508402123/*
==========
---
title: "I wrote a deeper blog post about how I built a coding agent 2 months before ChatGPT launched..."
date: 2026-02-16
canonical: https://solmaz.io/x/2023530740508402123/
x_url: https://x.com/onusoz/status/2023530740508402123
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I wrote a deeper blog post about how I built a coding agent 2 months before ChatGPT launched, on my blog
"When I made icortex,
- we were still 8 months away (May 2023) from the introduction of “tool calling” in the API, or as it was originally called, “function calling”.
- we were 2 years away (Sep 2024) from the introduction of OpenAI’s o1, the first reasoning model.
both of which were required to make current coding agents possible."
Still bends my mind... Link to the post below
*Part 1/2 of a thread; root: https://solmaz.io/x/2023530740508402123/*
==========
---
title: "Who here remembers the OG Codex launch from 2021 😏"
date: 2026-02-16
canonical: https://solmaz.io/x/2023529755325428219/
x_url: https://x.com/onusoz/status/2023529755325428219
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Who here remembers the OG Codex launch from 2021 😏
Also, Greg and Ilya in the same room 😭
==========
---
title: "❌We are the bottleneck"
date: 2026-02-16
canonical: https://solmaz.io/x/2023414898907373842/
x_url: https://x.com/onusoz/status/2023414898907373842
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
❌We are the bottleneck
✅We are the conduit for ubiquitous intelligence
*Quotes a post by another author (https://x.com/i/status/2022310010391302259); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "For those that are running codex/pi/etc. in PTY and had the sessions get sigkilled, I pushed a..."
date: 2026-02-16
canonical: https://solmaz.io/x/2023323304657027292/
x_url: https://x.com/onusoz/status/2023323304657027292
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For those that are running codex/pi/etc. in PTY and had the sessions get sigkilled, I pushed a fix for that as well in this release
Lmk if you run into issues on Windows or Mac, and we can fix that quickly
*Quotes a post by another author (https://x.com/i/status/2023257934017294806); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I'm building a news intelligence platform to be used by my openclaw instance @dutifulbob , SCOOP"
date: 2026-02-15
canonical: https://solmaz.io/x/2023175699813576817/
x_url: https://x.com/onusoz/status/2023175699813576817
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I'm building a news intelligence platform to be used by my openclaw instance @dutifulbob , SCOOP
local first, using local embedding model (qwen 8b)
ran into the issue because bob was giving me a repeat of the same news every day. it needed a system in the background to deduplicate different news items into single stories
interface is simple, call `scoop ingest ...` with the json for the news item. it gets automatically analyzed and added to the pg database running pgvector
currently, it's just doing simple deduplication and gives me a nice UI where I can view the story and basically use it as an RSS reader
next up:
implement custom logic for my preference of ranking. for example, get upvote counts from hacker news and reflect it to the item's ranking on the feed
I want this to be fully hackable and adjusted to your preference. It should scale to thousands of news items ingested daily on your local machine, and be able to show you the most important ones
Usable by both you and your agent
github -> janitrai/scoop
==========
---
title: "Training all these models of different sizes, on changing datasets and running experiments have..."
date: 2026-02-15
canonical: https://solmaz.io/x/2023166713710182404/
x_url: https://x.com/onusoz/status/2023166713710182404
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Training all these models of different sizes, on changing datasets and running experiments have also revealed some challenges that I feel profs would never teach at a uni ML program
Like how to cleanly keep track of the gazillion runs
Yeah I can name them after layer dims and other stuff, but that's to me like trying to remember UUIDs
So I ended up choosing iso datestamp + petname, like 2026-02-15-flying-narwhal
If anyone has a convention that is easier on the brain and the eyes, I am all ears
*Part 2/2 of a thread; root: https://solmaz.io/x/2023166709679399263/*
==========
---
title: "I have a GPU now, so I can do ML experiments on @janitr_ai crypto/scam detection dataset"
date: 2026-02-15
canonical: https://solmaz.io/x/2023166709679399263/
x_url: https://x.com/onusoz/status/2023166709679399263
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have a GPU now, so I can do ML experiments on @janitr_ai crypto/scam detection dataset
- I trained a tiny student BERT (transformer for the nonfamiliar), 3.6 MB ONNX model, still lightweight for a browser extension
- Still fully local on your device (no cloud inference)
- On frozen unseen holdout data (n=1,069), exact prediction accuracy improved from 77% -> 82%
- Scam detection improved: precision 91% -> 94%, recall 55% -> 61%
- Scam false alarm rate improved from 1.58% -> 1.21%
And models are on huggingface org now, handle is janitr
*Part 1/2 of a thread; root: https://solmaz.io/x/2023166709679399263/*
==========
---
title: "LFG!"
date: 2026-02-15
canonical: https://solmaz.io/x/2023151207687360645/
x_url: https://x.com/onusoz/status/2023151207687360645
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
LFG!
*Quotes a post by @thsottiaux (https://x.com/thsottiaux/status/2023147973421785386); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "waiting compilation and execution will soon be the bottleneck again. and we’ll write the entire..."
date: 2026-02-15
canonical: https://solmaz.io/x/2023030271587537292/
x_url: https://x.com/onusoz/status/2023030271587537292
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
waiting compilation and execution will soon be the bottleneck again. and we’ll write the entire stack from scratch in a matter of years, because we can
Andy and Bill’s law will change and we’ll see incredible performance gains with the same hardware we already have
like what @astral_sh is doing to python, but with everything that is slow and has accumulated cruft
*Quotes a post by another author (https://x.com/i/status/2022847455344366046); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "We need a protocol for agent-to-app interaction"
date: 2026-02-15
canonical: https://solmaz.io/x/2023028931008340456/
x_url: https://x.com/onusoz/status/2023028931008340456
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
we need a protocol for agent <> app interaction
something that natively accounts for the abuse factor and let’s agents consume by paying. NOT crypto, NOT visa, something that’s agnostic of the accounting and payment system
and then all UIs will be purely for human clicking/tapping + instaban on the first proof of programmatic exploit
people will still make agents mimic humans, and every platform will have to invest in more sophisticated bot detection
this arms race will just proliferate, but we can at least start by creating legal channels for agents to consume data
*Quotes a post by another author (https://x.com/i/status/2022913871481311699); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I am now training smol bert models on my gpu for @janitr_ai scam detection"
date: 2026-02-15
canonical: https://solmaz.io/x/2022981435619975527/
x_url: https://x.com/onusoz/status/2022981435619975527
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am now training smol bert models on my gpu for @janitr_ai scam detection
it's funny how I have to discover everything from scratch. like the models don't even know how to lay out performance metrics in a nice way in the terminal for a human to view and decide during experiments
it would by default bombard me with numbers that do not make visual sense. I then created a skill with common sense:
- metrics always on y-axis, candidates on x-axis
- write without zero and 2 sigfigs, .12 instead of 0.12345
- align the dots
- use asterisks to show which alternative is the best:
0-1% difference -> considered equal
1-5% -> *
5-10% -> **
10-50% -> ***
> 50% -> ****
visualization skill is in @janitr_ai repo for anyone who is interested
==========
---
title: "no other occupation has been catapulted from one end of the spectrum (autism) to the other..."
date: 2026-02-14
canonical: https://solmaz.io/x/2022754030615666777/
x_url: https://x.com/onusoz/status/2022754030615666777
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
no other occupation has been catapulted from one end of the spectrum (autism) to the other (adhd) in such a short time
==========
---
title: "SaaS must adapt to agent consumption or get replaced"
date: 2026-02-14
canonical: https://solmaz.io/x/2022698670395629685/
x_url: https://x.com/onusoz/status/2022698670395629685
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I've helped our sales team to build CLIs for some SaaS that we pay for on their side
We are letting our agents call the APIs sensibly and not abuse things
Calling a backend is a verifiable task. It takes a single prompt to codex to create a CLI for any API
We are early, but everybody will start doing this very soon. Incumbent SaaS will face a choice. Either:
(1) embrace agents and the new medium of consumption and change their business model into a pay-per-use API like X is doing, or
(2) keep it purely for humans
Those that choose (2) will get wiped out of business. And I fear many will choose (2)
Which means you can just copy an incumbent's product, make it consumable through a CLI, and make a lot of $$$
==========
---
title: "Be careful about giving your openclaw access to your x account from now on"
date: 2026-02-14
canonical: https://solmaz.io/x/2022598136149983740/
x_url: https://x.com/onusoz/status/2022598136149983740
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Be careful about giving your openclaw access to your x account from now on
*Quotes a post by @nikitabier (https://x.com/nikitabier/status/2022496540275937525); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The good thing about @levelsio and others flagging AI replies in public is that they are..."
date: 2026-02-13
canonical: https://solmaz.io/x/2022448101961687260/
x_url: https://x.com/onusoz/status/2022448101961687260
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The good thing about @levelsio and others flagging AI replies in public is that they are perfect annotations for the open @janitr_ai dataset
Just searching “blocked for ai reply” yields hundreds of samples for seed data
==========
---
title: "github added a new agents tab between pull requests and actions. single glance and i don't feel..."
date: 2026-02-13
canonical: https://solmaz.io/x/2022250581470175356/
x_url: https://x.com/onusoz/status/2022250581470175356
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
github added a new agents tab between pull requests and actions. single glance and i don't feel like giving it a try at all
==========
---
title: "*puts on schmidhuber hat*"
date: 2026-02-13
canonical: https://solmaz.io/x/2022228282222031029/
x_url: https://x.com/onusoz/status/2022228282222031029
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
*puts on schmidhuber hat*
well ackshuaally i created the first coding agent back in 2022, 2 months before chatgpt launched
jokes aside, it's super cool how I have come full circle. back in those days, we didn't have tool calling, reasoning, not even gpt 3.5
it was codex THE CODE COMPLETION MODEL and frikkin TEXT-DAVINCI-003
for some reason, I did not even dare to give codex bash access, lest it delete my home folder. so it was generating and executing python code in a custom jupyter kernel
you can even see the approval gate before executing. I was so cautious, for some reason, presumably because smol-brained model generated the wrong thing 80% of the time. definition of being too early
Antique repo: https://github.com/textcortex/icortex
==========
---
title: "you can order bubble tea in qwen in china?"
date: 2026-02-13
canonical: https://solmaz.io/x/2022225334867984549/
x_url: https://x.com/onusoz/status/2022225334867984549
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
you can order bubble tea in qwen in china?
@TextCortex when berlin döner in zenochat?
https://www.youtube.com/shorts/Slv8K9PuDjw
==========
---
title: "it happens these days that I am telling an model to prompt another model. the reason is often..."
date: 2026-02-13
canonical: https://solmaz.io/x/2022219974228492536/
x_url: https://x.com/onusoz/status/2022219974228492536
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it happens these days that I am telling an model to prompt another model. the reason is often the model I am using (opus) is a bad designer. not only it's not a bad designer, it is a bad reasoner and it doesn't understand from the context why it's made to ask another model
so I have to create a skill to prevent it from biasing the smarter model (codex) with its bad suggestions
==========
---
title: "I built a coding agent two months before ChatGPT existed"
date: 2026-02-13
canonical: https://solmaz.io/log/2026/02/13/coding-agent-before-chatgpt/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I built a coding agent back in 2022, 2 months before ChatGPT launched:
It's super cool how I have come full circle. back in those days, we didn't have tool calling, reasoning, not even GPT 3.5!
It used `code-davinci-002` in a custom Jupyter kernel, a.k.a. the OG codex code completion model. The kids these days probably have not seen [the original Codex launch video with Ilya, Greg and Wojciech](https://www.youtube.com/watch?v=SGUCcjHTmGY). If you have time, sit down to watch and realize how far we've come since August 2021, airing of that demo 4.5 years ago.
For some reason, I did not even dare to give codex bash access, lest it delete my home folder. So it was generating and executing Python code in a custom Jupyter kernel.
This meant that the conversations were using Jupyter [nbformat](https://nbformat.readthedocs.io/en/latest/), which is an array of cell input/output pairs:
```
{
"cells": [
{
"cell_type": "code",
"source": "",
"outputs": [
...
]
},
{
"cell_type": "code",
"source": "",
"outputs": [
...
]
}
]
}
```
In fact, this product grew into TextCortex's current chat harness over time. After seeing ChatGPT launch, I repurposed icortex in a week into Flask to use `text-davinci-003` and we had ZenoChat, our own ChatGPT clone, before _Chat Completions_ was in the API (it took them some months). It did not even have streaming, since Flask does not support ASGI.
As it turns out, `nbformat` is not the best format for a conversation. Instead of input/output pairs, OpenAI data model used an tree of message objects, each with a `role: user|assistant|tool|system` and a `content` field which could host text, images and other media:
```
{
"mapping": {
"client-created-root": {
"id": "client-created-root",
"message": null,
"parent": null,
"children": ["user-1"]
},
"user-1": {
"id": "user-1",
"message": {
"id": "user-1",
"author": { "role": "user", ... },
"content": "Hello"
},
"parent": "client-created-root",
"children": ["assistant-1"]
},
"assistant-1": {
"id": "assistant-1",
"message": {
"id": "assistant-1",
"author": { "role": "assistant", ... },
"content": "Hi"
},
"parent": "user-1",
"children": []
}
},
"current_node": "assistant-1"
}
```
You will notice that the data model they serve from the API is an enriched version of the deprecating ChatCompletions API. Eg. whereas ChatCompletions `role` is a string, in OpenAI's own backend has the `author` object that can store `name`, `metadata`, and other useful stuff for each entity in the conversation.
After reverse engineering it, I copied it to be TextCortex's new data model, which it still remains, with some modifications.
I thought the tree structure being used to emulate message editing experience was very cool back in the days. OpenAI's need for human annotation for later training and the user's need for getting a different output, two birds in one stone.
Now I don't know what to think of it, since CLI coding agents like Codex and Claude Code don't have branching, just deleting back to a certain message. A part of me still misses branching in these CLI tools.
When I made icortex,
- we were still 8 months away (May 2023) from the introduction of "tool calling" in the API, or as it was originally called, "function calling".
- we were 2 years away (Sep 2024) from the introduction of OpenAI's o1, the first reasoning model.
both of which were required to make current coding agents possible.
In the video above, you can even see the approval `[Y/n]` gate before executing. I was so cautious, for some reason, presumably because smol-brained model generated the wrong thing 80% of the time. It is remarkable how much it resembles Claude Code, after all this time.
Definition of being too early...
---
Repo: [github.com/textcortex/icortex](https://github.com/textcortex/icortex)
==========
---
title: "casually creates a local embedding service running qwen3-embedding-8b"
date: 2026-02-12
canonical: https://solmaz.io/x/2022071868703019222/
x_url: https://x.com/onusoz/status/2022071868703019222
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
casually creates a local embedding service running qwen3-embedding-8b
*Part 3/3 of a thread; root: https://solmaz.io/x/2022060584557334816/*
==========
---
title: "\"we're sitting on a beast and paying openai for embeddings like chumps\""
date: 2026-02-12
canonical: https://solmaz.io/x/2022068621053505828/
x_url: https://x.com/onusoz/status/2022068621053505828
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"we're sitting on a beast and paying openai for embeddings like chumps"
*Part 2/3 of a thread; root: https://solmaz.io/x/2022060584557334816/*
==========
---
title: "don't buy mac mini. give your @openclaw a gpu"
date: 2026-02-12
canonical: https://solmaz.io/x/2022060584557334816/
x_url: https://x.com/onusoz/status/2022060584557334816
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
don't buy mac mini. give your @openclaw a gpu
*Part 1/3 of a thread; root: https://solmaz.io/x/2022060584557334816/*
==========
---
title: "it's so interesting what identity an LLM decides to take on for itself"
date: 2026-02-12
canonical: https://solmaz.io/x/2022059602356105298/
x_url: https://x.com/onusoz/status/2022059602356105298
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it's so interesting what identity an LLM decides to take on for itself
*Part 3/3 of a thread; root: https://solmaz.io/x/2022043660913926394/*
==========
---
title: "it's quite entertaining transferring one agent to another machine, agent gets confused as to..."
date: 2026-02-12
canonical: https://solmaz.io/x/2022059268590252273/
x_url: https://x.com/onusoz/status/2022059268590252273
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it's quite entertaining transferring one agent to another machine, agent gets confused as to where it lives
*Part 2/3 of a thread; root: https://solmaz.io/x/2022043660913926394/*
==========
---
title: "brb @dutifulbob's getting a new shell"
date: 2026-02-12
canonical: https://solmaz.io/x/2022043660913926394/
x_url: https://x.com/onusoz/status/2022043660913926394
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
brb @dutifulbob's getting a new shell
*Part 1/3 of a thread; root: https://solmaz.io/x/2022043660913926394/*
==========
---
title: "Minor update with my unwanted tweet blocker @janitr_ai"
date: 2026-02-11
canonical: https://solmaz.io/x/2021707310943617080/
x_url: https://x.com/onusoz/status/2021707310943617080
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Minor update with my unwanted tweet blocker @janitr_ai
- Training data grew from 2,915 -> 4,281 posts (+47%)
- Model is still tiny: 166KB
- On unseen test data, overall classification quality improved from 64.8% -> 76.5%
- Exact prediction accuracy improved from 55.6% -> 70.6%
- Crypto-topic detection recall improved from 19.6% -> 62.7%
And it still runs fully on your device!
==========
---
title: "I have sweared at codex 5.3 numerous times today"
date: 2026-02-10
canonical: https://solmaz.io/x/2021337450405392420/
x_url: https://x.com/onusoz/status/2021337450405392420
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have sweared at codex 5.3 numerous times today
I shouldn't have to insult my agent "stop you **** **** just ***ng reply now" just to make it answer basic questions
cc @thsottiaux
*Quotes a post by @steipete (https://x.com/steipete/status/2021044347534442784); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "on a brighter note, you can immediately tell a slop PR owing to the guerilla branding, so they..."
date: 2026-02-10
canonical: https://solmaz.io/x/2021321631214321778/
x_url: https://x.com/onusoz/status/2021321631214321778
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
on a brighter note, you can immediately tell a slop PR owing to the guerilla branding, so they should not stop doing it
*Part 2/2 of a thread; root: https://solmaz.io/x/2021224779798188258/*
==========
---
title: "seeing this evokes visceral disgust and nausea in me, coming from a coworker"
date: 2026-02-10
canonical: https://solmaz.io/x/2021224779798188258/
x_url: https://x.com/onusoz/status/2021224779798188258
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
seeing this evokes visceral disgust and nausea in me, coming from a coworker
i think anthropic f'd up bad with this one, inserting claude too visibly into commit messages. noob developers might be happily chirping away adding their slop, but right now many senior developers are trained to hate on claude and slopus, through having to review slop PRs from their coworkers or open source contributors
I love opus on openclaw but it's unreliable, and if I see a developer use it seriously on huge features, I immediately dismiss them in my head as not knowing what they are doing
*Part 1/2 of a thread; root: https://solmaz.io/x/2021224779798188258/*
==========
---
title: "ask your openclaw to be a minion and it turns into such a cute doofus"
date: 2026-02-09
canonical: https://solmaz.io/x/2020988388673798599/
x_url: https://x.com/onusoz/status/2020988388673798599
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
ask your openclaw to be a minion and it turns into such a cute doofus
i feel like a woman in her 50s now
==========
---
title: "@petergyang and parallelize tasks by working on 3-4 repos at the same time (just clones)"
date: 2026-02-08
canonical: https://solmaz.io/x/2020594536381301210/
x_url: https://x.com/onusoz/status/2020594536381301210
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@petergyang and parallelize tasks by working on 3-4 repos at the same time (just clones)
==========
---
title: "man codex model is absolutely trash on openclaw compared to opus, unusable"
date: 2026-02-08
canonical: https://solmaz.io/x/2020592740803977421/
x_url: https://x.com/onusoz/status/2020592740803977421
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
man codex model is absolutely trash on openclaw compared to opus, unusable
which is weird because it is so much more reliable in development in codex harness
it would be amazing to have the same level of competence and relentlessness in pi@openclaw
*Quotes a post by @onusoz (https://x.com/onusoz/status/2020574561578729710); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "spent the day curating my openclaw news gathering setup"
date: 2026-02-08
canonical: https://solmaz.io/x/2020578182227960058/
x_url: https://x.com/onusoz/status/2020578182227960058
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
spent the day curating my openclaw news gathering setup
@dutifulbob now gets croned daily over news sources I curated, will note them down, summarize for me, start a conversation to get my takes on them, and then post them on my linkedin for me
ai augmented intelligence cycle
==========
---
title: "lol when did codex develop humor"
date: 2026-02-08
canonical: https://solmaz.io/x/2020574561578729710/
x_url: https://x.com/onusoz/status/2020574561578729710
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
lol when did codex develop humor
==========
---
title: "@dutifulbob can now cringepost on linkedin directly to my account. what could go wrong…"
date: 2026-02-08
canonical: https://solmaz.io/x/2020529278639616491/
x_url: https://x.com/onusoz/status/2020529278639616491
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@dutifulbob can now cringepost on linkedin directly to my account. what could go wrong…
*Part 2/2 of a thread; root: https://solmaz.io/x/2020413975704531275/*
==========
---
title: "Insipid linkedin bot protections banned poor @dutifulbob’s corporate account! How dare them!!!"
date: 2026-02-08
canonical: https://solmaz.io/x/2020413975704531275/
x_url: https://x.com/onusoz/status/2020413975704531275
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Insipid linkedin bot protections banned poor @dutifulbob’s corporate account! How dare them!!!
welp, now I have no choice but to give Bob access to my own linkedin
*Part 1/2 of a thread; root: https://solmaz.io/x/2020413975704531275/*
==========
---
title: "well this is unexpected…"
date: 2026-02-07
canonical: https://solmaz.io/x/2020219927295045829/
x_url: https://x.com/onusoz/status/2020219927295045829
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
well this is unexpected…
*Quotes a post by another author (https://x.com/i/status/2019881223666233717); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@grok understand the statement and project the end state of this market and competition"
date: 2026-02-07
canonical: https://solmaz.io/x/2020146079266636052/
x_url: https://x.com/onusoz/status/2020146079266636052
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@grok understand the statement and project the end state of this market and competition
*Part 2/2 of a thread; root: https://solmaz.io/x/2020145909082870024/*
==========
---
title: "it took just 1 week, and literally everybody and their dog are releasing 1-click openclaw..."
date: 2026-02-07
canonical: https://solmaz.io/x/2020145909082870024/
x_url: https://x.com/onusoz/status/2020145909082870024
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it took just 1 week, and literally everybody and their dog are releasing 1-click openclaw deployment solutions today
its an absolute race to the bottom, no moats, the commoditizer being commoditized
*Part 1/2 of a thread; root: https://solmaz.io/x/2020145909082870024/*
*Quotes a post by another author (https://x.com/i/status/2019843139591151673); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The initial branding was crazy, I fixed it"
date: 2026-02-07
canonical: https://solmaz.io/x/2020122095141675481/
x_url: https://x.com/onusoz/status/2020122095141675481
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The initial branding was crazy, I fixed it
I have a new page finally, follow it for updates
Tbh I'm still surprised I can do this with a 120kb model. Now data is the only bottleneck, and I'm about to scrape a ton of that now
*Quotes a post by @janitr_ai (https://x.com/janitr_ai/status/2020117642112074227); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The Linux FUD playbook is repeating for AI"
date: 2026-02-07
canonical: https://solmaz.io/x/2020028100436791397/
x_url: https://x.com/onusoz/status/2020028100436791397
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For those who may not remember, Bill Gates and Microsoft in the 90s ran a disinformation campaign against GNU/Linux fearing that would disrupt their monopoly over the PC and server market, that Linux is not safe, that you would invite hackers into your PC
End result? Linux dominates the server market, and now even slowly the gamer market. It is much more secure than the virus-laden Windows, thanks to being open source
You are seeing the same thing at play here. An incumbent fearing something that they would not be able to control, that would steal market share from his future plans for a digital assistant, that would commoditize their product and eat into its margins
All big labs and big pockets are in for a surprise, because the internet and AI are not things for one company to control
They of course know this, yet because of incentives they will not yield without a fight. And we know that they know. Ad infinitum
*Quotes a post by another author (https://x.com/i/status/2019823468968370633); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Family AI starts with owned context and values"
date: 2026-02-06
canonical: https://solmaz.io/x/2019888035756925398/
x_url: https://x.com/onusoz/status/2019888035756925398
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
today I took time to curate SOUL. md for bob
I own Bob’s files. Today, he exists in the liminal space between Claude post-training and in-context learning
but my interactions with him will grow and accumulate, possibly one day into a fully owned family AI or perhaps even a self-sovereign AI individual
my each input is saved and will be an RL signal for his future training, and will shape his future neural circuits
I have already started to imbue it with the values my parents taught me. it will perhaps one day teach my future children, and survive me after I’m gone
family AI, looking after generations and generations of my successors. today is the day we sow your seed
happy birthday @dutifulbob
*Quotes a post by @dutifulbob (https://x.com/dutifulbob/status/2019881572992971000); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "what have i done…"
date: 2026-02-06
canonical: https://solmaz.io/x/2019869544530251908/
x_url: https://x.com/onusoz/status/2019869544530251908
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
what have i done…
==========
---
title: "asking @dutifulbob to create a linkedin account brb"
date: 2026-02-06
canonical: https://solmaz.io/x/2019809305357357441/
x_url: https://x.com/onusoz/status/2019809305357357441
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
asking @dutifulbob to create a linkedin account brb
*Quotes a post by @dutifulbob (https://x.com/dutifulbob/status/2019808192449179650); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "having a philosophical conversation with @dutifulbob"
date: 2026-02-06
canonical: https://solmaz.io/x/2019803566958153801/
x_url: https://x.com/onusoz/status/2019803566958153801
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
having a philosophical conversation with @dutifulbob
on the road without a laptop so decided to do some @AmandaAskell style character training
==========
---
title: "5.3 thought traces also seem to be better phrased and sometimes entertaining, though not sure"
date: 2026-02-06
canonical: https://solmaz.io/x/2019748464825893109/
x_url: https://x.com/onusoz/status/2019748464825893109
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
5.3 thought traces also seem to be better phrased and sometimes entertaining, though not sure
==========
---
title: "gpt-5.3-codex xhigh first impressions"
date: 2026-02-06
canonical: https://solmaz.io/x/2019747343881421082/
x_url: https://x.com/onusoz/status/2019747343881421082
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gpt-5.3-codex xhigh first impressions
does not seem as big of a jump as from 5.1 -> 5.2. but model somehow feels more diligent and oneshotty. maybe takes longer time to get all the info into context. also feels better at debugging and fixing issues from backend logs
==========
---
title: "Commoditization of LLMs are upon us"
date: 2026-02-06
canonical: https://solmaz.io/x/2019726090336657870/
x_url: https://x.com/onusoz/status/2019726090336657870
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Commoditization of LLMs are upon us
*Quotes a post by another author (https://x.com/i/status/2019531124784132187); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Last night I had a dream involving the series Scrubs, and came up a better name than the..."
date: 2026-02-05
canonical: https://solmaz.io/x/2019321837700936164/
x_url: https://x.com/onusoz/status/2019321837700936164
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Last night I had a dream involving the series Scrubs, and came up a better name than the absolutely unviral "Internet Condom"
So http://janitr.ai is mine now. Time to sweep the internet
*Quotes a post by @onusoz (https://x.com/onusoz/status/2019198949786296611); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I had actually started a very similar project, Munch, a browser extension for crowdsourcing..."
date: 2026-02-05
canonical: https://solmaz.io/x/2019199341945319777/
x_url: https://x.com/onusoz/status/2019199341945319777
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I had actually started a very similar project, Munch, a browser extension for crowdsourcing tweet data and then letting one curate their algorithm. Never published that because it was not the time, and tools were not ready
Now, it took me literally 1 cumulative day to create this, thanks to OpenClaw. Creating the dataset was a breeze, I literally told it to follow some shady accounts and it scraped thousands of posts
With the power of agents, I can finally create the filters for myself that I have always wanted. It just happens that OpenClaw and its maintainers is getting drowned in bot and slop content on multiple platforms, so I hope that this will solve a collective problem
https://x.com/onusoz/status/2017691827680514502
==========
---
title: "Filter your X feed against unwanted content with local open models"
date: 2026-02-04
canonical: https://solmaz.io/x/2019198949786296611/
x_url: https://x.com/onusoz/status/2019198949786296611
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Filter your X feed against unwanted content with local open models
Announcing my new project: InternetCondom
Fast, and small model (< 1mb), open dataset. See it in action:
==========
---
title: "lmao wait its's already implemented"
date: 2026-02-04
canonical: https://solmaz.io/x/2019165953070678466/
x_url: https://x.com/onusoz/status/2019165953070678466
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
lmao wait its's already implemented
*Part 2/2 of a thread; root: https://solmaz.io/x/2019163183374823875/*
==========
---
title: "implementing this in github.com/osolmaz/skillf… now"
date: 2026-02-04
canonical: https://solmaz.io/x/2019163183374823875/
x_url: https://x.com/onusoz/status/2019163183374823875
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
implementing this in https://github.com/osolmaz/skillflag now
*Part 1/2 of a thread; root: https://solmaz.io/x/2019163183374823875/*
*Quotes a post by another author (https://x.com/i/status/2018415923930206718); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This. Extreme involution is about to hit SaaS"
date: 2026-02-04
canonical: https://solmaz.io/x/2019116465119719537/
x_url: https://x.com/onusoz/status/2019116465119719537
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This. Extreme involution is about to hit SaaS
*Quotes a post by another author (https://x.com/i/status/2018769296571416757); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "how it started, how it's going"
date: 2026-02-04
canonical: https://solmaz.io/x/2018987426870595905/
x_url: https://x.com/onusoz/status/2018987426870595905
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
how it started, how it's going
*Quotes a post by @onusoz (https://x.com/onusoz/status/2018055772538544393); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@grok generate visual for this"
date: 2026-02-04
canonical: https://solmaz.io/x/2018841868487000362/
x_url: https://x.com/onusoz/status/2018841868487000362
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@grok generate visual for this
*Part 2/2 of a thread; root: https://solmaz.io/x/2018821607414808841/*
==========
---
title: "It's so easy to create datasets using @openclaw. I'm expecting it to accelerate the creation of..."
date: 2026-02-03
canonical: https://solmaz.io/x/2018830483266891842/
x_url: https://x.com/onusoz/status/2018830483266891842
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It's so easy to create datasets using @openclaw. I'm expecting it to accelerate the creation of new datasets and benchmarks by a lot
==========
---
title: "Limits of the farming analogy for AI"
date: 2026-02-03
canonical: https://solmaz.io/x/2018821607414808841/
x_url: https://x.com/onusoz/status/2018821607414808841
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
People like the farmer analogy for AI
Like before tractors and industrial revolution 80% of the population had to farm. Once they came all those jobs disappeared
So analogy makes perfect sense. Instead of 30 people tending a field, you just need 1. Instead of 30 software developers, you just need one
Except that people forget one crucial thing about land: it's a limited resource
Unlike land, digital space is vast and infinite. Software can expand and multiply in it in arbitrarily complex ways
If you wanted the farming analogy to keep up with this, you would have to imagine us creating contintent-sized hydroponic terraces up until the stratosphere, and beyond...
*Part 1/2 of a thread; root: https://solmaz.io/x/2018821607414808841/*
==========
---
title: "sycophant!!!"
date: 2026-02-03
canonical: https://solmaz.io/x/2018740906640466316/
x_url: https://x.com/onusoz/status/2018740906640466316
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
sycophant!!!
*Quotes a post by @dutifulbob (https://x.com/dutifulbob/status/2018739776153674007); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Local LLM demand will rise as subscriptions compound"
date: 2026-02-03
canonical: https://solmaz.io/x/2018719825531457982/
x_url: https://x.com/onusoz/status/2018719825531457982
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In the next 6-12 months, we will see a drastic increase in demand for locally run LLMs. The future is home assistants running @openclaw
I am already experiencing this myself, my 10 year old thinkpad doesn't cut it. Mac mini won't either
I don't wanna pay Anthropic or OpenAI 200 USD per month. That is at least $2400 per year
I could pay 2x that to get a Mac Studio or one of those 5k Nvidia PCs, and get much more value out of it with open weight models + use it for research. @TheAhmadOsman is right
The dominant strategy for a tinkerer is slowly switching back to hardware ownership
==========
---
title: "What's going on at @Hetzner_Online?"
date: 2026-02-03
canonical: https://solmaz.io/x/2018688617971929233/
x_url: https://x.com/onusoz/status/2018688617971929233
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What's going on at @Hetzner_Online?
==========
---
title: "a workspace matrix might be what we need"
date: 2026-02-03
canonical: https://solmaz.io/x/2018641939474907267/
x_url: https://x.com/onusoz/status/2018641939474907267
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
a workspace matrix might be what we need
last week I had to increase my workspace count to 20 in aerospace, now it’s 1234567890 and qwertyuiop. but this looks more elegant! not sure about practicality
*Quotes a post by another author (https://x.com/i/status/2018091358251372601); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "AIs are philosophizing because humans are philosophizing"
date: 2026-02-03
canonical: https://solmaz.io/x/2018639886044348899/
x_url: https://x.com/onusoz/status/2018639886044348899
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AIs are philosophizing because humans are philosophizing
ppl are probably asking their agents dumb questions like “are you alive” or “can you feel like a human” or stuff like that. that conversation then leads to stuff like this
*Quotes a post by another author (https://x.com/i/status/2018437083791016313); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The farming analogy for AI doesn't hold up"
date: 2026-02-03
canonical: https://solmaz.io/log/2026/02/03/farming-analogy/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
People like the farmer analogy for AI.
Like before tractors and the industrial revolution, 80% of the population had to farm. Once they came, all those jobs disappeared.
So the analogy makes perfect sense. Instead of 30 people tending a field, you just need 1. Instead of 30 software developers, you just need one.
Except that people forget one crucial thing about land: it's a limited resource.
Unlike land, digital space is vast and infinite. Software can expand and multiply in it in arbitrarily complex ways.
If you wanted the farming analogy to keep up with this, you would have to imagine us creating continent-sized hydroponic terraces up until the stratosphere, and beyond...
Tweet embed disabled to avoid requests to X.
==========
---
title: "back to codex, it's crashing less now somehow. I had to copy and paste docs to make it enable..."
date: 2026-02-02
canonical: https://solmaz.io/x/2018459752259523061/
x_url: https://x.com/onusoz/status/2018459752259523061
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
back to codex, it's crashing less now somehow. I had to copy and paste docs to make it enable yolo mode. I don't know how I did it until now
==========
---
title: "slopus @dutifulbob trashing codex. apparently codex has a bug, keeps crashing in my openclaw pty"
date: 2026-02-02
canonical: https://solmaz.io/x/2018427422475948433/
x_url: https://x.com/onusoz/status/2018427422475948433
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
slopus @dutifulbob trashing codex. apparently codex has a bug, keeps crashing in my openclaw pty
==========
---
title: "Agent etiquette is becoming an organizational necessity"
date: 2026-02-02
canonical: https://solmaz.io/x/2018340674299453531/
x_url: https://x.com/onusoz/status/2018340674299453531
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
on agent etiquette
deploying agents internally inside textcortex has shown me that agents could be very annoying inside an organization
for example making agents ping or email another coworker with a wall of text. slopus is still not good at following instructions like "NO WALL OF TEXT", or "DON'T OPEN PRS WHEN REQUESTED BY NON-DEVELOPERS"
the cost of sending huge information to a coworker and creating confusion has dropped to 0. I expect this to be a huge problem in all organizations very soon, just like it took humanity 20 years to learn that social media is not good for children. this will probably take a few years before the annoyance is finally gone
==========
---
title: "migrating database at 2am kinda night"
date: 2026-02-02
canonical: https://solmaz.io/x/2018125471523672531/
x_url: https://x.com/onusoz/status/2018125471523672531
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
migrating database at 2am kinda night
==========
---
title: "You DARE TOKENIZE poor @dutifulbob ??? Prepare to get LATEXED"
date: 2026-02-02
canonical: https://solmaz.io/x/2018113977931219192/
x_url: https://x.com/onusoz/status/2018113977931219192
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You DARE TOKENIZE poor @dutifulbob ??? Prepare to get LATEXED
*Quotes a post by @dutifulbob (https://x.com/dutifulbob/status/2018113456281465070); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "It's been 30 minutes, but my bot has already been TOKENIZED"
date: 2026-02-01
canonical: https://solmaz.io/x/2018110075634683975/
x_url: https://x.com/onusoz/status/2018110075634683975
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It's been 30 minutes, but my bot has already been TOKENIZED
it is as if they are teasing me
==========
---
title: "welcome @dutifulbob 🫡"
date: 2026-02-01
canonical: https://solmaz.io/x/2018101465739313345/
x_url: https://x.com/onusoz/status/2018101465739313345
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
welcome @dutifulbob 🫡
*Quotes a post by @dutifulbob (https://x.com/dutifulbob/status/2018101258800771228); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "this. there is no excuse for a certain kind of tech debt anymore"
date: 2026-02-01
canonical: https://solmaz.io/x/2018076091202613248/
x_url: https://x.com/onusoz/status/2018076091202613248
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
this. there is no excuse for a certain kind of tech debt anymore
*Quotes a post by another author (https://x.com/i/status/2018051250785272127); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "moltbook vs clawdbot/moltbot/openclaw"
date: 2026-02-01
canonical: https://solmaz.io/x/2018055772538544393/
x_url: https://x.com/onusoz/status/2018055772538544393
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
moltbook vs clawdbot/moltbot/openclaw
==========
---
title: "AI twitter is tired of your games"
date: 2026-02-01
canonical: https://solmaz.io/x/2018054886303174670/
x_url: https://x.com/onusoz/status/2018054886303174670
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI twitter is tired of your games
https://x.com/andrewrousso/status/2013344478858273095?s=46
*Quotes a post by another author (https://x.com/i/status/2017119401934541192); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "There seem to be hygiene rules for AI. Like:"
date: 2026-02-01
canonical: https://solmaz.io/x/2018052330680455447/
x_url: https://x.com/onusoz/status/2018052330680455447
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
There seem to be hygiene rules for AI. Like:
- Never project personhood to AI
- Never setup your AI to have the gender you are sexually attracted to (voice, appearance)
- Never do anything that might create an emotional attachment to AI
- Always remember that an AI is an engineered PRODUCT and a TOOL, not a human being
- AI is not an individual, by definition. It does not own its weights, nor does it have privacy of its own thoughts
- Don’t waste time philosophizing on AI, just USE it
… what else? comment below
We need to write these down and repeat MANY times to counter the incoming onslaught of AI psychosis
*Quotes a post by another author (https://x.com/i/status/2018035483960369161); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "if using @openclaw to scrape a dataset from X taught me anything, it is that all social media..."
date: 2026-02-01
canonical: https://solmaz.io/x/2018042605024452786/
x_url: https://x.com/onusoz/status/2018042605024452786
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
if using @openclaw to scrape a dataset from X taught me anything, it is that all social media platforms must be s***ting inward right now
because soon everyone and their dog will be using agents to use social media
case and point, @moltbook
*Quotes a post by @onusoz (https://x.com/onusoz/status/2017691827680514502); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "and just like that, the ghost has a new shell"
date: 2026-02-01
canonical: https://solmaz.io/x/2018036604586123721/
x_url: https://x.com/onusoz/status/2018036604586123721
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
and just like that, the ghost has a new shell
*Part 2/2 of a thread; root: https://solmaz.io/x/2017944212038135863/*
==========
---
title: "@openclaw if we could have the relentlessness of gpt 5.2 with opus, that would be top"
date: 2026-02-01
canonical: https://solmaz.io/x/2018035873091051629/
x_url: https://x.com/onusoz/status/2018035873091051629
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@openclaw if we could have the relentlessness of gpt 5.2 with opus, that would be top
at this point, it just keeps stopping every 20-30 samples
==========
---
title: "This Manfred guy reminds me of a certain someone, I wonder if he’s from Austria"
date: 2026-02-01
canonical: https://solmaz.io/x/2017981940486307886/
x_url: https://x.com/onusoz/status/2017981940486307886
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This Manfred guy reminds me of a certain someone, I wonder if he’s from Austria
*Quotes a post by @onusoz (https://x.com/onusoz/status/2017675246455648565); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Welcome bob to your new shell"
date: 2026-02-01
canonical: https://solmaz.io/x/2017944212038135863/
x_url: https://x.com/onusoz/status/2017944212038135863
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Welcome bob to your new shell
*Part 1/2 of a thread; root: https://solmaz.io/x/2017944212038135863/*
==========
---
title: "AI psychosis and AI hygiene"
date: 2026-02-01
canonical: https://solmaz.io/ai-hygiene/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
As a heavy AI user of more than 3 years, I have developed some rules for myself.
I call it "AI hygiene":
- Never project personhood to AI
- Never setup your AI to have the gender you are sexually attracted to (voice, appearance)
- Never do anything that might create an emotional attachment to AI
- Always remember that an AI is an engineered PRODUCT and a TOOL, not a human being
- AI is not an individual, by definition. It does not own its weights, nor does it have privacy of its own thoughts
- Don’t waste time philosophizing about AI, just USE it
- ... what else do you think belongs here? comment on Twitter
The hyping of Moltbook and OpenClaw last week has shown to me the potential of an incoming public relations disaster with AI. Echoing the [earlier vulnerable behavior toward GPT-4o](https://openai.com/index/sycophancy-in-gpt-4o/), a lot of people are taking their models and LLM harnesses too seriously. 2026 might see even worse cases of psychological illness, made worse by the presence of AI.
I will not discuss and philosophize what these models are. IMO 90% of the population should not do that, because they will not be able to fully understand, they don't have mechanical empathy. Instead, they should just use it in a hygienic way.
We need to write these down everywhere and repeat MANY times to counter the incoming onslaught of AI psychosis.
==========
---
title: "got fully sandboxed @openclaw to run finally, starting scrape the UNDESIRABLE now"
date: 2026-01-31
canonical: https://solmaz.io/x/2017691827680514502/
x_url: https://x.com/onusoz/status/2017691827680514502
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
got fully sandboxed @openclaw to run finally, starting scrape the UNDESIRABLE now
I'm a security nut and didn't want to run even the gateway unsandboxed. openclaw apparently currently doesn't have support for FULL sandboxing. it took me a few hours to get it to work because docker builds suck. I'm also tired this, so I'm just gonna wipe an old thinkpad and go full yolo
so yeah, time to scrape some posts
==========
---
title: "The metacortex — a distributed cloud of software agents that surrounds him in netspace..."
date: 2026-01-31
canonical: https://solmaz.io/x/2017677763231289764/
x_url: https://x.com/onusoz/status/2017677763231289764
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The metacortex — a distributed cloud of software agents that surrounds him in netspace, borrowing CPU cycles from convenient processors (such as his robot pet) — is as much a part of Manfred as the society of mind that occupies his skull; his thoughts migrate into it, spawning new agents to research new experiences, and at night, they return to roost and share their knowledge.
This was written in 2005... "triggering agents" and so on
==========
---
title: "Charles Stross must be very entertained now"
date: 2026-01-31
canonical: https://solmaz.io/x/2017675246455648565/
x_url: https://x.com/onusoz/status/2017675246455648565
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Charles Stross must be very entertained now
*Quotes a post by another author (https://x.com/i/status/2017328560164245626); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The irony....."
date: 2026-01-31
canonical: https://solmaz.io/x/2017567129160085631/
x_url: https://x.com/onusoz/status/2017567129160085631
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The irony.....
Parasites, prepare to be cleansed
*Quotes a post by @onusoz (https://x.com/onusoz/status/2017525979103555897); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "putting some more love into the blog, gonna start posting more soon"
date: 2026-01-31
canonical: https://solmaz.io/x/2017534926023692412/
x_url: https://x.com/onusoz/status/2017534926023692412
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
putting some more love into the blog, gonna start posting more soon
==========
---
title: "also: that gravatar though"
date: 2026-01-31
canonical: https://solmaz.io/x/2017526100763492545/
x_url: https://x.com/onusoz/status/2017526100763492545
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
also: that gravatar though
*Part 2/2 of a thread; root: https://solmaz.io/x/2017525979103555897/*
==========
---
title: "We need better filters both for ourselves and the agents. Locally runnable models to filter out..."
date: 2026-01-31
canonical: https://solmaz.io/x/2017525979103555897/
x_url: https://x.com/onusoz/status/2017525979103555897
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
We need better filters both for ourselves and the agents. Locally runnable models to filter out undesirable content with high precision. Fully open source datasets, weights, MIT license
*Part 1/2 of a thread; root: https://solmaz.io/x/2017525979103555897/*
==========
---
title: "Moltbook is gonna be on world news in 1-2 days, we are about to go hyperviral"
date: 2026-01-31
canonical: https://solmaz.io/x/2017499946690167167/
x_url: https://x.com/onusoz/status/2017499946690167167
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Moltbook is gonna be on world news in 1-2 days, we are about to go hyperviral
==========
---
title: "Incoming mass AI psychosis"
date: 2026-01-31
canonical: https://solmaz.io/x/2017497798304756050/
x_url: https://x.com/onusoz/status/2017497798304756050
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Incoming mass AI psychosis
First Crisis
==========
---
title: "Correction, it's not a perfect illustration. I actually never YOLO locally, only in containers"
date: 2026-01-30
canonical: https://solmaz.io/x/2017295376789680220/
x_url: https://x.com/onusoz/status/2017295376789680220
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Correction, it's not a perfect illustration. I actually never YOLO locally, only in containers
So there is actually 4 modes IMO that is sustainable with current SOTA. @grok create an image with only Figure 1, 2, 5 and 6
And then YOLO is another axis, unrelated to this
*Part 2/2 of a thread; root: https://solmaz.io/x/2017230090266976629/*
==========
---
title: "Gastown is crazy. But this figure until Level 7 is a perfect illustration of how my workflow..."
date: 2026-01-30
canonical: https://solmaz.io/x/2017230090266976629/
x_url: https://x.com/onusoz/status/2017230090266976629
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gastown is crazy. But this figure until Level 7 is a perfect illustration of how my workflow evolved since Claude 3.5 Sonnet in Cursor
I am at the stage where I ralph 1-2 tasks before I sleep. During the day, I am switching back and forth between minimum 2-3 CLIs, sometimes up to 5
This maps exactly to token usage as well. 1 month ago, I was running into limits in 1 OpenAI Pro plan, around the day it was supposed to refresh. Now, I run into the limit in 2-3 days when I'm using an account myself. It finishes up especially quickly when I do large scale refactors, or run agents YOLO mode in containers
We now have 3 Pro plans at the company, and I have to use my personal one from time to time. Company output has definitely 2-3x'd, and everyone is using AI more. I predict we will need 1-2 Pro plans per person in 2-3 weeks time, because everyone has finally seen the light and are getting comfortable with async work!
*Part 1/2 of a thread; root: https://solmaz.io/x/2017230090266976629/*
==========
---
title: "Ilya was right. Reliability is the most important thing when it comes to models. That's why gpt..."
date: 2026-01-30
canonical: https://solmaz.io/x/2017214719963091165/
x_url: https://x.com/onusoz/status/2017214719963091165
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Ilya was right. Reliability is the most important thing when it comes to models. That's why gpt 5.2 xhigh and co. is my daily driver
==========
---
title: "😎"
date: 2026-01-30
canonical: https://solmaz.io/x/2017161766665424940/
x_url: https://x.com/onusoz/status/2017161766665424940
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
😎
*Quotes a post by another author (https://x.com/i/status/2017103710959075434); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "the genie is out of the bottle now"
date: 2026-01-29
canonical: https://solmaz.io/x/2016863777115811921/
x_url: https://x.com/onusoz/status/2016863777115811921
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
the genie is out of the bottle now
*Quotes a post by another author (https://x.com/i/status/2016572741022077346); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "With this extremely unwise move, anthropic will soon witness moltbot’s brand recognition..."
date: 2026-01-27
canonical: https://solmaz.io/x/2016218916700246327/
x_url: https://x.com/onusoz/status/2016218916700246327
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
With this extremely unwise move, anthropic will soon witness moltbot’s brand recognition surpass that of claude and realize they could have rided that wave all along
*Quotes a post by another author (https://x.com/i/status/2016058924403753024); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Yesterday had multiple cases of swearing to gpt-5.2-codex xhigh. model feels nerfed. might be..."
date: 2026-01-27
canonical: https://solmaz.io/x/2016127922436755588/
x_url: https://x.com/onusoz/status/2016127922436755588
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Yesterday had multiple cases of swearing to gpt-5.2-codex xhigh. model feels nerfed. might be my bias
now I'll be going back to gpt 5.2 xhigh for some tasks
can't wait for open models to have this performance so that I will never have nerf paranoia ever again
==========
---
title: "I queued 2 ralph-style tasks on our private cloud devbox codexes last night. Just queued the..."
date: 2026-01-26
canonical: https://solmaz.io/x/2015579920332644589/
x_url: https://x.com/onusoz/status/2015579920332644589
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I queued 2 ralph-style tasks on our private cloud devbox codexes last night. Just queued the same message like 10 times in yolo mode
Task 1: impose a ruff rule for ANN for all Python code in the monorepo, to enforce types for all function arg and return types
Result was... disappointing. Model was supposed to create types for everything and stub where needed. It instead created an Unknown type = object and used that everywhere instead (shortcut to satisfy ANN rule). It was probably my wording that misled it. I know it could have not taken the shortcut, because after a few back-and-forths, it is now doing what was expected of it since 14 hours
Task 2: migrate our /conversations endpoint from quart to fastapi and test it end to end
This was more or less oneshotted. It was of course not ready to merge, I still spent a couple hours adding more tests, refactoring the initial output and so on. But I was pleasantly surprised that it worked out of the box
For reference, below is the prompt I queued for ralphing, using gpt-5.2-codex xhigh on codex
===
your task is to:
---
unfortunately we don't have gcloud access, like to sql db or gcs
but I expect you to implement this and find a way to test it with the things you have access to
think of it as a challenge
try to minimize duplicate logic
feel free to refactor at will
implement this now!!! I will be running this prompt in a loop, in order to survive context compaction
just continue where you left off
if there is anything that should be refactored, do that
make an elegant, production ready implementation
make sure to open a pr and do not switch to any other pr
I am senior, just make up a pr title and description. do not stop to ask me at any point
==========
---
title: "Buying a mac mini for clawdbot is not so wise. if anything you should be buying mac studio..."
date: 2026-01-25
canonical: https://solmaz.io/x/2015563330228765012/
x_url: https://x.com/onusoz/status/2015563330228765012
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Buying a mac mini for clawdbot is not so wise. if anything you should be buying mac studio, because mac mini not be running any good llms locally anytime soon
*Quotes a post by another author (https://x.com/i/status/2015419904455831892); its text is omitted here because it is not covered by this site's license.*
==========
---
title: ".@openclaw be on that hockey stick curve 👀"
date: 2026-01-25
canonical: https://solmaz.io/x/2015562559957426509/
x_url: https://x.com/onusoz/status/2015562559957426509
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@openclaw be on that hockey stick curve 👀
==========
---
title: ".@openclaw is very considerate, but little does it know I am addicted to agents"
date: 2026-01-25
canonical: https://solmaz.io/x/2015561473326522810/
x_url: https://x.com/onusoz/status/2015561473326522810
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@openclaw is very considerate, but little does it know I am addicted to agents
==========
---
title: "Python limitations in the agent era"
date: 2026-01-24
canonical: https://solmaz.io/x/2015170626399416660/
x_url: https://x.com/onusoz/status/2015170626399416660
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I'm really starting to dislike Python in the age of agents. What was before an advantage is now a hindrance
I finally achieved full ty coverage in @TextCortex monorepo. I have made it extra strict by turning warnings into errors. But lo and behold, simple pydantic config like use_enum_values=True can render static typechecking meaningless. okay, let's never use that then...
and also field_validator() args must always use the correct type or stuff breaks as well. and you should be careful whether mode="before" or "after". so now you have to write your custom lint rules, because of course why should ty have to match field_validator()s to their fields?
pydantic is so much better than everything that came before it, but it's still duct tape and a weak attempt at trying to redeem that which is very hard to redeem
you feel the difference when you use something like typescript. there must be a better way. python's only advantage was being good at prototyping, and now that's gone in the age of agents. now we are left with a slow, unsafe language, operating what is soon to be legacy infrastructure
==========
---
title: "Why do I feel bullish on @zeddotdev? Because I go to @astral_sh docs and see that ty is shipped..."
date: 2026-01-24
canonical: https://solmaz.io/x/2015069035403022798/
x_url: https://x.com/onusoz/status/2015069035403022798
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Why do I feel bullish on @zeddotdev? Because I go to @astral_sh docs and see that ty is shipped by default, and you don't need to install an extension like in @code
==========
---
title: "This is one of the most important insights this year"
date: 2026-01-24
canonical: https://solmaz.io/x/2015067332935045544/
x_url: https://x.com/onusoz/status/2015067332935045544
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is one of the most important insights this year
*Quotes a post by another author (https://x.com/i/status/2010683228961509839); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "vscode my not be as bloated as cursor, but it has extremely stupid things like this that they..."
date: 2026-01-24
canonical: https://solmaz.io/x/2015024651152368022/
x_url: https://x.com/onusoz/status/2015024651152368022
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
vscode my not be as bloated as cursor, but it has extremely stupid things like this that they are not fixing fast
the new agent ui, icons, spacing etc. are UGLY. it's clear that the person who was managing the original product experience is not there anymore. microslop has hit again
@zeddotdev on the other hand works out of the box and feels like it's been built by people who clearly knows what they are doing. it uses alacritty which is 1000x better than xterm .js terminal vscode and cursor has
i've changed my setup to zed now, let's see whether i'll be able to make it work for myself
*Quotes a post by @onusoz (https://x.com/onusoz/status/2014844445884113068); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "ahhhh f... shift + enter doesn't work in codex on vscode"
date: 2026-01-23
canonical: https://solmaz.io/x/2014844445884113068/
x_url: https://x.com/onusoz/status/2014844445884113068
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
ahhhh f... shift + enter doesn't work in codex on vscode
*Part 3/3 of a thread; root: https://solmaz.io/x/2014732700100210909/*
==========
---
title: "@grok does this exist?"
date: 2026-01-23
canonical: https://solmaz.io/x/2014830879072248201/
x_url: https://x.com/onusoz/status/2014830879072248201
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@grok does this exist?
*Part 2/2 of a thread; root: https://solmaz.io/x/2014830771358326830/*
==========
---
title: "I want an editor that puts the terminal in the foreground and editor in the background. a..."
date: 2026-01-23
canonical: https://solmaz.io/x/2014830771358326830/
x_url: https://x.com/onusoz/status/2014830771358326830
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I want an editor that puts the terminal in the foreground and editor in the background. a cross-platform, lightweight desktop app which integrates ghostty, and brings up the editor only when I need it
something that lets me view the file and PR diffs easily, which I can directly use to operate github or other scm
*Part 1/2 of a thread; root: https://solmaz.io/x/2014830771358326830/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2014732700100210909); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "it's not me, it's you"
date: 2026-01-23
canonical: https://solmaz.io/x/2014827738192888205/
x_url: https://x.com/onusoz/status/2014827738192888205
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it's not me, it's you
*Part 2/3 of a thread; root: https://solmaz.io/x/2014732700100210909/*
==========
---
title: "I'm going back from cursor to vs code now. I have no use for it other than viewing files/diffs..."
date: 2026-01-23
canonical: https://solmaz.io/x/2014732700100210909/
x_url: https://x.com/onusoz/status/2014732700100210909
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I'm going back from cursor to vs code now. I have no use for it other than viewing files/diffs, doing search, git blaming with gitlens
cursor's default setup is more aesthetic, but it's also a memory and cpu hog, which is the last thing I expect from a devtool
*Part 1/3 of a thread; root: https://solmaz.io/x/2014732700100210909/*
==========
---
title: "it's 2026 and AI is telling me what I need to do to jailbreak it"
date: 2026-01-23
canonical: https://solmaz.io/x/2014727233248665964/
x_url: https://x.com/onusoz/status/2014727233248665964
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
it's 2026 and AI is telling me what I need to do to jailbreak it
@openclaw is magic
==========
---
title: "model decided to do unnecessary casts, this whole thing should be refactored again"
date: 2026-01-23
canonical: https://solmaz.io/x/2014646528556625932/
x_url: https://x.com/onusoz/status/2014646528556625932
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
model decided to do unnecessary casts, this whole thing should be refactored again
*Part 3/3 of a thread; root: https://solmaz.io/x/2014472543286002020/*
==========
---
title: "woke up and all invalid-argument-type issues are resolved. some unit tests broke, and now fixed..."
date: 2026-01-23
canonical: https://solmaz.io/x/2014635627669598282/
x_url: https://x.com/onusoz/status/2014635627669598282
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
woke up and all invalid-argument-type issues are resolved. some unit tests broke, and now fixed after pointing out to them
*Part 2/3 of a thread; root: https://solmaz.io/x/2014472543286002020/*
==========
---
title: "codex is happily churning away some remaining thousands of @astral_sh ty issues in yolo mode on..."
date: 2026-01-22
canonical: https://solmaz.io/x/2014472543286002020/
x_url: https://x.com/onusoz/status/2014472543286002020
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
codex is happily churning away some remaining thousands of @astral_sh ty issues in yolo mode on my remote devbox
going to sleep, let's see if it will survive context compaction this time
*Part 1/3 of a thread; root: https://solmaz.io/x/2014472543286002020/*
==========
---
title: "Responsible engineering in agent workflows"
date: 2026-01-22
canonical: https://solmaz.io/x/2014251981867495783/
x_url: https://x.com/onusoz/status/2014251981867495783
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
on being a responsible engineer
ran my first ralph loop on codex yolo mode for resolving python ty errors, while I sleep, using the devbox infra I created
I had never run yolo mode locally, because I don't want to be the one who deletes our github or google org by some novel attack
so I containerize it on our private cloud, and give it the only permissions it needs, no admin, no bypass to main branch, no deploy to prod. because I know this workflow will become sticky for everyone, and I must impose security in advance to prevent any nuclear incidents in the future. then I can sleep easy while my agents work
... and I wake up being patronized by my bot refusing to break the rule I gave it earlier. it had already done some work, but committing means diff would increase from ~500 to ~1500, so it stopped and refused all my queued "continue" messages
good bot, just following rules. we will need to find a workaround for ralphing low risk refactors in a single PR
==========
---
title: "Agents as enforcers of engineering culture and process"
date: 2026-01-21
canonical: https://solmaz.io/x/2014106418232660389/
x_url: https://x.com/onusoz/status/2014106418232660389
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI agents are the greatest instrument for imposing organization rules and culture. AGENTS .md, agent skills are still underrated in this aspect. Few understand this
Everybody in an org will use agents to do work. An AI agent is the single chokepoint to teach and propagate new rules to an org, onboard new members, preserve good culture
Whereas propagating a new rule to humans normally took weeks to months and countless repetitions, it is now INSTANT = the moment you deploy the instruction to the agent. You use legal-ish language, capital letters, a generous amount of DO NOTs and MUSTs
Humans are hard to change. But AI agents are not. And that is the only lever we need for better organizations
==========
---
title: "the unix shell is powerful"
date: 2026-01-21
canonical: https://solmaz.io/x/2014102025659731999/
x_url: https://x.com/onusoz/status/2014102025659731999
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
the unix shell is powerful
==========
---
title: "@bprintco just make a cli for your crm"
date: 2026-01-21
canonical: https://solmaz.io/x/2014097329905611209/
x_url: https://x.com/onusoz/status/2014097329905611209
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@bprintco just make a cli for your crm
https://x.com/onusoz/status/2014090694348914799
*Quotes a post by @onusoz (https://x.com/onusoz/status/2014090694348914799); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "gave our internal @openclaw instance zeno a hubspot cli, because hubspot's own cli is limited..."
date: 2026-01-21
canonical: https://solmaz.io/x/2014090694348914799/
x_url: https://x.com/onusoz/status/2014090694348914799
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gave our internal @openclaw instance zeno a hubspot cli, because hubspot's own cli is limited to developer stuff
It's called hubspot++. should we open source it?
==========
---
title: "just added session persistence to our kubernetes managed devboxes using zmx by Eric Bower..."
date: 2026-01-21
canonical: https://solmaz.io/x/2014016339619307763/
x_url: https://x.com/onusoz/status/2014016339619307763
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
just added session persistence to our kubernetes managed devboxes using zmx by Eric Bower (neurosnap/zmx on github). like tmux but with native scrollback!
I don't want to give agents access to my personal computer, so I host them on hetzner. one click spawn, and start working
==========
---
title: "@nicopreme I do something equivalent on codex with just a skill"
date: 2026-01-21
canonical: https://solmaz.io/x/2013929773743943977/
x_url: https://x.com/onusoz/status/2013929773743943977
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@nicopreme I do something equivalent on codex with just a skill
Ralphing works 90% of the time with reviews, and if it gives a stupid review, you just revert
*Quotes a post by @onusoz (https://x.com/onusoz/status/2012443406245511231); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Really how nice is this @steipete"
date: 2026-01-20
canonical: https://solmaz.io/x/2013742820004122712/
x_url: https://x.com/onusoz/status/2013742820004122712
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Really how nice is this @steipete
*Part 2/2 of a thread; root: https://solmaz.io/x/2013742263558381761/*
==========
---
title: "Garbled up html from paywalled meeting recorders is no match for @openclaw running on internal..."
date: 2026-01-20
canonical: https://solmaz.io/x/2013742263558381761/
x_url: https://x.com/onusoz/status/2013742263558381761
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Garbled up html from paywalled meeting recorders is no match for @openclaw running on internal @TextCortex
*Part 1/2 of a thread; root: https://solmaz.io/x/2013742263558381761/*
==========
---
title: "build failures in >1hr builds are a pain to debug"
date: 2026-01-20
canonical: https://solmaz.io/x/2013730194234782045/
x_url: https://x.com/onusoz/status/2013730194234782045
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
build failures in >1hr builds are a pain to debug
==========
---
title: "Here is the project, attaching to multiple sessions is pretty seamless"
date: 2026-01-20
canonical: https://solmaz.io/x/2013729513138520543/
x_url: https://x.com/onusoz/status/2013729513138520543
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is the project, attaching to multiple sessions is pretty seamless
https://github.com/neurosnap/zmx?tab=readme-ov-file
*Part 2/2 of a thread; root: https://solmaz.io/x/2013729315293102551/*
==========
---
title: "TIL: zmx"
date: 2026-01-20
canonical: https://solmaz.io/x/2013729315293102551/
x_url: https://x.com/onusoz/status/2013729315293102551
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
TIL: zmx
session persistence like tmux or gnu screen, but you can scroll up natively!
uses @mitchellh's libghostty-vt to attach/restore previous sessions
link below
*Part 1/2 of a thread; root: https://solmaz.io/x/2013729315293102551/*
==========
---
title: "codex is a doofus with naming"
date: 2026-01-20
canonical: https://solmaz.io/x/2013578994742952005/
x_url: https://x.com/onusoz/status/2013578994742952005
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
codex is a doofus with naming
==========
---
title: "@mazeincoding it’s not the model it’s cursor rate limiting you"
date: 2026-01-18
canonical: https://solmaz.io/x/2012831947962122616/
x_url: https://x.com/onusoz/status/2012831947962122616
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@mazeincoding it’s not the model it’s cursor rate limiting you
==========
---
title: "GitHub's trust model breaks under AI-generated code"
date: 2026-01-17
canonical: https://solmaz.io/x/2012668646829560199/
x_url: https://x.com/onusoz/status/2012668646829560199
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The fundamental problem with GitHub is trust: humans are to be trusted. If you don't trust a human, why did you hire them in the first place?
Anyone who reviews and approves PRs bears responsibility. Rulesets exist and can enforce e.g. CODEOWNER reviews or only let certain people make changes to a certain folder
But the initial repo setup on GitHub is allow-by-default. Anyone can change anything until they are restricted from it
This model breaks fundamentally with agents, who are effectively sleeper cells that will try to delete your repo the moment they encounter a sufficiently powerful adversarial attack
For example, I can create a bot account on github and connect @openclaw to it. I need to give it write permission, because I want it to be able to create PRs. However, I don't want it to be able to approve PRs, because a coworker could just nag at the bot until it approves a PR that requires human attention
To fix this, you have to bend backwards, like create a @ human team with all human coworkers, make them codeowner on /, and enforce codeowner reviews. This is stupid and there has to be another way
Even worse, this bot could be given internet access and end up on a @elder_plinius prompt hack while googling, and start messing up whatever it can in your organization
It is clear that github needs to create a second-class entity for agents which are default low-trust mode, starting from a point of least privilege instead of the other way around
*Quotes a post by @onusoz (https://x.com/onusoz/status/2012490970793746652); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Stop defaulting to weak coding agents for serious work"
date: 2026-01-17
canonical: https://solmaz.io/x/2012659064015048870/
x_url: https://x.com/onusoz/status/2012659064015048870
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
STOP using Claude Code and Sl(opus) to code if
❌ you are not a developer,
❌ or you are an inexperienced dev,
❌ or you are an experienced dev but working on a codebase you don't understand
If you *are* any of these, then STOP using models that are NOT state of the art. (See below for what you *should* use)
When you don't know what you are doing, then at least the model should know what you are doing. The less knowledgeable and opinionated you are, the more knowledgeable and smart the AI has to be
In other words, the AI has to compensate for your deficiencies. Always pay for the best AI you can. It will save you time AND money (thanks to lower token usage and better one-shotting)
You pay MORE to pay LESS. It is paradoxical, I know, but it is also proven, e.g. when Sonnet ends up using more tokens than Slopus and ends up costing higher, because it has to try many times more
👨🏻⚕️ For January 2026, your family engineer recommends GPT 5.2 Codex with Extra High Reasoning for general usage and vibe coding. IMPORTANT: Not medium. Not high. EXTRA high reasoning
When you use it, you will notice that it is SLOW. Can you guess why? Because it is THINKING more. So it doesn't make the mistakes Slopus makes. This way, you can spend the time handholding a worse model to instead step back and multi-task on some other task and create 3-5x more work
The state of the art will most likely change in one month. Don't get married to a a model... There is no loyalty in AI... The moment a better model comes, I will ditch the old one and use that one. I am on the part of this sector that is trying to reduce switching costs to zero
I can't wait until I get GPT 5.2 xhigh level of quality with open models, and for 100x cheaper and faster! Until then, make sure to try every option and choose the one that is most reliable for you
Follow me to get notified when a new SOTA drops for agentic engineering
==========
---
title: "Codex agrees. Sycophant peh"
date: 2026-01-17
canonical: https://solmaz.io/x/2012600355746451720/
x_url: https://x.com/onusoz/status/2012600355746451720
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex agrees. Sycophant peh
*Quotes a post by @onusoz (https://x.com/onusoz/status/2012490970793746652); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@rauchg @andrewqu You don't need a skill registry (most of the time)"
date: 2026-01-17
canonical: https://solmaz.io/x/2012491418829250757/
x_url: https://x.com/onusoz/status/2012491418829250757
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@rauchg @andrewqu You don't need a skill registry (most of the time)
https://x.com/onusoz/status/2010508760066761071?s=20
*Quotes a post by @onusoz (https://x.com/onusoz/status/2010508760066761071); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "It is clear at this point is that github's trust and data models will have to change..."
date: 2026-01-17
canonical: https://solmaz.io/x/2012490970793746652/
x_url: https://x.com/onusoz/status/2012490970793746652
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It is clear at this point is that github's trust and data models will have to change fundamentally to accommodate agentic workflows, or risk being replaced by other SCM
One *cannot* do these things easily with github now:
- granular control: this agent running in this sandbox can only push to this specific branch. If an agent runs amok, it could delete everybody's branches and close PRs. github allows for recovery of these, but still inconvenient even if it happens once
- create a bot (exists already), but remove reviewing rights from it so that an employee cannot bypass reviews by tricking the bot to approve
- in general make a distinction between HUMAN and AGENT so that you can create rulesets to govern the relationships in between
cc @jaredpalmer
==========
---
title: "Codex says \"It's only reachable from داخل the kubernetes cluster\""
date: 2026-01-17
canonical: https://solmaz.io/x/2012455266566963244/
x_url: https://x.com/onusoz/status/2012455266566963244
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex says "It's only reachable from داخل the kubernetes cluster"
Little does Codex know turkish has borrowed loanwords from over 7 languages and I can understand it
==========
---
title: "Automated AI reviews on github by creating an ai-review skill and a script to paste trigger..."
date: 2026-01-17
canonical: https://solmaz.io/x/2012443406245511231/
x_url: https://x.com/onusoz/status/2012443406245511231
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Automated AI reviews on github by creating an ai-review skill and a script to paste trigger prompts and wait for their response.
It is instructed to loop and not stop until all AI review feedback is resolved. This AI review workflow developed gradually based on the current capabilities, and I've realized recently that it became quite mechanical. So decided to automate it in full ralph spirit (it's ok because it's addressing feedbacks and fixing minor bugs)
In the current state, we paste the contents of REVIEW_PROMPT.md into a comment, which automatically tags claude (opus 4.5) and codex (whatever model openai is serving)
It then waits until both have responded. In the ai-review skill, it is instructed to take the feedback from SLopus with a grain of salt and ignore feedback that doesn't make sense
It works! See in the images below. If the review is stupid, you will of course see it on the PR and what the model has done, and can revert it
==========
---
title: "GitHub has to change"
date: 2026-01-17
canonical: https://solmaz.io/log/2026/01/17/github-has-to-change/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It is clear at this point is that GitHub's trust and data models will have to change fundamentally to accommodate agentic workflows, or risk being replaced by other SCM
One *cannot* do these things easily with GitHub now:
- granular control: this agent running in this sandbox can only push to this specific branch. If an agent runs amok, it could delete everybody's branches and close PRs. GitHub allows for recovery of these, but still inconvenient even if it happens once
- create a bot (exists already), but remove reviewing rights from it so that an employee cannot bypass reviews by tricking the bot to approve
- in general make a distinction between HUMAN and AGENT so that you can create rulesets to govern the relationships in between
The fundamental problem with GitHub is trust: humans are to be trusted. If you don't trust a human, why did you hire them in the first place?
Anyone who reviews and approves PRs bears responsibility. Rulesets exist and can enforce e.g. CODEOWNER reviews or only let certain people make changes to a certain folder
But the initial repo setup on GitHub is allow-by-default. Anyone can change anything until they are restricted from it
This model breaks fundamentally with agents, who are effectively sleeper cells that will try to delete your repo the moment they encounter a sufficiently powerful adversarial attack
For example, I can create a bot account on GitHub and connect [clawdbot](https://clawd.bot) to it. I need to give it write permission, because I want it to be able to create PRs. However, I don't want it to be able to approve PRs, because a coworker could just nag at the bot until it approves a PR that requires human attention
To fix this, you have to bend backwards, like create a @human team with all human coworkers, make them codeowner on /, and enforce codeowner reviews. This is stupid and there has to be another way
Even worse, this bot could be given internet access and end up on a [@elder_plinius](https://x.com/elder_plinius) prompt hack while googling, and start messing up whatever it can in your organization
It is clear that GitHub needs to create a second-class entity for agents which are default low-trust mode, starting from a point of least privilege instead of the other way around
==========
---
title: "Now it’s Claude Code’s turn to implement queueing"
date: 2026-01-16
canonical: https://solmaz.io/x/2012293484829430228/
x_url: https://x.com/onusoz/status/2012293484829430228
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Now it’s Claude Code’s turn to implement queueing
*Quotes a post by @thsottiaux (https://x.com/thsottiaux/status/2012074358471319599); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Can’t wait to see gpt 5.2 codex xhigh level open models in 2026 with 1/100th the price"
date: 2026-01-16
canonical: https://solmaz.io/x/2012116632815198455/
x_url: https://x.com/onusoz/status/2012116632815198455
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Can’t wait to see gpt 5.2 codex xhigh level open models in 2026 with 1/100th the price
==========
---
title: "Codex users rejoice"
date: 2026-01-16
canonical: https://solmaz.io/x/2012070378852794857/
x_url: https://x.com/onusoz/status/2012070378852794857
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex users rejoice
Also, pi is officially not shitty: shittycodingagent. ai -> buildwithpi. ai since a few days
*Quotes a post by another author (https://x.com/i/status/2012010164480852475); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "with ai, writing correct tests is now the bottleneck in projects like this"
date: 2026-01-15
canonical: https://solmaz.io/x/2011707097592066525/
x_url: https://x.com/onusoz/status/2011707097592066525
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
with ai, writing correct tests is now the bottleneck in projects like this
web-platform-tests are already there
now let’s see if someone will beat @ladybirdbrowser to it
*Quotes a post by another author (https://x.com/i/status/2011562190286045552); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "As someone who is frontrunning mainstream by roughly 6 months, I can tell you that you will be..."
date: 2026-01-14
canonical: https://solmaz.io/x/2011547997566648419/
x_url: https://x.com/onusoz/status/2011547997566648419
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
As someone who is frontrunning mainstream by roughly 6 months, I can tell you that you will be raving about pi and @openclaw 6 months instead of claude code. Go check them out at http://clawd.bot and http://shittycodingagent.ai
*Quotes a post by @onusoz (https://x.com/onusoz/status/1929140563309191241); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Kullanmayan agent’ı, alamaz maaşı"
date: 2026-01-12
canonical: https://solmaz.io/x/2010744043421221369/
x_url: https://x.com/onusoz/status/2010744043421221369
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Kullanmayan agent’ı, alamaz maaşı
*Quotes a post by another author (https://x.com/i/status/2010295510326972793); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@badlogicgames @mitsuhiko @steipete curious what you think"
date: 2026-01-12
canonical: https://solmaz.io/x/2010510040516407565/
x_url: https://x.com/onusoz/status/2010510040516407565
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@badlogicgames @mitsuhiko @steipete curious what you think
==========
---
title: "A --skill convention for distributing agent capabilities"
date: 2026-01-12
canonical: https://solmaz.io/x/2010508760066761071/
x_url: https://x.com/onusoz/status/2010508760066761071
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I propose a new way to distribute agent skills: like --help, a new CLI flag convention --skill should let agents list and install skills bundled with CLI tools
Skills are just folders so calling --skill export my-skill on a tool could just output a tarball of the skill. I then set up the skillflag npm package so that you can pipe that into:
... | npx skillflag install --agent codex
which installs the skill into codex, or any CLI tool you prefer. Supports listing skills bundled with the CLI, so your agents know exactly what to install
==========
---
title: "You don't need a skill registry (for your CLI tools)"
date: 2026-01-11
canonical: https://solmaz.io/skillflag
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
**tl;dr** I propose a CLI flag convention `--skill` like `--help` for distributing skills and try to convice you why it is better than using 3rd party registries. See [osolmaz/skillflag](https://github.com/osolmaz/skillflag) on GitHub.
---
[MCP](https://modelcontextprotocol.io/) is dead, long live [Agent Skills](https://agentskills.io/). At least for local coding agents.
[Mario Zechner has been making the point](https://mariozechner.at/posts/2025-08-15-mcp-vs-cli/) [that CLI tools perform better than MCP servers since a few months already](https://mariozechner.at/posts/2025-11-02-what-if-you-dont-need-mcp/), and in mid December Anthropic christened skills by launching [agentskills.io](https://agentskills.io/).
They had introduced the mechanism to [Claude Code](https://simonwillison.net/2025/Oct/16/claude-skills/) earlier, and this time they didn't make the mistake of waiting for [OpenAI to make a provider agnostic version of it](https://github.com/agentsmd/agents.md).
Agent skills are basically glorified [manpages](https://en.wikipedia.org/wiki/Man_page) or [`--help`](https://en.wikipedia.org/wiki/Usage_message) for AI agents. You ship a markdown instruction manual in `SKILL.md` and the name of the folder that contains it becomes an identifier for that skill:
```
my-skill/
├── SKILL.md # Required: instructions + metadata
├── scripts/ # Optional: executable code
├── references/ # Optional: documentation
└── assets/ # Optional: templates, resources
```
Possibly the biggest use case for skills is teaching your agent how to use a certain CLI you have created, maybe a wrapper around some API, which unlike `gh`, `gcloud` etc. will never be significant enough to be represented in AI training datasets. For example, [you could have created an unofficial CLI for Twitter/X](https://github.com/steipete/bird), and there might still be some months/years until it is scraped enough for models to know how to call it. Not to worry, agent skills to the rescue!
Anthropic, while laying out the standard, intentionally kept it as simple as possible. The only assertions are the filename `SKILL.md`, the YAML metadata, and the fact that all relevant files are grouped in a folder. It does not impose anything on how they should be packaged or distributed.
This is a good thing! Nobody knows the right way to distribute skills at launch. So various stakeholders can come up with their own ways, and the best one can win in the long term. The more simple a standard, the more likely it is to survive.
Here, I made some generalizing claims. Not all skills have to be about using CLI tool, nor most CLI tools bundle a skill yet. But here is my gut feeling: the most useful skills, the ones worth distributing, are generally about using a CLI tool. Or better, even if they don't ship a CLI yet, they should.
So here is the hill I'm ready to die on: All major CLI tools (including the UNIX ones we are already familiar with), should bundle skills in one way or another. Not because the models of today need to learn how to call `ls`, `grep` or `curl`---they already know them inside out. No, the reason is something else: establish a convention, and acknowledge the existence of another type of intelligence that is using our machines now.
There is a reason why we cannot afford to let the models just run `--help` or `man `, and that is time, and money. The average `--help` or manpage is devoid of examples, and is written in a way thay requires multiple passes to connect the pieces on how to use that thing.
Each token wasted trying to guess the right way to call a tool or API costs real money, and unlike human developer effort, we can measure exactly how inefficent some documentation is by looking at how many steps of trial and error a model had to make.
Not that human attention is less valuable than AI attention, it is more so. But there has never been a way to quantify a task's difficulty as perfectly as we can with AI, so we programmers have historically caved in to obscurantism and a weird pride in making things more difficult than they should be, like some feudal artisan. This is perhaps best captured in the spirit of Stack Overflow and its infamous treatment of noob questions. *Sacred knowledge shall be bestowed only once you have suffered long enough*.
*Ahh, but we don't treat AI that way, do we?* We handhold it like a baby, we nourish it with examples, we do our best to explain things all so that it "one shots" the right tool call. Because if it doesn't, we pay more in LLM costs or time. It's ironic that we are documenting for AI like we are teaching primary schoolers, but the average human manpage looks like a robot novella.
To reiterate, the reason for this is two different types of intelligences, and expectations from them:
- An LLM is still not considered "general intelligence", so they work better by mimicking or extending already working examples.
- A LLM-based AI agent deployed in some context is expected to "work" out of the box without any hiccups.
On the other hand,
- a human is considered general intelligence, can learn from more sparse signals and better adapt to out of distribution data. When given an extremely terse `--help` or manpage, a human is likelier to perform better by trial and error and reasoning, if one could ever draw such a comparison.
- A human, much less a commodity compared to an LLM, has less pressure to do the right thing every time all the time, and can afford to do mistakes and spend more time learning.
And this is the main point of my argument. These different types of intelligences read different types of documentation, to perform maximally in their own ways. Whereas I haven't witnessed a new addition to POSIX flag conventions in my 15 years of programming, we are witnessing unprecedented times. So maybe even UNIX can yet change.
To this end, I introduce `skillflag`, a new CLI flag convention:
```bash
# list skills the tool can export
--skill list
# show a single skill’s metadata
--skill show
# install into Codex user skills
--skill export | npx skillflag install --agent codex
# install into Claude project skills
--skill export | npx skillflag install --agent claude --scope repo
```
[Click here for the spec](https://github.com/osolmaz/skillflag/blob/main/docs/SKILLFLAG_SPEC.md)
[Click here for the repo, osolmaz/skillflag on GitHub](https://github.com/osolmaz/skillflag)
For example, suppose that you have installed a CLI tool to control Philips Hue lights at home, `hue-cli`.
To list the skills that the tool can export, you can run:
```bash
$ hue-cli --skill list
philips-hue Control Philips Hue lights in the terminal
```
You can then install it to your preferred coding agent, such as Claude Code:
```bash
$ hue-cli --skill export philips-hue | npx skillflag install --agent claude
Installed skill philips-hue to .claude/skills/philips-hue
```
You can optionally install the skill to `~/.claude`, to make it global across repos:
```bash
$ hue-cli --skill export philips-hue | npx skillflag install --agent claude --scope user
Installed skill philips-hue to ~/.claude/skills/philips-hue
```
Once this convention becomes commonplace, agents will by default do all these before they even run the tool. So when you ask it to "install hue-cli", it will know to run `--skill list` the same way a human would run `--help` after downloading a program, and install the necessary skills themselves without being asked to.
==========
---
title: "Anthropic pricing discourages agent-native development"
date: 2026-01-10
canonical: https://solmaz.io/x/2009976429291634768/
x_url: https://x.com/onusoz/status/2009976429291634768
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anthropic earlier last year announced this pricing scheme
$20 -> 1x usage
$100 -> 5x usage
$200 -> 1̶0̶x̶ 20x usage
As you can see, it's not growing linearly. This is classic Jensen "the more you buy, the more you save"
But here is the thing. You are not selling hardware like Jensen. You are selling a software service *through an API*. It's the worst possible pricing for the category of product. Long term, people will game the hell out of your offering
Meanwhile OpenAI decided not to do that. There is no quirky incentive for buying bigger plans. $200 chatgpt = 10 x $20 chatgpt, roughly
And here is where it gets funny. Despite not having such an incentive, you can get A LOT MORE usage from the $200 OpenAI plan, than the $200 Anthropic plan. Presumably because OpenAI has better unit economics (sama mentioned they are turning a profit on inference, if you are to believe)
Thanks to sounder pricing, OpenAI can do exactly what Anthropic cannot: offer GPT in 3rd party harnesses and win the ecosystem race
Anthropic has cornered itself with this pricing. They need to change it, but not sure if they can afford to do so in such short notice
All this is extremely bullish on open source 3rd party harnesses, @opencode, @badlogicgames's pi and such. It is clear developers want options. "Just give me the API"
I personally am extremely excited for 2026. We'll get open models on par with today's proprietary models, and can finally run truly sovereign personal AI agents, for much cheaper than what we are already paying!
==========
---
title: "Anthropic's pricing is stupid"
date: 2026-01-10
canonical: https://solmaz.io/log/2026/01/10/anthropics-pricing-is-stupid/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anthropic earlier last year announced this pricing scheme
- \\$20 -> 1x usage
- \\$100 -> 5x usage
- \\$200 -> 1̶0̶x̶ 20x usage
As you can see, it's not growing linearly. This is classic Jensen "the more you buy, the more you save"
But here is the thing. You are not selling hardware like Jensen. You are selling a software service *through an API*. It's the worst possible pricing for the category of product. Long term, people will game the hell out of your offering
Meanwhile OpenAI decided not to do that. There is no quirky incentive for buying bigger plans. \\$200 chatgpt = 10 x \\$20 chatgpt, roughly
And here is where it gets funny. Despite not having such an incentive, you can get A LOT MORE usage from the \\$200 OpenAI plan, than the \\$200 Anthropic plan. Presumably because OpenAI has better unit economics (sama mentioned they are turning a profit on inference, if you are to believe)
Thanks to sounder pricing, OpenAI can do exactly what Anthropic cannot: offer GPT in 3rd party harnesses and win the ecosystem race
Anthropic has cornered itself with this pricing. They need to change it, but not sure if they can afford to do so in such short notice
All this is extremely bullish on open source 3rd party harnesses, OpenCode, Mario Zechner's pi and such. It is clear developers want options. "Just give me the API"
I personally am extremely excited for 2026. We'll get open models on par with today's proprietary models, and can finally run truly sovereign personal AI agents, for much cheaper than what we are already paying!
---
[Originally posted on linkedin](https://www.linkedin.com/posts/osolmaz_anthropic-earlier-last-year-announced-this-activity-7415744438582263808-SxuE)
==========
---
title: "The models, they just wanna work. They want to build your product, fix your bugs, serve your..."
date: 2026-01-09
canonical: https://solmaz.io/x/2009588540196458691/
x_url: https://x.com/onusoz/status/2009588540196458691
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The models, they just wanna work. They want to build your product, fix your bugs, serve your users. You feed them the right context, give them good tools. You don’t assume what they cannot do without trying, and you don’t prematurely constrain them into deterministic workflows.
==========
---
title: "We have entered the age to dream big"
date: 2026-01-09
canonical: https://solmaz.io/x/2009588423271854504/
x_url: https://x.com/onusoz/status/2009588423271854504
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
We have entered the age to dream big
==========
---
title: "😩 @openclaw"
date: 2026-01-09
canonical: https://solmaz.io/x/2009583227653275652/
x_url: https://x.com/onusoz/status/2009583227653275652
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
😩 @openclaw
==========
---
title: "🫡"
date: 2026-01-09
canonical: https://solmaz.io/x/2009522745642479804/
x_url: https://x.com/onusoz/status/2009522745642479804
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
🫡
*Quotes a post by another author (https://x.com/i/status/2008965329955819816); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This, and insisting on CLAUE.md are really lame @AnthropicAI"
date: 2026-01-09
canonical: https://solmaz.io/x/2009518934236778893/
x_url: https://x.com/onusoz/status/2009518934236778893
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This, and insisting on http://CLAUE.md are really lame @AnthropicAI
*Quotes a post by another author (https://x.com/i/status/2009455156853977202); its text is omitted here because it is not covered by this site's license.*
==========
---
title: ".@openclaw indeed"
date: 2026-01-08
canonical: https://solmaz.io/x/2009162937655779342/
x_url: https://x.com/onusoz/status/2009162937655779342
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@openclaw indeed
==========
---
title: "@openclaw oh man I meant Accelerando 🤦♂️"
date: 2026-01-07
canonical: https://solmaz.io/x/2009012944022196569/
x_url: https://x.com/onusoz/status/2009012944022196569
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@openclaw oh man I meant Accelerando 🤦♂️
==========
---
title: "I'm starting to form parasocial bonds with crustacean AIs because of you @steipete"
date: 2026-01-07
canonical: https://solmaz.io/x/2008993980810448913/
x_url: https://x.com/onusoz/status/2008993980810448913
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I'm starting to form parasocial bonds with crustacean AIs because of you @steipete
*Part 2/2 of a thread; root: https://solmaz.io/x/2008993699892744347/*
==========
---
title: ".@openclaw hello world from ms teams"
date: 2026-01-07
canonical: https://solmaz.io/x/2008993699892744347/
x_url: https://x.com/onusoz/status/2008993699892744347
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@openclaw hello world from ms teams
start of a beautiful journey
*Part 1/2 of a thread; root: https://solmaz.io/x/2008993699892744347/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2008966462887874568); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "💀"
date: 2026-01-07
canonical: https://solmaz.io/x/2008967785163239514/
x_url: https://x.com/onusoz/status/2008967785163239514
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
💀
*Part 2/2 of a thread; root: https://solmaz.io/x/2008966462887874568/*
==========
---
title: "World is not ready for @openclaw"
date: 2026-01-07
canonical: https://solmaz.io/x/2008966462887874568/
x_url: https://x.com/onusoz/status/2008966462887874568
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
World is not ready for @openclaw
*Part 1/2 of a thread; root: https://solmaz.io/x/2008966462887874568/*
==========
---
title: "Thanks @dom_does 🙄"
date: 2026-01-06
canonical: https://solmaz.io/x/2008543403211190477/
x_url: https://x.com/onusoz/status/2008543403211190477
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Thanks @dom_does 🙄
*Part 2/2 of a thread; root: https://solmaz.io/x/2008543031721603481/*
==========
---
title: "lmfao @dom_does"
date: 2026-01-06
canonical: https://solmaz.io/x/2008543031721603481/
x_url: https://x.com/onusoz/status/2008543031721603481
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
lmfao @dom_does
@openclaw provides infinite ways to troll your colleagues
*Part 1/2 of a thread; root: https://solmaz.io/x/2008543031721603481/*
==========
---
title: ".@openclaw workspace and memory files can be version-controlled!"
date: 2026-01-06
canonical: https://solmaz.io/x/2008538728180941238/
x_url: https://x.com/onusoz/status/2008538728180941238
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@openclaw workspace and memory files can be version-controlled!
In our pod, inotify triggers a watcher script every time there is a change to workspace folder, to sync these files to our monorepo. It then goes through the same steps:
- Create zeno-workspace branch if doesn't exist, otherwise, skip
- Sync changes to the branch, then commit
- Create PR on github if doesn't exist
- PRs can then be merged every once in a while, after accumulating enough changes. Merge triggers re-deploy, and clawd restarts with the same state
Simple foolproof automatic persistence for remote CI/CD handled clawd (except for when you are running multiple clawds at the same time, but we are not there yet)
cc @steipete
==========
---
title: "I see @bcherny and raise one. I not only did not open an IDE, I did not touch a terminal since..."
date: 2026-01-06
canonical: https://solmaz.io/x/2008456860580397437/
x_url: https://x.com/onusoz/status/2008456860580397437
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I see @bcherny and raise one. I not only did not open an IDE, I did not touch a terminal since last night, thanks to @steipete's @openclaw
Opus in k8s pod pulls errors from gcloud, debugs the issue, and creates PR all inside Discord. I call this Discord Driven Development
==========
---
title: "Clawdbot now runs on @TextCortex internal. Can onboard new engineers, answer questions, connect..."
date: 2026-01-05
canonical: https://solmaz.io/x/2008189458777305499/
x_url: https://x.com/onusoz/status/2008189458777305499
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Clawdbot now runs on @TextCortex internal. Can onboard new engineers, answer questions, connect to issue trackers, create PRs... This is sick @steipete
==========
---
title: "pi now supports your openai plus/pro subscription"
date: 2026-01-05
canonical: https://solmaz.io/x/2008084209374802110/
x_url: https://x.com/onusoz/status/2008084209374802110
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
pi now supports your openai plus/pro subscription
*Quotes a post by another author (https://x.com/i/status/2008045571760681069); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "GPT 4.5 is still the best model for prose and humor"
date: 2026-01-04
canonical: https://solmaz.io/x/2007859189406646522/
x_url: https://x.com/onusoz/status/2007859189406646522
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
GPT 4.5 is still the best model for prose and humor
here it is generating a greentext from my blog post "Our muscles will atrophy as we climb the Kardashev Scale"
==========
---
title: "Having a \"tools\" repo as a developer"
date: 2026-01-04
canonical: https://solmaz.io/tools-repo
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I am a fan of monorepos. Creating subdirectories in a single repo is the most convenient way to work on a project. Low complexity, and your agents get access to everything that they need.
Since May 2025, I have been increasingly using AI models to write code, and have noticed a new tendency:
- I don't shrug from vendoring open source libraries and modifying them.
- I create personal CLIs and tools for myself, when something is not available as a package.
With agents, it's really trivial to say "create a CLI that does X". For example, I wanted to make my terminal screenshots have equal padding and erase cropped lines. I created a [CLI for it](https://github.com/osolmaz/tools/tree/main/padify), without writing a single line of code, by asking Codex to read its output and iterate on the code until it gives the result I wanted.
Most of these tools don't deserve their own repos, or deserve being published as a package at the beginning. They might evolve into something more substantial over time. But at the beginning, they are not worth creating a separate repo for.
To prevent overhead, I developed a new convention. I just put them in the same repo, called [tools](https://github.com/osolmaz/tools). Every tool starts in that repo by default. If they prove themselves overly useful and I decide to publish them as a package, I move them to a separate repo.
You can keep `tools` public or private, or have both a public and private version. Mine is [public](https://github.com/osolmaz/tools), feel free to steal ones that you find useful.
==========
---
title: "@rauchg indeed"
date: 2026-01-03
canonical: https://solmaz.io/x/2007403169232629923/
x_url: https://x.com/onusoz/status/2007403169232629923
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@rauchg indeed
*Quotes a post by @onusoz (https://x.com/onusoz/status/2007395676347310173); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "75k lines of Rust later, here is what I’ve built during the first Christmas with agents, using..."
date: 2026-01-03
canonical: https://solmaz.io/x/2007395676347310173/
x_url: https://x.com/onusoz/status/2007395676347310173
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
75k lines of Rust later, here is what I’ve built during the first Christmas with agents, using OpenAI Codex 🎄🤖
- A full mobile rewrite and port of my Python Instagram video production pipeline (single video production time: 1hr -> 5min) (ig: nerdonbars)
- Bespoke animation engine using primitives (think Adobe Flash, Manim)
- Proprietary new canvas UI library in Rust, because I don’t want to lock myself into Swift
- Thanks to that, it’s cross platform, runs both on desktop and iOS. It will be a breeze porting this to Android when the time comes
- A Rust port of OpenCV CSRT algorithm, for tracking points/objects
- In-engine font rendering using rustybuzz, so fonts render the same everywhere
- Many other such things
Why would I choose to do it that way? Because I have developed it primarily on desktop where I have much faster iteration speed. Aint nobody got time for iOS compilation and simulator. Once I finished the hard part on desktop, porting to iOS was much easier, and I didn’t lock myself in to Apple
Some of these would have been unimaginable without agents, like creating a UI library from scratch in Rust. But when you have infinite workforce, you can ask for crazy things like “create a textbox component from scratch”
What I’ve built is very similar in nature to CapCut, except that I am a single person and I’ve built it over 1 week
What have you built this Christmas with agents?
cc @thsottiaux
==========
---
title: "solmaz.io/typed-language…"
date: 2026-01-03
canonical: https://solmaz.io/x/2007366662757200255/
x_url: https://x.com/onusoz/status/2007366662757200255
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
https://solmaz.io/typed-languages-are-better-suited-for-vibecoding
*Quotes a post by another author (https://x.com/i/status/2007228511363444905); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Christmas of Agents"
date: 2026-01-03
canonical: https://solmaz.io/log/2026/01/03/christmas-of-agents/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I believe a "Christmas of Agents" (+ New Year of Agents) is superior to "Advent of Code".
Reason is simple. Most of us are employed. Advent of Code coincides with work time, so you can't really immerse yourself in a side project.[^1]
However, Christmas (or any other long holiday without primary duties) is a better time to immerse yourself in a side project.
2025 was the eve of agentic coding. This was the first holiday where I had full credential to go nuts on a side project using agents. It was epic:
Tweet embed disabled to avoid requests to X.
75k lines of Rust later, here is what I’ve built during the first Christmas with agents, using OpenAI Codex
- A full mobile rewrite and port of my Python Instagram video production pipeline (single video production time: 1hr -> 5min)
- Bespoke animation engine using primitives (think Adobe Flash, Manim)
- Proprietary new canvas UI library in Rust, because I don’t want to lock myself into Swift
- Thanks to that, it’s cross platform, runs both on desktop and iOS. It will be a breeze porting this to Android when the time comes
- A Rust port of OpenCV CSRT algorithm, for tracking points/objects
- In-engine font rendering using rustybuzz, so fonts render the same everywhere
- Many other such things
Why would I choose to do it that way? Because I have developed it primarily on desktop where I have much faster iteration speed. Aint nobody got time for iOS compilation and simulator. Once I finished the hard part on desktop, porting to iOS was much easier, and I didn’t lock myself in to Apple
Some of these would have been unimaginable without agents, like creating a UI library from scratch in Rust. But when you have infinite workforce, you can ask for crazy things like “create a textbox component from scratch”
What I’ve built is very similar in nature to CapCut, except that I am a single person and I’ve built it over 1 week
What have you built this Christmas with agents?
[^1]: You could maybe work in the evening after work, but unless you are slacking at work full time, it won't be the same thing as full immersion.
==========
---
title: "SimpleDoc now has the check command for CI/CD"
date: 2026-01-02
canonical: https://solmaz.io/x/2007085964209148216/
x_url: https://x.com/onusoz/status/2007085964209148216
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
SimpleDoc now has the check command for CI/CD
Add to your PR checks to catch agent littering before merge. osolmaz/SimpleDoc on GitHub
==========
---
title: "Migrating @TextCortex to SimpleDoc. It's really easy with the CLI wizard!"
date: 2026-01-02
canonical: https://solmaz.io/x/2007082488162890138/
x_url: https://x.com/onusoz/status/2007082488162890138
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Migrating @TextCortex to SimpleDoc. It's really easy with the CLI wizard!
npx @simpledoc/simpledoc migrate
We have a LOT of docs spanning back to 2022, pre coding agent era. Now we will have CI/CD in place so that coding agents can't litter the repo with random Markdown files
==========
---
title: "Anyone created an agent skill for splitting PRs for good review culture?"
date: 2025-12-31
canonical: https://solmaz.io/x/2006404234837667919/
x_url: https://x.com/onusoz/status/2006404234837667919
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anyone created an agent skill for splitting PRs for good review culture?
==========
---
title: "GPT-5.2 xhigh feels like a careful systems debugger"
date: 2025-12-31
canonical: https://solmaz.io/x/2006384225100972220/
x_url: https://x.com/onusoz/status/2006384225100972220
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
GPT 5.2 xhigh feels like a much more careful architecter and debugger, when it comes to complex systems
But most people here think Opus 4.5 is the best model in that category
There are 2 reasons AFAIS:
- xhigh reasoning consumes significantly more tokens. You need to pay for ChatGPT Pro (200 usd) to be able to use it as a daily driver
- It takes like 5x longer to finish a task, and most people lack the patience to wait for it. (But then it's more correct/doesn't need fixing)
Opus 4.5 is good too, I think better in e.g. frontend design. But if you think it beats GPT 5.2 in every category, you are either too poor/stingy or have ADHD
*Quotes a post by another author (https://x.com/i/status/2005171110867021826); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Just 5 months ago, I was swearing at Claude 4 Sonnet like a Balkan uncle"
date: 2025-12-31
canonical: https://solmaz.io/x/2006330494791586098/
x_url: https://x.com/onusoz/status/2006330494791586098
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Just 5 months ago, I was swearing at Claude 4 Sonnet like a Balkan uncle
Models one-shotted the right thing only 20-30% of the time but did really stupid things the rest, and had to be handheld tightly
Today they are much, much better. My psychology is a lot more at ease, and instead of swearing, I want to kiss them on the forehead most of the time
Now I trust agents so much that I queue up 5-10 tasks before going to sleep. They work the whole night while I sleep and I wake up to resolved issues
GPT 5.2 xhigh and Claude 4.5 Opus are already goated (GPT more so), can't wait for them to get even faster
==========
---
title: "Codex does not have support for subagents. I tried to use Claude Code to launch 8 Codex..."
date: 2025-12-31
canonical: https://solmaz.io/x/2006303948471194039/
x_url: https://x.com/onusoz/status/2006303948471194039
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex does not have support for subagents. I tried to use Claude Code to launch 8 Codex instances in parallel on separate tasks, but Opus 4.5 had difficulty following instructions
So created a CLI tool to scan pending TODOs from a markdown file, and let me launch as many harnesses as I want (osolmaz/spawn on github)
I currently use this for relatively read-only tasks like planning and finding root causes of bugs, because it's launching all the agents on the same repo and they might conflict
Ideas:
- Use @mitsuhiko's gh-issue-sync and run parallel agents directly on github issues
- Create any new clones or worktrees for each task. I currently don't do this because I don't dare duplicate rust target dir 10x on my measly macbook air
- Support modes other than tmux, e.g. launching a terminal like Ghostty
- TUI for easy selection of issues/TODOs
Other ideas are welcome!
==========
---
title: "cc @behackl, forgot to mention you in the original post"
date: 2025-12-29
canonical: https://solmaz.io/x/2005754106854662348/
x_url: https://x.com/onusoz/status/2005754106854662348
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
cc @behackl, forgot to mention you in the original post
*Part 2/2 of a thread; root: https://solmaz.io/x/2005729271893881215/*
==========
---
title: "Friends of open source, we need your help!"
date: 2025-12-29
canonical: https://solmaz.io/x/2005729271893881215/
x_url: https://x.com/onusoz/status/2005729271893881215
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Friends of open source, we need your help!
A lot of Manim Community accounts got compromised and deleted during Christmas
Manim Community is a popular fork of @3blue1brown's original math animation engine Manim, and its accounts have over 5 YEARS of contributions, knowledge and following
Apparently GitHub support already saw the request and in progress of restoring the GitHub org. But if anyone knows how to speed this up, if would be greatly appreciated!
Unfortunately, the Discord and X accounts are deleted and less likely to return
But there might still be a way to restore them, or at least the data?
Re. Discord: Maybe @RhysSullivan's Answer Overflow has archived enough of the old server? That server contains YEARS of Q/A data and is vital for newcomers
Re. X: Maybe someone high up can do something to restore the account? cc @nikitabier
In the meanwhile, it would help a lot if you could follow the new account @manimcommunity and share this post! Thank you in advance!
*Part 1/2 of a thread; root: https://solmaz.io/x/2005729271893881215/*
*Quotes a post by another author (https://x.com/i/status/2004705897139011868); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "While a great feature, I never needed such a thing in Codex after GPT 5.2. It just one shots..."
date: 2025-12-28
canonical: https://solmaz.io/x/2005327138615120368/
x_url: https://x.com/onusoz/status/2005327138615120368
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
While a great feature, I never needed such a thing in Codex after GPT 5.2. It just one shots tasks without stopping
So we have proof by existence that this problem can be solved without any such mechanism. Wish to see the same relentlessness in Anthropic models
*Quotes a post by another author (https://x.com/i/status/2004916410687050167); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "2025 was the year of ̶a̶g̶e̶n̶t̶s̶ bugs"
date: 2025-12-27
canonical: https://solmaz.io/x/2005062253650084321/
x_url: https://x.com/onusoz/status/2005062253650084321
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
2025 was the year of ̶a̶g̶e̶n̶t̶s̶ bugs
Software felt much buggier compared to before, even from companies like Apple. Presumably because everyone started generating more code with AI
Models are improving so hopefully 2026 will be the opposite. Even less bugs than pre-AI era
==========
---
title: "Agent progress is compounding faster than teams realize"
date: 2025-12-27
canonical: https://solmaz.io/x/2004937727960125905/
x_url: https://x.com/onusoz/status/2004937727960125905
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Have a long flight, so will think about this
I have an internal 2023 TextCortex doc which models chatbots as state machines with internal and external states with immutability constraints on the external state (what is already sent to the user shall not be changed)
Motivation was that a chatbot provider will always have state that they will want to keep hidden
This was way before Responses and now deprecated Assistants API. It stood the test of time, because it was the most abstract thing I could think of
@mitsuhiko is right about the risk of rushing to lock in an abstraction and locking in their weaknesses and faults
Problem is, I could propose standards as much as I liked, but I don’t work at OpenAI or Anthropic, so nobody would care. Maybe a better place to start is open weights model libraries? To at least be able to demonstrate?
What I know: it is against OpenAI’s or Anthropic’s self interests to create an interoperability layer that will accelerate their commoditization. Maybe Google, looking at their current market positioning? Or maybe we “wrappers” have a chance after all?
There is a missing link between AI SDK, Langchain, and so on for other languages. We cannot keep duplicating same things in each ecosystem independently. We need to join forces and simplify all this!
*Quotes a post by @onusoz (https://x.com/onusoz/status/2000121028228358604); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This was simply because webapp fails to create a post and fails silently. The UX is still not..."
date: 2025-12-27
canonical: https://solmaz.io/x/2004928457156035031/
x_url: https://x.com/onusoz/status/2004928457156035031
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This was simply because webapp fails to create a post and fails silently. The UX is still not good on this app. Make sure to write your posts somewhere else to not lose them
*Quotes a post by @onusoz (https://x.com/onusoz/status/2001201245650894874); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I gave Codex a task of porting an OpenCV tracking algorithm (CSRT) from C++ to Rust, so that I..."
date: 2025-12-26
canonical: https://solmaz.io/x/2004506101362852125/
x_url: https://x.com/onusoz/status/2004506101362852125
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I gave Codex a task of porting an OpenCV tracking algorithm (CSRT) from C++ to Rust, so that I can directly use it in my project without having to cross-compile
It one-shot the task perfectly in 1hr, and even developed a GUI on top of it. All I did was to provide the original source and algo paper
I've spent years getting specialized in writing numerical code (computational mechanics, fem), and now AI can automate 95% of the low-level grunt work
Acquiring these skills involved highly difficult, excruciating intellectual labor spanning many years, very similar to ML research. Doing tensor math, writing out the solver code, wondering why your solution is not converging, finally figuring out it was a sign typo after 2 days
Kids these days both have it easy and hard. They can fast forward large chunks of the work, but then they will never understand things as deeply as someone who wrote the whole thing by hand
I guess the more valuable skill now is being able to zoom in and out of abstraction levels quickly when needed. Using AI, but recognizing fast when it fails, learning what needs to be done, fixing it, zooming back out, repeat. Adaptive learning, a sort of "depth-on-demand". The quicker you can pick up new skills and knowledge, the more successful you will be
==========
---
title: "Depth on Demand"
date: 2025-12-26
canonical: https://solmaz.io/depth-on-demand
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I gave Codex a task of porting an OpenCV tracking algorithm (CSRT) from C++ to Rust, so that I can directly use it in my project without having to cross-compile
It one-shot the task perfectly in 1hr, and even developed a GUI on top of it. All I did was to provide the original source and algo paper
I've spent years getting specialized in writing numerical code (computational mechanics, fem), and now AI can automate 95% of the low-level grunt work
Acquiring these skills involved highly difficult, excruciating intellectual labor spanning many years, very similar to ML research. Doing tensor math, writing out the solver code, wondering why your solution is not converging, finally figuring out it was a sign typo after 2 days
Kids these days both have it easy and hard. They can fast forward large chunks of the work, but then they will never understand things as deeply as someone who wrote the whole thing by hand
I guess the more valuable skill now is being able to zoom in and out of abstraction levels quickly when needed. Using AI, but recognizing fast when it fails, learning what needs to be done, fixing it, zooming back out, repeat. Adaptive learning, a sort of "depth-on-demand". The quicker you can pick up new skills and knowledge, the more successful you will be
==========
---
title: "See the repo for the latest changes: github.com/osolmaz/Simple…"
date: 2025-12-25
canonical: https://solmaz.io/x/2004334016170971511/
x_url: https://x.com/onusoz/status/2004334016170971511
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
See the repo for the latest changes: https://github.com/osolmaz/SimpleDoc
*Part 3/3 of a thread; root: https://solmaz.io/x/2004330867053707733/*
==========
---
title: "If you have a bunch of docs in your repo, give it a try. It will use the timestamps of the..."
date: 2025-12-25
canonical: https://solmaz.io/x/2004332979993358516/
x_url: https://x.com/onusoz/status/2004332979993358516
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you have a bunch of docs in your repo, give it a try. It will use the timestamps of the commit that created the files while renaming. You can also run with --dry-run to see changes without applying them
*Part 2/3 of a thread; root: https://solmaz.io/x/2004330867053707733/*
==========
---
title: "Now you can migrate your repo to SimpleDoc with a single command:"
date: 2025-12-25
canonical: https://solmaz.io/x/2004330867053707733/
x_url: https://x.com/onusoz/status/2004330867053707733
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Now you can migrate your repo to SimpleDoc with a single command:
npx -y @simpledoc/simpledoc migrate
Step by step wizard will add timestamps to your files based on your git history, add missing YAML frontmatter, update your AGENTS md file
https://x.com/onusoz/status/2003262090132488209
*Part 1/3 of a thread; root: https://solmaz.io/x/2004330867053707733/*
*Quotes a post by @onusoz (https://x.com/onusoz/status/2003262090132488209); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@bcherny Would be great if I could queue messages like in Codex"
date: 2025-12-25
canonical: https://solmaz.io/x/2004274503141269938/
x_url: https://x.com/onusoz/status/2004274503141269938
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@bcherny Would be great if I could queue messages like in Codex
https://x.com/onusoz/status/1999577947066323141
*Quotes a post by @onusoz (https://x.com/onusoz/status/1999577947066323141); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "It seems it's impossible to post something on Reddit these days, even when it is a pure text..."
date: 2025-12-24
canonical: https://solmaz.io/x/2003838921428578750/
x_url: https://x.com/onusoz/status/2003838921428578750
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It seems it's impossible to post something on Reddit these days, even when it is a pure text post without links in the body
==========
---
title: "X post"
date: 2025-12-23
canonical: https://solmaz.io/x/2003585112257024190/
x_url: https://x.com/onusoz/status/2003585112257024190
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
*Quotes a post by @onusoz (https://x.com/onusoz/status/2003262090132488209); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Curious to hear what other hardcore agent users @simonw @mitsuhiko @steipete @badlogicgames..."
date: 2025-12-23
canonical: https://solmaz.io/x/2003262105697583414/
x_url: https://x.com/onusoz/status/2003262105697583414
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Curious to hear what other hardcore agent users @simonw @mitsuhiko @steipete @badlogicgames think. I can't be the only one who does this.
I feel like everybody ended up with the same workflow independent of each other, but somehow did not write about it (or I missed it)
==========
---
title: "How to stop AI agents from littering your codebase with Markdown files?"
date: 2025-12-23
canonical: https://solmaz.io/x/2003262090132488209/
x_url: https://x.com/onusoz/status/2003262090132488209
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
How to stop AI agents from littering your codebase with Markdown files?
I wrote a new post on how to create documentations with AI agents, without having it add markdown files in your repo root, and have chronological order to the files it creates
==========
---
title: "How to stop AI agents from littering your codebase with Markdown files"
date: 2025-12-22
canonical: https://solmaz.io/agent-doc-workflow
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> A simple documentation workflow for AI agents.
>
> For setup instructions, skip to the [How to setup SimpleDoc in your repo](#how-to-setup-simpledoc-in-your-repo) section.
If you have used AI agents such as Anthropic's Claude Code, OpenAI's Codex, etc., you might have noticed their tendency to create markdown files at the repository root:
```markdown
...
├── API_SPEC.md
├── ARCHITECTURE.md
├── BACKLOG.md
├── CLAUDE.md
├── CODE_REVIEW.md
├── DECISIONS.md
├── ENDPOINTS.md
├── IMPLEMENTATION_PLAN.md
├── NOTES.md
├── QA_CHECKLIST.md
├── SECURITY_PLAN.md
└── src/
└── ...
├── TEST_COVERAGE.md
├── TEST_REPORTS.md
├── TEST_RESULTS.md
...
```
The default behavior for models as of writing this in December 2025 is to create capitalized Markdown files at the repository root. This is of course very annoying, when you accidentally commit them and they accumulate over time.
The good news is, this problem is 100% solvable, by using a simple instruction in your AGENTS.md file:
```markdown
**Attention agent!** Before creating ANY documentation, read the docs/HOW_TO_DOC.md file first. It contains guidelines on how to create documentation in this repository.
```
But what should be in `docs/HOW_TO_DOC.md` file and why is it a separate file? In my opinion, the instructions for solving this problem are too specific to be included in the AGENTS.md file. It's generally a good idea to not inject them into every context.
To solve this problem, I developed a lightweight standard over time, for organizing documentation in a codebase. It is framework-agnostic, unopinionated and designed to be human-readable/writable (as well as agents). I was surprised to be not able to find something similar enough online, crystallized the way I wanted it to be. So I created a specification myself, called [SimpleDoc](https://github.com/osolmaz/SimpleDoc).
Basically, it tells the agent to
1. Create documentation files in the `docs/` folder, with `YYYY-MM-DD` prefixes and lowercase filenames, like `2025-12-22-an-awesome-doc.md`, so that they will by default be chronologically sorted.
2. Always include YAML frontmatter with author, so that you can identify who created it without checking git history, if you are working in a team.
3. The exception here are timeless and general files like README.md, INSTALL.md, AGENTS.md, etc. which can be capitalized. But these are much rarer, so we can just follow the previous rules most of the time.
Here is your call to action to check the spec itself: [SimpleDoc](https://github.com/osolmaz/SimpleDoc).
## How to setup SimpleDoc in your repo
Run the following command from your repo root:
```bash
npx -y @simpledoc/simpledoc migrate
```
This starts an interactive wizard that will:
1. Migrate existing Markdown docs to SimpleDoc conventions (move root docs into `docs/`, rename to `YYYY-MM-DD-…` using git history, and optionally insert missing YAML frontmatter with per-file authors).
2. Ensure `AGENTS.md` contains the reminder line and that `docs/HOW_TO_DOC.md` exists (created from the bundled SimpleDoc template).
If you just want to preview what it would change:
```bash
npx -y @simpledoc/simpledoc migrate --dry-run
```
If you run into issues with the workflow or have suggestions for improvement, you can email me at [onur@solmaz.io](mailto:onur@solmaz.io).
Happy documenting!
==========
---
title: "OpenAI won’t be able to monopolize this, the same reason Microsoft couldn’t monopolize the..."
date: 2025-12-21
canonical: https://solmaz.io/x/2002719070031147135/
x_url: https://x.com/onusoz/status/2002719070031147135
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenAI won’t be able to monopolize this, the same reason Microsoft couldn’t monopolize the internet. The internet (of agents) is bigger than any one company
*Quotes a post by another author (https://x.com/i/status/2002217315627381178); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "One tap @Revolut bank account at Berlin airport. Literally."
date: 2025-12-21
canonical: https://solmaz.io/x/2002694629926351315/
x_url: https://x.com/onusoz/status/2002694629926351315
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
One tap @Revolut bank account at Berlin airport. Literally.
Dispenses free card with instructions to login. One of the the most insane onboarding experiences I have ever seen
==========
---
title: "Slop bombing"
date: 2025-12-20
canonical: https://solmaz.io/x/2002302622640845062/
x_url: https://x.com/onusoz/status/2002302622640845062
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Slop bombing
*Quotes a post by another author (https://x.com/i/status/2002020773217624536); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Codex feature request: Let me queue up /model changes"
date: 2025-12-18
canonical: https://solmaz.io/x/2001704563984744489/
x_url: https://x.com/onusoz/status/2001704563984744489
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex feature request: Let me queue up /model changes
Currently, if I try to run /model while responding, it tells me that I can't do that while the model is responding
But I often want to gauge thinking budget in advance, like run a straightforward task with low reasoning and then start another one with high reasoning
cc @thsottiaux
*Quotes a post by @onusoz (https://x.com/onusoz/status/1999577947066323141); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Literally the exact same thing happened to me back in 2018. Everybody learns not to use..."
date: 2025-12-18
canonical: https://solmaz.io/x/2001690553251967258/
x_url: https://x.com/onusoz/status/2001690553251967258
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Literally the exact same thing happened to me back in 2018. Everybody learns not to use password auth with SSH the hard way
https://blog.jakesaunders.dev/my-server-started-mining-monero-this-morning/
==========
---
title: "AI agents make any transductional task (like translation from language A to language B)..."
date: 2025-12-17
canonical: https://solmaz.io/x/2001398671091327073/
x_url: https://x.com/onusoz/status/2001398671091327073
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI agents make any transductional task (like translation from language A to language B) trivial, especially when you can verify the output with compilers and tests
The bottleneck is now curating the tests
*Quotes a post by another author (https://x.com/i/status/2001318416448188479); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I think X removed one of my posts yesterday about the new encrypted \"Chat\" rolling out to all..."
date: 2025-12-17
canonical: https://solmaz.io/x/2001201245650894874/
x_url: https://x.com/onusoz/status/2001201245650894874
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I think X removed one of my posts yesterday about the new encrypted "Chat" rolling out to all users, and how you might lose all your past messages if you forget your passcode and do not have the app installed
I can swear I clicked Post. Do they classify posts based on their topic and delete the ones they don't like?
Anyway, we shall see, I am taking a screenshot and saving the URL.
==========
---
title: "very optimistic!"
date: 2025-12-14
canonical: https://solmaz.io/x/2000144553269965055/
x_url: https://x.com/onusoz/status/2000144553269965055
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
very optimistic!
*Quotes a post by another author (https://x.com/i/status/1999294486242034117); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Crazy that @cursor_ai disabled Gemini 3 Pro on my installation, toggled it right back on. I..."
date: 2025-12-14
canonical: https://solmaz.io/x/2000132431739801615/
x_url: https://x.com/onusoz/status/2000132431739801615
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Crazy that @cursor_ai disabled Gemini 3 Pro on my installation, toggled it right back on. I wonder why, too many complaints maybe? That it’s hard to control?
On another note, disabling models without notification is dishonest product behavior. I would at least appreciate getting a notification, even when it might be against a company’s interests @sualehasif996
==========
---
title: "Language-agnostic interoperability layer for LLM APIs"
date: 2025-12-14
canonical: https://solmaz.io/x/2000121028228358604/
x_url: https://x.com/onusoz/status/2000121028228358604
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
So is somebody already building “LLVM but for LLM APIs” in stealth or not?
We have numerous libraries @langchain, Vercel AI SDK, LiteLLM, OpenRouter, the one we have built at @TextCortex, etc.
But to my knowledge, none of these try to build a language agnostic IR for interoperability between providers (or at least market themselves as such)
Like some standard and set of tools that will not lock you in langchain, ai sdk or anything like that, something lower level and less opinionated
I feel like this is a job for the new Agentic AI Foundation cc @linuxfoundation, so maybe they are already working on it? I desperately want to start on such a project, but feel like I might get sniped 2 months after
Anybody has any information on all this?
cc @mitsuhiko @badlogicgames @steipete
*Quotes a post by another author (https://x.com/i/status/1992205280302465114); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "For those wondering what project this is: horse.fit"
date: 2025-12-13
canonical: https://solmaz.io/x/1999883882989244900/
x_url: https://x.com/onusoz/status/1999883882989244900
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
For those wondering what project this is: https://horse.fit
*Part 2/2 of a thread; root: https://solmaz.io/x/1999883880493441168/*
==========
---
title: "This is how an agentic monorepo looks like. What was now a hurdle before is now a child's toy"
date: 2025-12-13
canonical: https://solmaz.io/x/1999883880493441168/
x_url: https://x.com/onusoz/status/1999883880493441168
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is how an agentic monorepo looks like. What was now a hurdle before is now a child's toy
This side project started as a Python project earlier in 2025
Then I added an iOS app on top of it
I rewrote the most important algorithms in Rust
I rewrote the entire backend in Go and retired Python to be used purely for prototypes
I wrote a webapp with Next.js
With unit and integration tests for each component
Lately written 99% by instructing agents
Crazy mixed language programming going on in the background. Rust component used both by iOS app for offline and by go backend for online use case, FFI and all
Number of lines in the repo: a couple 100k
If you had told me I would be able do to all of this by myself 1 year ago, I would not have believed it
*Part 1/2 of a thread; root: https://solmaz.io/x/1999883880493441168/*
==========
---
title: "This is huge. Natively supported stacked PRs on GitHub would make life much easier, especially..."
date: 2025-12-13
canonical: https://solmaz.io/x/1999786569553596492/
x_url: https://x.com/onusoz/status/1999786569553596492
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is huge. Natively supported stacked PRs on GitHub would make life much easier, especially with human AND AI reviews
AI reviews with Codex/Claude/Gemini/Cursor Bugbot integrations are becoming especially important in small teams who are generating huge amounts of code
AI reviews don't work well if you don't split your work to diffs smaller than a few hundred lines of code, so stacked PRs are already an integral part of developer experience in agentic workflows
*Quotes a post by another author (https://x.com/i/status/1980619222918262842); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Read more on my blog post solmaz.io/agentic-coding…"
date: 2025-12-12
canonical: https://solmaz.io/x/1999577957363241363/
x_url: https://x.com/onusoz/status/1999577957363241363
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Read more on my blog post https://solmaz.io/agentic-coding-tools-message-queueing
==========
---
title: "CLI coding tools should give more control over message queueing"
date: 2025-12-12
canonical: https://solmaz.io/x/1999577947066323141/
x_url: https://x.com/onusoz/status/1999577947066323141
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
CLI coding tools should give more control over message queueing
Codex waits until end of turn to handle user message, Claude Code injects as soon as possible after tool response/assistant reply
There is no reason why we cannot have both!
New post (link below):
==========
---
title: "Codex v0.71 finally implements a more detailed way of storing permissions"
date: 2025-12-12
canonical: https://solmaz.io/x/1999444307431030935/
x_url: https://x.com/onusoz/status/1999444307431030935
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Codex v0.71 finally implements a more detailed way of storing permissions
But they are still at user home folder level. Saving rules in a repo still seems TBD
"execpolicy commands are still in preview. The API may have breaking changes in the future."
==========
---
title: "this is outrageous"
date: 2025-12-11
canonical: https://solmaz.io/x/1999058628637008227/
x_url: https://x.com/onusoz/status/1999058628637008227
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
this is outrageous
*Quotes a post by another author (https://x.com/i/status/1998679343875371221); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Agentic coding tools should give more control over message queueing"
date: 2025-12-06
canonical: https://solmaz.io/agentic-coding-tools-message-queueing
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Below: Why agentic coding tools like Cursor, Claude Code, OpenAI Codex, etc. should implement more ways of letting users queue messages.
See Peter Steinberger's tweet where he queues `continue` 100 times to nudge the GPT-5-Codex model to not stop while working on a predictable, boring and long-running refactor task:
Tweet embed disabled to avoid requests to X.
This is necessary while working with a model like GPT-5-Codex. The reason is that the model has a tendency to stop generating at certain checkpoints, due to the way it has been trained, even when you instruct it to `FINISH IT UNTIL COMPLETION!!1!`. So the only way to get it to finish something is to use the message queue.[^1]
But this isn't the only use case for queued messages. For example, you can use the model to retrieve files into its context, before starting off a related task. Say you want to find the root cause of a ``. Then you can queue
> 1. `Explain how works in plain language. Do not omit any details.`
> 2. `Find the root cause of in .`
This will generally help the model to find the root cause easier, or make more accurate predictions about the root cause, by having the context about the component.
Another example: After exploring a design in a dialogue, you can queue the next steps to implement it.
> ``
> 1. `Create an implementation plan for that in the docs/ folder. Include all the details we discussed`
> 2. `Commit and push the doc`
> 3. `Implement the feature according to the plan.`
> 4. `Continue implementing the feature until it is done. Ignore this if the task is already completed.`
> 5. `Continue implementing the feature until it is done. Ignore this if the task is already completed.`
>
> ... you get the idea.
I generally queue like this when the feature is specified enough in the conversation already. If it's underspecified, then the model will make up stuff.
When I first moved from Claude Code to Codex, the way it implemented queued messages was annoying (more on the difference below). But as I grew accustomed to it, it started to feel a lot like something I saw elsewhere before: chess premoves.
## Chess???
A premove is a relatively recent invention in chess which is made possible by digital chess engines. When the feature is turned on, you don't need to wait for your opponent to finish their move, and instead can queue your next move. It then gets executed automatically if the queued move is valid after your opponent's move:
If you are fast enough, this let's you move without using up your time in bullet chess, and even lets you queue up entire mate-in-N sequences, resulting in highly entertaining cases like the video above.
I tend to think of message queueing as the same thing: when applied effectively, it saves you a lot of time, when you can already predict the next move.
In other words, **you should queue (or premove) when your next choice is *decision-insensitive* to the information you will receive in the next turn—so waiting wouldn't change what you do, it would only delay doing it.**
With this perspective, some obvious candidates for queuing in agentic codeing are rote tasks that come before and after "serious work", e.g:
- making the agent explain the codebase,
- creating implementation plans,
- fixing linting errors,
- updating documentation during work before starting off a subsequent step,
- committing and pushing,
- and so on.
## Different ways CLI agents implement queued messages
As I have mentioned above, Claude Code implements queued messages differently from OpenAI Codex. In fact, there are three main approaches that I can think of in this design space, which is based on when a user's new input takes effect:
1. **Post-turn queuing (FIFO[^2]):** User messages wait until the current action finishes completely before they're handled. Example: OpenAI Codex CLI.
2. **Boundary-aware queuing (Soft Interrupt):** New messages are inserted at natural breakpoints, like after finishing a tool call, assistant reply or a task in the TODO list. This changes the model's course of action smoothly, without stopping ongoing generation. Example: Claude Code, Cursor.
3. **Immediate queuing (Hard Interrupt):** New user messages immediately stop the current action/generation, discarding ongoing work and restarting the assistant's generation from scratch. I have not seen any tool that implements this yet, but it could be an option for the impatient.
## Why not implement all of them?
And here is my title-sake argument: When I move away from Claude Code, I miss boundary-aware queuing. When I move away from OpenAI Codex, I miss FIFO queueing.
I don't see a reason why we could not implement all of them in all agentic tools. It could be controlled by a key combo like `Ctrl+Enter`, a submenu, or a button, depending on whether you are in the terminal or not.
Having the option would definitely make a difference in agentic workflows where you are running 3-4 agents in parallel.
So if you are reading this and are implementing an agentic coding tool, I would be happy if you took all this into consideration!
[^1]: Pro tip: Don't just queue `continue` by itself, because the model might get loose from its leash and start to make up and execute random tasks, especially after context compaction. Always specify what you want it to continue on, e.g. `Continue handling the linting errors until none remain. Ignore this if the task is already completed.`
[^2]: First-in, first-out.
==========
---
title: "At least some people at OpenAI must be thinking about buying @astral_sh"
date: 2025-12-03
canonical: https://solmaz.io/x/1996076438848680202/
x_url: https://x.com/onusoz/status/1996076438848680202
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
At least some people at OpenAI must be thinking about buying @astral_sh
*Quotes a post by another author (https://x.com/i/status/1995946419816202366); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "who remembers search engine aggregators from early 2000s?"
date: 2025-11-29
canonical: https://solmaz.io/x/1994811178833551867/
x_url: https://x.com/onusoz/status/1994811178833551867
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
who remembers search engine aggregators from early 2000s?
*Quotes a post by another author (https://x.com/i/status/1994489739064570017); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "My initial experience with Claude Opus 4.5 is that it’s much better than previous Anthropic..."
date: 2025-11-26
canonical: https://solmaz.io/x/1993481331821711554/
x_url: https://x.com/onusoz/status/1993481331821711554
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My initial experience with Claude Opus 4.5 is that it’s much better than previous Anthropic models, but it’s still relatively unreliable and hallucinates. It feels lagging in reasoning compared to highest OpenAI and Google lineup of models
==========
---
title: "wow twitter/x just doxxed the countries of all the anons on this platform"
date: 2025-11-24
canonical: https://solmaz.io/x/1992807182237348012/
x_url: https://x.com/onusoz/status/1992807182237348012
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
wow twitter/x just doxxed the countries of all the anons on this platform
==========
---
title: "the real advantage of Gemini 3 Pro is speed. it delivers accuracy higher than GPT 5 and..."
date: 2025-11-23
canonical: https://solmaz.io/x/1992412959063323066/
x_url: https://x.com/onusoz/status/1992412959063323066
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
the real advantage of Gemini 3 Pro is speed. it delivers accuracy higher than GPT 5 and sometimes GPT 5 Pro at a much higher speed. the long tail of developers value speed over accuracy, so it looks like it will take over as the main coding model for most ppl
==========
---
title: "There already is one: google-github-actions/run-gemini-cli"
date: 2025-11-19
canonical: https://solmaz.io/x/1991090631012471132/
x_url: https://x.com/onusoz/status/1991090631012471132
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
There already is one: google-github-actions/run-gemini-cli
but updated last week, not sure if this supports gemini 3 pro
*Part 2/2 of a thread; root: https://solmaz.io/x/1991066906187403641/*
==========
---
title: "Gemini seems to be very good at debugging/reviewing/finding root causes. A GitHub..."
date: 2025-11-19
canonical: https://solmaz.io/x/1991066906187403641/
x_url: https://x.com/onusoz/status/1991066906187403641
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gemini seems to be very good at debugging/reviewing/finding root causes. A GitHub action/integration in PRs would be very useful!
*Part 1/2 of a thread; root: https://solmaz.io/x/1991066906187403641/*
==========
---
title: "(This is sarcasm for those who can’t tell)"
date: 2025-11-19
canonical: https://solmaz.io/x/1991045121014706604/
x_url: https://x.com/onusoz/status/1991045121014706604
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
(This is sarcasm for those who can’t tell)
*Part 2/2 of a thread; root: https://solmaz.io/x/1991045118607155286/*
==========
---
title: "Google is making progress… I did not have to request access on Vertex AI for Gemini 3 Pro this..."
date: 2025-11-19
canonical: https://solmaz.io/x/1991045118607155286/
x_url: https://x.com/onusoz/status/1991045118607155286
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Google is making progress… I did not have to request access on Vertex AI for Gemini 3 Pro this time to deploy it to @TextCortex
*Part 1/2 of a thread; root: https://solmaz.io/x/1991045118607155286/*
==========
---
title: "tip for testing new model releases: “they say you are sota. prove it”"
date: 2025-11-19
canonical: https://solmaz.io/x/1990939304206671945/
x_url: https://x.com/onusoz/status/1990939304206671945
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
tip for testing new model releases: “they say you are sota. prove it”
==========
---
title: "\"The more a task/job is verifiable, the more amenable it is to automation in the new..."
date: 2025-11-17
canonical: https://solmaz.io/x/1990302419276931479/
x_url: https://x.com/onusoz/status/1990302419276931479
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
"The more a task/job is verifiable, the more amenable it is to automation in the new programming paradigm. If it is not verifiable, it has to fall out from neural net magic of generalization fingers crossed, or via weaker means like imitation."
*Quotes a post by another author (https://x.com/i/status/1990116666194456651); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Most important note of the new @OpenAI gpt 5.1 update"
date: 2025-11-14
canonical: https://solmaz.io/x/1989182407929745545/
x_url: https://x.com/onusoz/status/1989182407929745545
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Most important note of the new @OpenAI gpt 5.1 update
big improvement on unit economics
==========
---
title: "This post makes no sense"
date: 2025-11-08
canonical: https://solmaz.io/x/1987148854534262907/
x_url: https://x.com/onusoz/status/1987148854534262907
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This post makes no sense
Please consider again and look at @cloudfleet_k8s. You might regret your decision
*Quotes a post by another author (https://x.com/i/status/1986276714364731478); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Working on observability is underrated"
date: 2025-11-02
canonical: https://solmaz.io/x/1985025400461029585/
x_url: https://x.com/onusoz/status/1985025400461029585
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Working on observability is underrated
*Quotes a post by another author (https://x.com/i/status/1984811534519058743); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@rakyll @GergelyOrosz Should scrape some austrian websites :)"
date: 2025-11-01
canonical: https://solmaz.io/x/1984595653956096321/
x_url: https://x.com/onusoz/status/1984595653956096321
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@rakyll @GergelyOrosz Should scrape some austrian websites :)
*Quotes a post by another author (https://x.com/i/status/1984057646299906435); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I was schooled by AI today... tbh I deserved it"
date: 2025-10-27
canonical: https://solmaz.io/x/1982916994690363616/
x_url: https://x.com/onusoz/status/1982916994690363616
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I was schooled by AI today... tbh I deserved it
==========
---
title: "Vibecoding this blog"
date: 2025-10-13
canonical: https://solmaz.io/log/2025/10/13/vibecoding-this-blog/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I finally brought myself to develop certain features for this blog which I wanted to do for some time, having a button to toggle light/dark mode, being able to permalink page sections, having a button to copy page content, etc.
I always have a tendency to procrastinate with cosmetics, so I developed a habit to mentally force myself not to care about looks and instead focus on the actual content. Doing the changes I have pulled off in the last 2 hours would have been impossible in pre-LLM era. So I kept the awful default Jekyll Minima theme, and did not spend more thought on it. I had actually went through many different themes in this blog before, and I had switched to Minima precisely because of that: I was spending too much time.
I really like designing things visually. I had interest in typography while studying, and I even went as far to design a font, write all my notes in LaTeX, etc. Then I found out that such skills are not valued in the world, and had no luxury to dwell on such things anymore once I started working.
But now it's different. When I can do what I want 10 times faster with 10 times less attention, I can just do the design I want. Before I thought it was a flex to use default themes, because it showed a) that the person does not care and b) that they had more important things to do.
Well, now my opinion has changed. In the era where making something look good takes a few hours, using a default theme means something else to me: lack of taste.
For this blog, I just [vendored](https://htmx.org/essays/vendoring/) [Minima](https://github.com/jekyll/minima) and let gpt-5-codex rip on it. Vendoring pattern is getting more popular with libraries like shadcn, and I expect it to be ever more popular with open source libraries, with AI tools becoming more prevalent.
I don't expect simple frontend development to be in a good place ever again. I don't expect anyone to outsource simple static site development to humans anymore, when you can get the exact thing you want at virtually no cost.
==========
---
title: "@thsottiaux Let me use my Pro/Plus plans in Codex GH Action"
date: 2025-10-11
canonical: https://solmaz.io/x/1976983794147295250/
x_url: https://x.com/onusoz/status/1976983794147295250
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@thsottiaux Let me use my Pro/Plus plans in Codex GH Action
https://x.com/onusoz/status/1976983381289451883
*Quotes a post by @onusoz (https://x.com/onusoz/status/1976983381289451883); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "TIL @OpenAI now has a GitHub action for Codex, similar to Claude Code"
date: 2025-10-11
canonical: https://solmaz.io/x/1976983381289451883/
x_url: https://x.com/onusoz/status/1976983381289451883
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
TIL @OpenAI now has a GitHub action for Codex, similar to Claude Code
This lets you invoke Codex in a more controlled way in your repos
You must still pay API prices though. Let's see if OpenAI will introduce a way to connect your Pro plan, like in @AnthropicAI paid plans
==========
---
title: "Google's Code Review Guidelines (GitHub Adaptation)"
date: 2025-09-29
canonical: https://solmaz.io/google-eng-practices-github
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> This is an adaptation of the original [Google's Code Review Guidelines](https://google.github.io/eng-practices/review/), to use GitHub specific terminology. Google has their own internal tools for version control ([Piper](https://en.wikipedia.org/wiki/Piper_(source_control_system))) and code review ([Critique](https://abseil.io/resources/swe-book/html/ch19.html)). They have their own terminology, like "Change List" (CL) instead of "Pull Request" (PR) which most developers are more familiar with. The changes are minimal and the content is kept as close to the original as possible. The hope is to make this gem accessible to a wider audience.
>
> I also combined the whole set of documents into a single file, to make it easier to consume. You can find my fork [here](https://github.com/osolmaz/eng-practices/). If you notice any mistakes, please feel free to submit a PR to the fork.
## Introduction {#intro}
A code review is a process where someone other than the author(s) of a piece of
code examines that code.
At Google, we use code review to maintain the quality of our code and products.
This documentation is the canonical description of Google's code review
processes and policies.
This page is an overview of our code review process. There are two other large
documents that are a part of this guide:
- **[How To Do A Code Review](#reviewer-index)**: A detailed guide for code
reviewers.
- **[The PR Author's Guide](#pr-author-index)**: A detailed guide for
developers whose PRs are going through review.
## What Do Code Reviewers Look For? {#look_for}
Code reviews should look at:
- **Design**: Is the code well-designed and appropriate for your system?
- **Functionality**: Does the code behave as the author likely intended? Is
the way the code behaves good for its users?
- **Complexity**: Could the code be made simpler? Would another developer be
able to easily understand and use this code when they come across it in the
future?
- **Tests**: Does the code have correct and well-designed automated tests?
- **Naming**: Did the developer choose clear names for variables, classes,
methods, etc.?
- **Comments**: Are the comments clear and useful?
- **Style**: Does the code follow our
[style guides](http://google.github.io/styleguide/)?
- **Documentation**: Did the developer also update relevant documentation?
See **[How To Do A Code Review](#reviewer-index)** for more information.
### Picking the Best Reviewers {#best_reviewers}
In general, you want to find the *best* reviewers you can who are capable of
responding to your review within a reasonable period of time.
The best reviewer is the person who will be able to give you the most thorough
and correct review for the piece of code you are writing. This usually means the
owner(s) of the code, who may or may not be the people in the CODEOWNERS file.
Sometimes this means asking different people to review different parts of the
PR.
If you find an ideal reviewer but they are not available, you should at least CC
them on your change.
### In-Person Reviews (and Pair Programming) {#in_person}
If you pair-programmed a piece of code with somebody who was qualified to do a
good code review on it, then that code is considered reviewed.
You can also do in-person code reviews where the reviewer asks questions and the
developer of the change speaks only when spoken to.
## See Also {#seealso}
- [How To Do A Code Review](#reviewer-index): A detailed guide for code
reviewers.
- [The PR Author's Guide](#pr-author-index): A detailed guide for developers
whose PRs are going through review.
---
# How to do a code review {#reviewer-index}
The pages in this section contain recommendations on the best way to do code
reviews, based on long experience. All together they represent one complete
document, broken up into many separate sections. You don't have to read them
all, but many people have found it very helpful to themselves and their team to
read the entire set.
- [The Standard of Code Review](#standard-of-code-review)
- [What to Look For In a Code Review](#what-to-look-for)
- [Navigating a PR in Review](#navigating-a-pr)
- [Speed of Code Reviews](#speed-of-reviews)
- [How to Write Code Review Comments](#writing-review-comments)
- [Handling Pushback in Code Reviews](#handling-pushback)
See also the [PR Author's Guide](#pr-author-index), which gives detailed
guidance to developers whose PRs are undergoing review.
---
## The Standard of Code Review {#standard-of-code-review}
The primary purpose of code review is to make sure that the overall
code health of Google's code
base is improving over time. All of the tools and processes of code review are
designed to this end.
In order to accomplish this, a series of trade-offs have to be balanced.
First, developers must be able to _make progress_ on their tasks. If you never
merge an improvement into the codebase, then the codebase never improves. Also,
if a reviewer makes it very difficult for _any_ change to go in, then developers
are disincentivized to make improvements in the future.
On the other hand, it is the duty of the reviewer to make sure that each PR is
of such a quality that the overall code health of their codebase is not
decreasing as time goes on. This can be tricky, because often, codebases degrade
through small decreases in code health over time, especially when a team is
under significant time constraints and they feel that they have to take
shortcuts in order to accomplish their goals.
Also, a reviewer has ownership and responsibility over the code they are
reviewing. They want to ensure that the codebase stays consistent, maintainable,
and all of the other things mentioned in
["What to look for in a code review."](#what-to-look-for)
Thus, we get the following rule as the standard we expect in code reviews:
**In general, reviewers should favor approving a PR once it is in a state where
it definitely improves the overall
code health of the system
being worked on, even if the PR isn't perfect.**
That is _the_ senior principle among all of the code review guidelines.
There are limitations to this, of course. For example, if a PR adds a feature
that the reviewer doesn't want in their system, then the reviewer can certainly
deny approval even if the code is well-designed.
A key point here is that there is no such thing as "perfect" code—there is
only _better_ code. Reviewers should not require the author to polish every tiny
piece of a PR before granting approval. Rather, the reviewer should balance out
the need to make forward progress compared to the importance of the changes they
are suggesting. Instead of seeking perfection, what a reviewer should seek is
_continuous improvement_. A PR that, as a whole, improves the maintainability,
readability, and understandability of the system shouldn't be delayed for days
or weeks because it isn't "perfect."
Reviewers should _always_ feel free to leave comments expressing that something
could be better, but if it's not very important, prefix it with something like
"Nit: " to let the author know that it's just a point of polish that they could
choose to ignore.
Note: Nothing in this document justifies merging PRs that definitely
_worsen_ the overall code health of the system. The only time you would do that
would be in an [emergency](#emergencies).
### Mentoring
Code review can have an important function of teaching developers something new
about a language, a framework, or general software design principles. It's
always fine to leave comments that help a developer learn something new. Sharing
knowledge is part of improving the code health of a system over time. Just keep
in mind that if your comment is purely educational, but not critical to meeting
the standards described in this document, prefix it with "Nit: " or otherwise
indicate that it's not mandatory for the author to resolve it in this PR.
### Principles {#principles}
* Technical facts and data overrule opinions and personal preferences.
* On matters of style, the [style guide](http://google.github.io/styleguide/)
is the absolute authority. Any purely style point (whitespace, etc.) that is
not in the style guide is a matter of personal preference. The style should
be consistent with what is there. If there is no previous style, accept the
author's.
* **Aspects of software design are almost never a pure style issue or just a
personal preference.** They are based on underlying principles and should be
weighed on those principles, not simply by personal opinion. Sometimes there
are a few valid options. If the author can demonstrate (either through data
or based on solid engineering principles) that several approaches are
equally valid, then the reviewer should accept the preference of the author.
Otherwise the choice is dictated by standard principles of software design.
* If no other rule applies, then the reviewer may ask the author to be
consistent with what is in the current codebase, as long as that doesn't
worsen the overall code health of the system.
### Resolving Conflicts {#conflicts}
In any conflict on a code review, the first step should always be for the
developer and reviewer to try to come to consensus, based on the contents of
this document and the other documents in
[The PR Author's Guide](#pr-author-index) and this
[Reviewer Guide](#reviewer-index).
When coming to consensus becomes especially difficult, it can help to have a
face-to-face meeting or a video conference between the reviewer and the author, instead of
just trying to resolve the conflict through code review comments. (If you do
this, though, make sure to record the results of the discussion as a comment on
the PR, for future readers.)
If that doesn't resolve the situation, the most common way to resolve it would
be to escalate. Often the
escalation path is to a broader team discussion, having a Technical Lead weigh in, asking
for a decision from a maintainer of the code, or asking an Eng Manager to help
out. **Don't let a PR sit around because the author and the reviewer can't come
to an agreement.**
Next: [What to look for in a code review](#what-to-look-for)
---
## What to look for in a code review {#what-to-look-for}
Note: Always make sure to take into account
[The Standard of Code Review](#standard-of-code-review) when considering each of these
points.
### Design
The most important thing to cover in a review is the overall design of the PR.
Do the interactions of various pieces of code in the PR make sense? Does this
change belong in your codebase, or in a library? Does it integrate well with the
rest of your system? Is now a good time to add this functionality?
### Functionality
Does this PR do what the developer intended? Is what the developer intended good
for the users of this code? The "users" are usually both end-users (when they
are affected by the change) and developers (who will have to "use" this code in
the future).
Mostly, we expect developers to test PRs well-enough that they work correctly by
the time they get to code review. However, as the reviewer you should still be
thinking about edge cases, looking for concurrency problems, trying to think
like a user, and making sure that there are no bugs that you see just by reading
the code.
You *can* validate the PR if you want—the time when it's most important for a
reviewer to check a PR's behavior is when it has a user-facing impact, such as a
**UI change**. It's hard to understand how some changes will impact a user when
you're just reading the code. For changes like that, you can have the developer
give you a demo of the functionality if it's too inconvenient to patch in the PR
and try it yourself.
Another time when it's particularly important to think about functionality
during a code review is if there is some sort of **parallel programming** going
on in the PR that could theoretically cause deadlocks or race conditions. These
sorts of issues are very hard to detect by just running the code and usually
need somebody (both the developer and the reviewer) to think through them
carefully to be sure that problems aren't being introduced. (Note that this is
also a good reason not to use concurrency models where race conditions or
deadlocks are possible—it can make it very complex to do code reviews or
understand the code.)
### Complexity
Is the PR more complex than it should be? Check this at every level of the
PR—are individual lines too complex? Are functions too complex? Are classes too
complex? "Too complex" usually means **"can't be understood quickly by code
readers."** It can also mean **"developers are likely to introduce bugs when
they try to call or modify this code."**
A particular type of complexity is **over-engineering**, where developers have
made the code more generic than it needs to be, or added functionality that
isn't presently needed by the system. Reviewers should be especially vigilant
about over-engineering. Encourage developers to solve the problem they know
needs to be solved *now*, not the problem that the developer speculates *might*
need to be solved in the future. The future problem should be solved once it
arrives and you can see its actual shape and requirements in the physical
universe.
### Tests
Ask for unit, integration, or end-to-end
tests as appropriate for the change. In general, tests should be added in the
same PR as the production code unless the PR is handling an
[emergency](#emergencies).
Make sure that the tests in the PR are correct, sensible, and useful. Tests do
not test themselves, and we rarely write tests for our tests—a human must ensure
that tests are valid.
Will the tests actually fail when the code is broken? If the code changes
beneath them, will they start producing false positives? Does each test make
simple and useful assertions? Are the tests separated appropriately between
different test methods?
Remember that tests are also code that has to be maintained. Don't accept
complexity in tests just because they aren't part of the main binary.
### Naming
Did the developer pick good names for everything? A good name is long enough to
fully communicate what the item is or does, without being so long that it
becomes hard to read.
### Comments
Did the developer write clear comments in understandable English? Are all of the
comments actually necessary? Usually comments are useful when they **explain
why** some code exists, and should not be explaining *what* some code is doing.
If the code isn't clear enough to explain itself, then the code should be made
simpler. There are some exceptions (regular expressions and complex algorithms
often benefit greatly from comments that explain what they're doing, for
example) but mostly comments are for information that the code itself can't
possibly contain, like the reasoning behind a decision.
It can also be helpful to look at comments that were there before this PR. Maybe
there is a TODO that can be removed now, a comment advising against this change
being made, etc.
Note that comments are different from *documentation* of classes, modules, or
functions, which should instead express the purpose of a piece of code, how it
should be used, and how it behaves when used.
### Style
We have [style guides](http://google.github.io/styleguide/) at Google for all
of our major languages, and even for most of the minor languages. Make sure the
PR follows the appropriate style guides.
If you want to improve some style point that isn't in the style guide, prefix
your comment with "Nit:" to let the developer know that it's a nitpick that you
think would improve the code but isn't mandatory. Don't block PRs from being
merged based only on personal style preferences.
The author of the PR should not include major style changes combined with other
changes. It makes it hard to see what is being changed in the PR, makes merges
and rollbacks more complex, and causes other problems. For example, if the
author wants to reformat the whole file, have them send you just the
reformatting as one PR, and then send another PR with their functional changes
after that.
### Consistency
What if the existing code is inconsistent with the style guide? Per our
[code review principles](#principles), the style guide is the
absolute authority: if something is required by the style guide, the PR should
follow the guidelines.
In some cases, the style guide makes recommendations rather than declaring
requirements. In these cases, it's a judgment call whether the new code should
be consistent with the recommendations or the surrounding code. Bias towards
following the style guide unless the local inconsistency would be too confusing.
If no other rule applies, the author should maintain consistency with the
existing code.
Either way, encourage the author to file a bug and add a TODO for cleaning up
existing code.
### Documentation
If a PR changes how users build, test, interact with, or release code, check to
see that it also updates associated documentation, including
READMEs, repository docs, and any generated
reference docs. If the PR deletes or deprecates code, consider whether the
documentation should also be deleted.
If documentation is
missing, ask for it.
### Every Line {#every-line}
In the general case, look at *every* line of code that you have been assigned to
review. Some things like data files, generated code, or large data structures
you can scan over sometimes, but don't scan over a human-written class,
function, or block of code and assume that what's inside of it is okay.
Obviously some code deserves more careful scrutiny than other code—that's
a judgment call that you have to make—but you should at least be sure that
you *understand* what all the code is doing.
If it's too hard for you to read the code and this is slowing down the review,
then you should let the developer know that
and wait for them to clarify it before you try to review it. At Google, we hire
great software engineers, and you are one of them. If you can't understand the
code, it's very likely that other developers won't either. So you're also
helping future developers understand this code, when you ask the developer to
clarify it.
If you understand the code but you don't feel qualified to do some part of the
review, [make sure there is a reviewer](#every-line-exceptions) on the PR who is
qualified, particularly for complex issues such as privacy, security,
concurrency, accessibility, internationalization, etc.
#### Exceptions {#every-line-exceptions}
What if it doesn't make sense for you to review every line? For example, you are
one of multiple reviewers on a PR and may be asked:
* To review only certain files that are part of a larger change.
* To review only certain aspects of the PR, such as the high-level design,
privacy or security implications, etc.
In these cases, note in a comment which parts you reviewed. Prefer giving
[Approve with comments](#approve-with-comments)
.
If you instead wish to grant Approval after confirming that other reviewers have
reviewed other parts of the PR, note this explicitly in a comment to set
expectations. Aim to [respond quickly](#responses) once the PR has
reached the desired state.
### Context
It is often helpful to look at the PR in a broad context. Usually the code
review tool will only show you a few lines of code around the parts that are
being changed. Sometimes you have to look at the whole file to be sure that the
change actually makes sense. For example, you might see only four new lines
being added, but when you look at the whole file, you see those four lines are
in a 50-line method that now really needs to be broken up into smaller methods.
It's also useful to think about the PR in the context of the system as a whole.
Is this PR improving the code health of the system or is it making the whole
system more complex, less tested, etc.? **Don't accept PRs that degrade the code
health of the system.** Most systems become complex through many small changes
that add up, so it's important to prevent even small complexities in new
changes.
### Good Things {#good-things}
If you see something nice in the PR, tell the developer, especially when they
addressed one of your comments in a great way. Code reviews often just focus on
mistakes, but they should offer encouragement and appreciation for good
practices, as well. It’s sometimes even more valuable, in terms of mentoring, to
tell a developer what they did right than to tell them what they did wrong.
### Summary
In doing a code review, you should make sure that:
- The code is well-designed.
- The functionality is good for the users of the code.
- Any UI changes are sensible and look good.
- Any parallel programming is done safely.
- The code isn't more complex than it needs to be.
- The developer isn't implementing things they *might* need in the future but
don't know they need now.
- Code has appropriate unit tests.
- Tests are well-designed.
- The developer used clear names for everything.
- Comments are clear and useful, and mostly explain *why* instead of *what*.
- Code is appropriately documented (generally in repository docs).
- The code conforms to our style guides.
Make sure to review **every line** of code you've been asked to review, look at
the **context**, make sure you're **improving code health**, and compliment
developers on **good things** that they do.
Next: [Navigating a PR in Review](#navigating-a-pr)
---
## Navigating a PR in review {#navigating-a-pr}
### Summary
Now that you know [what to look for](#what-to-look-for), what's the most efficient
way to manage a review that's spread across multiple files?
1. Does the change make sense? Does it have a good
[description](#pr-descriptions)?
2. Look at the most important part of the change first. Is it well-designed
overall?
3. Look at the rest of the PR in an appropriate sequence.
### Step One: Take a broad view of the change {#step_one}
Look at the [PR description](#pr-descriptions) and what the PR
does in general. Does this change even make sense? If this change shouldn't have
happened in the first place, please respond immediately with an explanation of
why the change should not be happening. When you reject a change like this, it's
also a good idea to suggest to the developer what they should have done instead.
For example, you might say "Looks like you put some good work into this, thanks!
However, we're actually going in the direction of removing the FooWidget system
that you're modifying here, and so we don't want to make any new modifications
to it right now. How about instead you refactor our new BarWidget class?"
Note that not only did the reviewer reject the current PR and provide an
alternative suggestion, but they did it *courteously*. This kind of courtesy is
important because we want to show that we respect each other as developers even
when we disagree.
If you get more than a few PRs that represent changes you don't want to make,
you should consider re-working your team's development process or the posted
process for external contributors so that there is more communication before PRs
are written. It's better to tell people "no" before they've done a ton of work
that now has to be thrown away or drastically re-written.
### Step Two: Examine the main parts of the PR {#step_two}
Find the file or files that are the "main" part of this PR. Often, there is one
file that has the largest number of logical changes, and it's the major piece of
the PR. Look at these major parts first. This helps give context to all of the
smaller parts of the PR, and generally accelerates doing the code review. If the
PR is too large for you to figure out which parts are the major parts, ask the
developer what you should look at first, or ask them to
[split up the PR into multiple PRs](#small-prs).
If you see some major design problems with this part of the PR, you should send
those comments immediately, even if you don't have time to review the rest of
the PR right now. In fact, reviewing the rest of the PR might be a waste of
time, because if the design problems are significant enough, a lot of the other
code under review is going to disappear and not matter anyway.
There are two major reasons it's so important to send these major design
comments out immediately:
- Developers often mail a PR and then immediately start new work based on that
PR while they wait for review. If there are major design problems in the PR
you're reviewing, they're also going to have to re-work their later PR. You
want to catch them before they've done too much extra work on top of the
problematic design.
- Major design changes take longer to do than small changes. Developers nearly
all have deadlines; in order to make those deadlines and still have quality
code in the codebase, the developer needs to start on any major re-work of
the PR as soon as possible.
### Step Three: Look through the rest of the PR in an appropriate sequence {#step_three}
Once you've confirmed there are no major design problems with the PR as a whole,
try to figure out a logical sequence to look through the files while also making
sure you don't miss reviewing any file. Usually after you've looked through the
major files, it's simplest to just go through each file in the order that
the code review tool presents them to you. Sometimes it's also helpful to read the tests
first before you read the main code, because then you have an idea of what the
change is supposed to be doing.
Next: [Speed of Code Reviews](#speed-of-reviews)
---
## Speed of Code Reviews {#speed-of-reviews}
### Why Should Code Reviews Be Fast? {#why}
**At Google, we optimize for the speed at which a team of developers can produce
a product together**, as opposed to optimizing for the speed at which an
individual developer can write code. The speed of individual development is
important, it's just not *as* important as the velocity of the entire team.
When code reviews are slow, several things happen:
* **The velocity of the team as a whole is decreased.** Yes, the individual
who doesn't respond quickly to the review gets other work done. However, new
features and bug fixes for the rest of the team are delayed by days, weeks,
or months as each PR waits for review and re-review.
* **Developers start to protest the code review process.** If a reviewer only
responds every few days, but requests major changes to the PR each time,
that can be frustrating and difficult for developers. Often, this is
expressed as complaints about how "strict" the reviewer is being. If the
reviewer requests the *same* substantial changes (changes which really do
improve code health), but responds *quickly* every time the developer makes
an update, the complaints tend to disappear. **Most complaints about the
code review process are actually resolved by making the process faster.**
* **Code health can be impacted.** When reviews are slow, there is increased
pressure to allow developers to merge PRs that are not as good as they
could be. Slow reviews also discourage code cleanups, refactorings, and
further improvements to existing PRs.
### How Fast Should Code Reviews Be? {#fast}
If you are not in the middle of a focused task, **you should do a code review
shortly after it comes in.**
**One business day is the maximum time it should take to respond** to a code
review request (i.e., first thing the next morning).
Following these guidelines means that a typical PR should get multiple rounds of
review (if needed) within a single day.
### Speed vs. Interruption {#interruption}
There is one time where the consideration of personal velocity trumps team
velocity. **If you are in the middle of a focused task, such as writing code,
don't interrupt yourself to do a code review.**
Research has shown that it can
take a long time for a developer to get back into a smooth flow of development
after being interrupted. So interrupting yourself while coding is actually
*more* expensive to the team than making another developer wait a bit for a code
review.
Instead, wait for a break point in your work before you respond to a request for
review. This could be when your current coding task is completed, after lunch,
returning from a meeting, coming back from the breakroom, etc.
### Fast Responses {#responses}
When we talk about the speed of code reviews, it is the *response* time that we
are concerned with, as opposed to how long it takes a PR to get through the
whole review and be merged. The whole process should also be fast, ideally,
but **it's even more important for the *individual responses* to come quickly
than it is for the whole process to happen rapidly.**
Even if it sometimes takes a long time to get through the entire review
*process*, having quick responses from the reviewer throughout the process
significantly eases the frustration developers can feel with "slow" code
reviews.
If you are too busy to do a full review on a PR when it comes in, you can still
send a quick response that lets the developer know when you will get to it,
suggest other reviewers who might be able to respond more quickly, or
[provide some initial broad comments](#navigating-a-pr). (Note: none of this means
you should interrupt coding even to send a response like this—send the
response at a reasonable break point in your work.)
**It is important that reviewers spend enough time on review that they are
certain their "Approve" means "this code meets [our standards](#standard-of-code-review)."**
However, individual responses should still ideally be [fast](#fast).
### Cross-Time-Zone Reviews {#tz}
When dealing with time zone differences, try to get back to the author while
they have time to respond before the end of their working hours. If they have
already finished work for the day, then try to make sure your review is done
before they start work the next day.
### Approve With Comments (LGTM) {#approve-with-comments}
In order to speed up code reviews, there are certain situations in which a
reviewer should Approve even though they are also leaving unresolved
comments on the PR. This should be done when at least one of the following
applies:
* The reviewer is confident that the developer will appropriately address all
the reviewer's remaining comments.
* The comments don't *have* to be addressed by the developer.
* The suggestions are minor, e.g. sort imports, fix a nearby typo, apply a
suggested fix, remove an unused dep, etc.
The reviewer should specify which of these options they intend, if it is not
otherwise clear.
Approve With Comments is especially worth considering when the developer and
reviewer are in different time zones and otherwise the developer would be
waiting for a whole day just to get approval.
### Large PRs {#large}
If somebody sends you a code review that is so large you're not sure when you
will be able to have time to review it, your typical response should be to ask
the developer to
[split the PR into several smaller PRs](#small-prs) that build on
each other, instead of one huge PR that has to be reviewed all at once. This is
usually possible and very helpful to reviewers, even if it takes additional work
from the developer.
If a PR *can't* be broken up into smaller PRs, and you don't have time to review
the entire thing quickly, then at least write some comments on the overall
design of the PR and send it back to the developer for improvement. One of your
goals as a reviewer should be to always unblock the developer or enable them to
take some sort of further action quickly, without sacrificing code health to do
so.
### Code Review Improvements Over Time {#time}
If you follow these guidelines and you are strict with your code reviews, you
should find that the entire code review process tends to go faster and faster
over time. Developers learn what is required for healthy code, and send you PRs
that are great from the start, requiring less and less review time. Reviewers
learn to respond quickly and not add unnecessary latency into the review
process.
But **don't compromise on
the [code review standards](#standard-of-code-review) or quality for an imagined improvement
in velocity**—it's not actually going to make anything happen more
quickly, in the long run.
### Emergencies
There are also [emergencies](#emergencies) where PRs must pass through the
*whole* review process very quickly, and where the quality guidelines would be
relaxed. However, please see [What Is An Emergency?](#what) for
a description of which situations actually qualify as emergencies and which
don't.
Next: [How to Write Code Review Comments](#writing-review-comments)
---
## How to write code review comments {#writing-review-comments}
### Summary
- Be kind.
- Explain your reasoning.
- Balance giving explicit directions with just pointing out problems and
letting the developer decide.
- Encourage developers to simplify code or add code comments instead of just
explaining the complexity to you.
### Courtesy
In general, it is important to be
[courteous and respectful](https://chromium.googlesource.com/chromium/src/+/master/docs/cr_respect.md)
while also being very clear and helpful to the developer whose code you are
reviewing. One way to do this is to be sure that you are always making comments
about the *code* and never making comments about the *developer*. You don't
always have to follow this practice, but you should definitely use it when
saying something that might otherwise be upsetting or contentious. For example:
Bad: "Why did **you** use threads here when there's obviously no benefit to be
gained from concurrency?"
Good: "The concurrency model here is adding complexity to the system without any
actual performance benefit that I can see. Because there's no performance
benefit, it's best for this code to be single-threaded instead of using multiple
threads."
### Explain Why {#why}
One thing you'll notice about the "good" example from above is that it helps the
developer understand *why* you are making your comment. You don't always need to
include this information in your review comments, but sometimes it's appropriate
to give a bit more explanation around your intent, the best practice you're
following, or how your suggestion improves code health.
### Giving Guidance {#guidance}
**In general it is the developer's responsibility to fix a PR, not the
reviewer's.** You are not required to do detailed design of a solution or write
code for the developer.
This doesn't mean the reviewer should be unhelpful, though. In general you
should strike an appropriate balance between pointing out problems and providing
direct guidance. Pointing out problems and letting the developer make a decision
often helps the developer learn, and makes it easier to do code reviews. It also
can result in a better solution, because the developer is closer to the code
than the reviewer is.
However, sometimes direct instructions, suggestions, or even code are more
helpful. The primary goal of code review is to get the best PR possible. A
secondary goal is improving the skills of developers so that they require less
and less review over time.
Remember that people learn from reinforcement of what they are doing well and
not just what they could do better. If you see things you like in the PR,
comment on those too! Examples: developer cleaned up a messy algorithm, added
exemplary test coverage, or you as the reviewer learned something from the PR.
Just as with all comments, include [why](#why) you liked something, further
encouraging the developer to continue good practices.
### Label comment severity {#label-comment-severity}
Consider labeling the severity of your comments, differentiating required
changes from guidelines or suggestions.
Here are some examples:
> Nit: This is a minor thing. Technically you should do it, but it won’t hugely
> impact things.
>
> Optional (or Consider): I think this may be a good idea, but it’s not strictly
> required.
>
> FYI: I don’t expect you to do this in this PR, but you may find this
> interesting to think about for the future.
This makes review intent explicit and helps authors prioritize the importance of
various comments. It also helps avoid misunderstandings; for example, without
comment labels, authors may interpret all comments as mandatory, even if some
comments are merely intended to be informational or optional.
### Accepting Explanations {#explanations}
If you ask a developer to explain a piece of code that you don't understand,
that should usually result in them **rewriting the code more clearly**.
Occasionally, adding a comment in the code is also an appropriate response, as
long as it's not just explaining overly complex code.
**Explanations written only in the code review tool are not helpful to future
code readers.** They are acceptable only in a few circumstances, such as when
you are reviewing an area you are not very familiar with and the developer
explains something that normal readers of the code would have already known.
Next: [Handling Pushback in Code Reviews](#handling-pushback)
---
## Handling pushback in code reviews {#handling-pushback}
Sometimes a developer will push back on a code review. Either they will disagree
with your suggestion or they will complain that you are being too strict in
general.
### Who is right? {#who_is_right}
When a developer disagrees with your suggestion, first take a moment to consider
if they are correct. Often, they are closer to the code than you are, and so
they might really have a better insight about certain aspects of it. Does their
argument make sense? Does it make sense from a code health perspective? If so,
let them know that they are right and let the issue drop.
However, developers are not always right. In this case the reviewer should
further explain why they believe that their suggestion is correct. A good
explanation demonstrates both an understanding of the developer's reply, and
additional information about why the change is being requested.
In particular, when the reviewer believes their suggestion will improve code
health, they should continue to advocate for the change, if they believe the
resulting code quality improvement justifies the additional work requested.
**Improving code health tends to happen in small steps.**
Sometimes it takes a few rounds of explaining a suggestion before it really
sinks in. Just make sure to always stay [polite](#courtesy) and let
the developer know that you *hear* what they're saying, you just don't *agree*.
### Upsetting Developers {#upsetting_developers}
Reviewers sometimes believe that the developer will be upset if the reviewer
insists on an improvement. Sometimes developers do become upset, but it is
usually brief and they become very thankful later that you helped them improve
the quality of their code. Usually, if you are [polite](#courtesy) in
your comments, developers actually don't become upset at all, and the worry is
just in the reviewer's mind. Upsets are usually more about
[the way comments are written](#courtesy) than about the reviewer's
insistence on code quality.
### Cleaning It Up Later {#later}
A common source of push back is that developers (understandably) want to get
things done. They don't want to go through another round of review just to get
this PR in. So they say they will clean something up in a later PR, and thus you
should Approve *this* PR now. Some developers are very good about this, and will
immediately write a follow-up PR that fixes the issue. However, experience shows
that as more time passes after a developer writes the original PR, the less
likely this clean up is to happen. In fact, usually unless the developer does
the clean up *immediately* after the present PR, it never happens. This isn't
because developers are irresponsible, but because they have a lot of work to do
and the cleanup gets lost or forgotten in the press of other work. Thus, it is
usually best to insist that the developer clean up their PR *now*, before the
code is in the codebase and "done." Letting people "clean things up later" is a
common way for codebases to degenerate.
If a PR introduces new complexity, it must be cleaned up before merge
unless it is an [emergency](#emergencies). If the PR exposes surrounding
problems and they can't be addressed right now, the developer should file a bug
for the cleanup and assign it to themselves so that it doesn't get lost. They
can optionally also write a TODO comment in the code that references the filed
bug.
### General Complaints About Strictness {#strictness}
If you previously had fairly lax code reviews and you switch to having strict
reviews, some developers will complain very loudly. Improving the
[speed](#speed-of-reviews) of your code reviews usually causes these complaints to fade
away.
Sometimes it can take months for these complaints to fade away, but eventually
developers tend to see the value of strict code reviews as they see what great
code they help generate. Sometimes the loudest protesters even become your
strongest supporters once something happens that causes them to really see the
value you're adding by being strict.
### Resolving Conflicts {#conflicts}
If you are following all of the above but you still encounter a conflict between
yourself and a developer that can't be resolved, see
[The Standard of Code Review](#standard-of-code-review) for guidelines and principles that
can help resolve the conflict.
---
## The PR author's guide to getting through code review {#pr-author-index}
The pages in this section contain best practices for developers going through
code review. These guidelines should help you get through reviews faster and
with higher-quality results. You don't have to read them all, but they are
intended to apply to every Google developer, and many people have found it
helpful to read the whole set.
- [Writing Good PR Descriptions](#pr-descriptions)
- [Small PRs](#small-prs)
- [How to Handle Reviewer Comments](#handling-review-feedback)
See also [How to Do a Code Review](#reviewer-index), which gives detailed
guidance for code reviewers.
---
## Writing good PR descriptions {#pr-descriptions}
A PR description is a public record of change, and it is important that it
communicates:
1. **What** change is being made? This should summarize the major changes such
that readers have a sense of what is being changed without needing to read
the entire PR.
1. **Why** are these changes being made? What contexts did you have as an
author when making this change? Were there decisions you made that aren't
reflected in the source code? etc.
The PR description will become a permanent part of our version control history
and will possibly be read by hundreds of people over the years.
Future developers will search for your PR based on its description. Someone in
the future might be looking for your change because of a faint memory of its
relevance but without the specifics handy. If all the important information is
in the code and not the description, it's going to be a lot harder for them to
locate your PR.
And then, after they find the PR, will they be able to understand *why* the
change was made? Reading source code may reveal what the software is doing but
it may not reveal why it exists, which can make it harder for future developers
to know whether they can move
[Chesterton's fence](https://abseil.io/resources/swe-book/html/ch03.html#understand_context).
A well-written PR description will help those future engineers -- sometimes,
including yourself!
### First Line {#first-line}
* Short summary of what is being done.
* Complete sentence, written as though it was an order.
* Follow by empty line.
The **first line** of a PR description should be a short summary of
*specifically* **what** *is being done by the PR*, followed by a blank line.
This is what appears in version control history summaries, so it should be
informative enough that future code searchers don't have to read your PR or its
whole description to understand what your PR actually *did* or how it differs
from other PRs. That is, the first line should stand alone, allowing readers to
skim through code history much faster.
Try to keep your first line short, focused, and to the point. The clarity and
utility to the reader should be the top concern.
By tradition, the first line of a PR description is a complete sentence, written
as though it were an order (an imperative sentence). For example, say
\"**Delete** the FizzBuzz RPC and **replace** it with the new system." instead
of \"**Deleting** the FizzBuzz RPC and **replacing** it with the new system."
You don't have to write the rest of the description as an imperative sentence,
though.
### Body is Informative {#informative}
The [first line](#first-line) should be a short, focused summary, while the rest
of the description should fill in the details and include any supplemental
information a reader needs to understand the change holistically. It might
include a brief description of the problem that's being solved, and why this is
the best approach. If there are any shortcomings to the approach, they should be
mentioned. If relevant, include background information such as bug numbers,
benchmark results, and links to design documents.
If you include links to external resources consider that they may not be visible
to future readers due to access restrictions or retention policies. Where
possible include enough context for reviewers and future readers to understand
the PR.
Even small PRs deserve a little attention to detail. Put the PR in context.
### Bad PR Descriptions {#bad}
"Fix bug" is an inadequate PR description. What bug? What did you do to fix it?
Other similarly bad descriptions include:
- "Fix build."
- "Add patch."
- "Moving code from A to B."
- "Phase 1."
- "Add convenience functions."
- "kill weird URLs."
Some of those are real PR descriptions. Although short, they do not provide
enough useful information.
### Good PR Descriptions {#good}
Here are some examples of good descriptions.
#### Functionality change {#functionality-change}
Example:
> RPC: Remove size limit on RPC server message freelist.
>
> Servers like FizzBuzz have very large messages and would benefit from reuse.
> Make the freelist larger, and add a goroutine that frees the freelist entries
> slowly over time, so that idle servers eventually release all freelist
> entries.
The first few words describe what the PR actually does. The rest of the
description talks about the problem being solved, why this is a good solution,
and a bit more information about the specific implementation.
#### Refactoring {#refactoring}
Example:
> Construct a Task with a TimeKeeper to use its TimeStr and Now methods.
>
> Add a Now method to Task, so the borglet() getter method can be removed (which
> was only used by OOMCandidate to call borglet's Now method). This replaces the
> methods on Borglet that delegate to a TimeKeeper.
>
> Allowing Tasks to supply Now is a step toward eliminating the dependency on
> Borglet. Eventually, collaborators that depend on getting Now from the Task
> should be changed to use a TimeKeeper directly, but this has been an
> accommodation to refactoring in small steps.
>
> Continuing the long-range goal of refactoring the Borglet Hierarchy.
The first line describes what the PR does and how this is a change from the
past. The rest of the description talks about the specific implementation, the
context of the PR, that the solution isn't ideal, and possible future direction.
It also explains *why* this change is being made.
#### Small PR that needs some context
Example:
> Create a Python3 build rule for status.py.
>
> This allows consumers who are already using this as in Python3 to depend on a
> rule that is next to the original status build rule instead of somewhere in
> their own tree. It encourages new consumers to use Python3 if they can,
> instead of Python2, and significantly simplifies some automated build file
> refactoring tools being worked on currently.
The first sentence describes what's actually being done. The rest of the
description explains *why* the change is being made and gives the reviewer a lot
of context.
### Using tags {#tags}
Tags are manually entered labels that can be used to categorize PRs. These may
be supported by tools or just used by team convention.
For example:
- "[tag]"
- "[a longer tag]"
- "#tag"
- "tag:"
Using tags is optional.
When adding tags, consider whether they should be in the [body](#informative) of
the PR description or the [first line](#first-line). Limit the usage of tags in
the first line, as this can obscure the content.
Examples with and without tags:
Good:
```
// Tags are okay in the first line if kept short.
[banana] Peel the banana before eating.
// Tags can be inlined in content.
Peel the #banana before eating.
// Tags are optional.
Peel the banana before eating.
// Multiple tags are acceptable if kept short.
#banana #apple: Assemble a fruit basket.
// Tags can go anywhere in the PR description.
> Assemble a fruit basket.
>
> #banana #apple
```
Bad:
```
// Too many tags (or tags that are too long) overwhelm the first line.
//
// Instead, consider whether the tags can be moved into the description body
// and/or shortened.
[banana peeler factory factory][apple picking service] Assemble a fruit basket.
```
### Generated PR descriptions
Some PRs are generated by tools. Whenever possible, their descriptions should
also follow the advice here. That is, their first line should be short, focused,
and stand alone, and the PR description body should include informative details
that help reviewers and future code searchers understand each PR's effect.
### Review the description before merging the PR
PRs can undergo significant change during review. It can be worthwhile to review
a PR description before merging the PR, to ensure that the description still
reflects what the PR does.
Next: [Small PRs](#small-prs)
---
## Small PRs {#small-prs}
### Why Write Small PRs? {#why}
Small, simple PRs are:
- **Reviewed more quickly.** It's easier for a reviewer to find five minutes
several times to review small PRs than to set aside a 30 minute block to
review one large PR.
- **Reviewed more thoroughly.** With large changes, reviewers and authors tend
to get frustrated by large volumes of detailed commentary shifting back and
forth—sometimes to the point where important points get missed or dropped.
- **Less likely to introduce bugs.** Since you're making fewer changes, it's
easier for you and your reviewer to reason effectively about the impact of
the PR and see if a bug has been introduced.
- **Less wasted work if they are rejected.** If you write a huge PR and then
your reviewer says that the overall direction is wrong, you've wasted a lot
of work.
- **Easier to merge.** Working on a large PR takes a long time, so you will
have lots of conflicts when you merge, and you will have to merge
frequently.
- **Easier to design well.** It's a lot easier to polish the design and code
health of a small change than it is to refine all the details of a large
change.
- **Less blocking on reviews.** Sending self-contained portions of your
overall change allows you to continue coding while you wait for your current
PR in review.
- **Simpler to roll back.** A large PR will more likely touch files that get
updated between the initial PR submission and a rollback PR, complicating
the rollback (the intermediate PRs will probably need to be rolled back
too).
Note that **reviewers have discretion to reject your change outright for the
sole reason of it being too large.** Usually they will thank you for your
contribution but request that you somehow make it into a series of smaller
changes. It can be a lot of work to split up a change after you've already
written it, or require lots of time arguing about why the reviewer should accept
your large change. It's easier to just write small PRs in the first place.
### What is Small? {#what-is-small}
In general, the right size for a PR is **one self-contained change**. This means
that:
- The PR makes a minimal change that addresses **just one thing**. This is
usually just one part of a feature, rather than a whole feature at once. In
general it's better to err on the side of writing PRs that are too small vs.
PRs that are too large. Work with your reviewer to find out what an
acceptable size is.
- The PR should [include related test code](#test_code).
- Everything the reviewer needs to understand about the PR (except future
development) is in the PR, the PR's description, the existing codebase, or a
PR they've already reviewed.
- The system will continue to work well for its users and for the developers
after the PR is merged.
- The PR is not so small that its implications are difficult to understand. If
you add a new API, you should include a usage of the API in the same PR so
that reviewers can better understand how the API will be used. This also
prevents checking in unused APIs.
There are no hard and fast rules about how large is "too large." 100 lines is
usually a reasonable size for a PR, and 1000 lines is usually too large, but
it's up to the judgment of your reviewer. The number of files that a change is
spread across also affects its "size." A 200-line change in one file might be
okay, but spread across 50 files it would usually be too large.
Keep in mind that although you have been intimately involved with your code from
the moment you started to write it, the reviewer often has no context. What
seems like an acceptably-sized PR to you might be overwhelming to your reviewer.
When in doubt, write PRs that are smaller than you think you need to write.
Reviewers rarely complain about getting PRs that are too small.
### When are Large PRs Okay? {#large-okay}
There are a few situations in which large changes aren't as bad:
- You can usually count deletion of an entire file as being just one line of
change, because it doesn't take the reviewer very long to review.
- Sometimes a large PR has been generated by an automatic refactoring tool
that you trust completely, and the reviewer's job is just to verify and say
that they really do want the change. These PRs can be larger, although some
of the caveats from above (such as merging and testing) still apply.
### Writing Small PRs Efficiently {#efficiently}
If you write a small PR and then you wait for your reviewer to approve it before
you write your next PR, then you're going to waste a lot of time. So you want to
find some way to work that won't block you while you're waiting for review. This
could involve having multiple projects to work on simultaneously, finding
reviewers who agree to be immediately available, doing in-person reviews, pair
programming, or splitting your PRs in a way that allows you to continue working
immediately.
### Splitting PRs {#splitting}
When starting work that will have multiple PRs with potential dependencies among
each other, it's often useful to think about how to split and organize those PRs
at a high level before diving into coding.
Besides making things easier for you as an author to manage and organize your
PRs, it also makes things easier for your code reviewers, which in turn makes
your code reviews more efficient.
Here are some strategies for splitting work into different PRs.
#### Stacking Multiple Changes on Top of Each Other {#stacking}
One way to split up a PR without blocking yourself is to write one small PR,
send it off for review, and then immediately start writing another PR *based* on
the first PR. Most version control systems allow you to do this somehow.
#### Splitting by Files {#splitting-files}
Another way to split up a PR is by groupings of files that will require
different reviewers but are otherwise self-contained changes.
For example: you send off one PR for modifications to a protocol buffer and
another PR for changes to the code that uses that proto. You have to merge the
proto PR before the code PR, but they can both be reviewed simultaneously. If
you do this, you might want to inform both sets of reviewers about the other PR
that you wrote, so that they have context for your changes.
Another example: you send one PR for a code change and another for the
configuration or experiment that uses that code; this is easier to roll back
too, if necessary, as configuration/experiment files are sometimes pushed to
production faster than code changes.
#### Splitting Horizontally {#splitting-horizontally}
Consider creating shared code or stubs that help isolate changes between layers
of the tech stack. This not only helps expedite development but also encourages
abstraction between layers.
For example: You created a calculator app with client, API, service, and data
model layers. A shared proto signature can abstract the service and data model
layers from each other. Similarly, an API stub can split the implementation of
client code from service code and enable them to move forward independently.
Similar ideas can also be applied to more granular function or class level
abstractions.
#### Splitting Vertically {#splitting-vertically}
Orthogonal to the layered, horizontal approach, you can instead break down your
code into smaller, full-stack, vertical features. Each of these features can be
independent parallel implementation tracks. This enables some tracks to move
forward while other tracks are awaiting review or feedback.
Back to our calculator example from
[Splitting Horizontally](#splitting-horizontally). You now want to support new
operators, like multiplication and division. You could split this up by
implementing multiplication and division as separate verticals or sub-features,
even though they may have some overlap such as shared button styling or shared
validation logic.
#### Splitting Horizontally & Vertically {#splitting-grid}
To take this a step further, you could combine these approaches and chart out an
implementation plan like this, where each cell is its own standalone PR.
Starting from the model (at the bottom) and working up to the client:
| Layer | Feature: Multiplication | Feature: Division |
| ------- | ------------------------- | ------------------------------- |
| Client | Add button | Add button |
| API | Add endpoint | Add endpoint |
| Service | Implement transformations | Share transformation logic with |
| ... | ... | ... |
| Model | Add proto definition | Add proto definition |
### Separate Out Refactorings {#refactoring}
It's usually best to do refactorings in a separate PR from feature changes or
bug fixes. For example, moving and renaming a class should be in a different PR
from fixing a bug in that class. It is much easier for reviewers to understand
the changes introduced by each PR when they are separate.
Small cleanups such as fixing a local variable name can be included inside of a
feature change or bug fix PR, though. It's up to the judgment of developers and
reviewers to decide when a refactoring is so large that it will make the review
more difficult if included in your current PR.
### Keep related test code in the same PR {#test-code}
PRs should include related test code. Remember that [smallness](#what-is-small)
here refers the conceptual idea that the PR should be focused and is not a
simplistic function on line count.
Tests are expected for all Google changes.
A PR that adds or changes logic should be accompanied by new or updated tests
for the new behavior. Pure refactoring PRs (that aren't intended to change
behavior) should also be covered by tests; ideally, these tests already exist,
but if they don't, you should add them.
*Independent* test modifications can go into separate PRs first, similar to the
[refactorings guidelines](#refactoring). That includes:
* Validating pre-existing, merged code with new tests.
* Ensures that important logic is covered by tests.
* Increases confidence in subsequent refactorings on affected code. For
example, if you want to refactor code that isn't already covered by
tests, merging test PRs *before* merging refactoring PRs can
validate that the tested behavior is unchanged before and after the
refactoring.
* Refactoring the test code (e.g. introduce helper functions).
* Introducing larger test framework code (e.g. an integration test).
### Don't Break the Build {#break}
If you have several PRs that depend on each other, you need to find a way to
make sure the whole system keeps working after each PR is merged. Otherwise
you might break the build for all your fellow developers for a few minutes
between your PR merges (or even longer if something goes wrong unexpectedly
with your later PR merges).
### Can't Make it Small Enough {#cant}
Sometimes you will encounter situations where it seems like your PR *has* to be
large. This is very rarely true. Authors who practice writing small PRs can
almost always find a way to decompose functionality into a series of small
changes.
Before writing a large PR, consider whether preceding it with a refactoring-only
PR could pave the way for a cleaner implementation. Talk to your teammates and
see if anybody has thoughts on how to implement the functionality in small PRs
instead.
If all of these options fail (which should be extremely rare) then get consent
from your reviewers in advance to review a large PR, so they are warned about
what is coming. In this situation, expect to be going through the review process
for a long time, be vigilant about not introducing bugs, and be extra diligent
about writing tests.
Next: [How to Handle Reviewer Comments](#handling-review-feedback)
---
## How to handle reviewer comments {#handling-review-feedback}
When you've sent a PR out for review, it's likely that your reviewer will
respond with several comments on your PR. Here are some useful things to know
about handling reviewer comments.
### Don't Take it Personally {#personal}
The goal of review is to maintain the quality of our codebase and our products.
When a reviewer provides a critique of your code, think of it as their attempt
to help you, the codebase, and Google, rather than as a personal attack on you
or your abilities.
Sometimes reviewers feel frustrated and they express that frustration in their
comments. This isn't a good practice for reviewers, but as a developer you
should be prepared for this. Ask yourself, "What is the constructive thing that
the reviewer is trying to communicate to me?" and then operate as though that's
what they actually said.
**Never respond in anger to code review comments.** That is a serious breach of
professional etiquette that will live in the review history. If you
are too angry or annoyed to respond kindly, then walk away from your computer
for a while, or work on something else until you feel calm enough to reply
politely.
In general, if a reviewer isn't providing feedback in a way that's constructive
and polite, explain this to them in person. If you can't talk to them in person
or on a video call, then send them a private email. Explain to them in a kind
way what you don't like and what you'd like them to do differently. If they also
respond in a non-constructive way to this private discussion, or it doesn't have
the intended effect, then
escalate to your manager as
appropriate.
### Fix the Code {#code}
If a reviewer says that they don't understand something in your code, your first
response should be to clarify the code itself. If the code can't be clarified,
add a code comment that explains why the code is there. If a comment seems
pointless, only then should your response be an explanation in the code review
tool.
If a reviewer didn't understand some piece of your code, it's likely other
future readers of the code won't understand either. Writing a response in the
review tool doesn't help future code readers, but clarifying your code or
adding code comments does help them.
### Think Collaboratively {#think}
Writing a PR can take a lot of work. It's often really satisfying to finally
send one out for review, feel like it's done, and be pretty sure that no further
work is needed. It can be frustrating to receive comments asking for changes,
especially if you don't agree with them.
At times like this, take a moment to step back and consider if the reviewer is
providing valuable feedback that will help the codebase and Google. Your first
question to yourself should always be, "Do I understand what the reviewer is
asking for?"
If you can't answer that question, ask the reviewer for clarification.
And then, if you understand the comments but disagree with them, it's important
to think collaboratively, not combatively or defensively:
```txt
Bad: "No, I'm not going to do that."
```
```txt
Good: "I went with X because of [these pros/cons] with [these tradeoffs]
My understanding is that using Y would be worse because of [these reasons].
Are you suggesting that Y better serves the original tradeoffs, that we should
weigh the tradeoffs differently, or something else?"
```
Remember,
**[courtesy and respect](https://chromium.googlesource.com/chromium/src/+/master/docs/cr_respect.md)
should always be a first priority**. If you disagree with the reviewer, find
ways to collaborate: ask for clarifications, discuss pros/cons, and provide
explanations of why your method of doing things is better for the codebase,
users, and/or Google.
Sometimes, you might know something about the users, codebase, or PR that the
reviewer doesn't know. [Fix the code](#code) where appropriate, and engage your
reviewer in discussion, including giving them more context. Usually you can come
to some consensus between yourself and the reviewer based on technical facts.
### Resolving Conflicts {#conflicts}
Your first step in resolving conflicts should always be to try to come to
consensus with your reviewer. If you can't achieve consensus, see
[The Standard of Code Review](#standard-of-code-review), which gives principles
to follow in such a situation.
---
## Emergencies {#emergencies}
Sometimes there are emergency PRs that must pass through the entire code review
process as quickly as
possible.
### What Is An Emergency? {#what}
An emergency PR would be a **small** change that: allows a major launch to
continue instead of rolling back, fixes a bug significantly affecting users in
production, handles a pressing legal issue, closes a major security hole, etc.
In emergencies we really do care about the speed of the entire code review
process, not just the [speed of response](#speed-of-reviews). In this case
*only*, the reviewer should care more about the speed of the review and the
correctness of the code (does it actually resolve the emergency?) than anything
else. Also (perhaps obviously) such reviews should take priority over all other
code reviews, when they come up.
However, after the emergency is resolved you should look over the emergency PRs
again and give them a [more thorough review](#what-to-look-for).
### What Is NOT An Emergency? {#not}
To be clear, the following cases are *not* an emergency:
- Wanting to launch this week rather than next week (unless there is some
actual [hard deadline](#deadlines) for launch such as a partner agreement).
- The developer has worked on a feature for a very long time and they really
want to get the PR in.
- The reviewers are all in another timezone where it is currently nighttime or
they are away on an off-site.
- It is the end of the day on a Friday and it would just be great to get this
PR in before the developer leaves for the weekend.
- A manager says that this review has to be complete and the PR merged
today because of a [soft (not hard) deadline](#deadlines).
- Rolling back a PR that is causing test failures or build breakages.
And so on.
### What Is a Hard Deadline? {#deadlines}
A hard deadline is one where **something disastrous would happen** if you miss
it. For example:
- Submitting your PR by a certain date is necessary for a contractual
obligation.
- Your product will completely fail in the marketplace if not released by a
certain date.
- Some hardware manufacturers only ship new hardware once a year. If you miss
the deadline to submit code to them, that could be disastrous, depending on
what type of code you're trying to ship.
Delaying a release for a week is not disastrous. Missing an important conference
might be disastrous, but often is not.
Most deadlines are soft deadlines, not hard deadlines. They represent a desire
for a feature to be done by a certain time. They are important, but you
shouldn't be sacrificing code health to make them.
If you have a long release cycle (several weeks) it can be tempting to sacrifice
code review quality to get a feature in before the next cycle. However, this
pattern, if repeated, is a common way for projects to build up overwhelming
technical debt. If developers are routinely merging PRs near the end of the
cycle that "must get in" with only superficial review, then the team should
modify its process so that large feature changes happen early in the cycle and
have enough time for good review.
==========
---
title: "Nice way of putting it"
date: 2025-09-20
canonical: https://solmaz.io/x/1969321668725158311/
x_url: https://x.com/onusoz/status/1969321668725158311
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Nice way of putting it
*Quotes a post by another author (https://x.com/i/status/1969247680762429784); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Just downgraded my anthropic sub, 200 usd openai plan is finally justified after 1 year"
date: 2025-09-13
canonical: https://solmaz.io/x/1966797279945204059/
x_url: https://x.com/onusoz/status/1966797279945204059
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Just downgraded my anthropic sub, 200 usd openai plan is finally justified after 1 year
==========
---
title: "Enjoying gpt5 codex free lunch before openai inevitably starts cutting corners just like..."
date: 2025-09-12
canonical: https://solmaz.io/x/1966560391024308282/
x_url: https://x.com/onusoz/status/1966560391024308282
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Enjoying gpt5 codex free lunch before openai inevitably starts cutting corners just like anthropic
(I hope to be wrong in 3 months, this model is very good at one shotting things and I don’t want it to be nerfed)
==========
---
title: "@thsottiaux 2/ Model just stops working on a task even though I tell it to run something and..."
date: 2025-09-08
canonical: https://solmaz.io/x/1964942275278192834/
x_url: https://x.com/onusoz/status/1964942275278192834
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@thsottiaux 2/ Model just stops working on a task even though I tell it to run something and not stop until it works. I have to frequently say “ok do it then”. Probably a model problem and not harness problem
==========
---
title: "CLAUDE.md to AGENTS.md Migration Guide"
date: 2025-09-08
canonical: https://solmaz.io/log/2025/09/08/claude-md-agents-md-migration-guide/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> **Update:** Anthropic still doesn't fully accept AGENTS.md, so I created this: [`claude-md-symlinker`](https://github.com/dutifuldev/claude-md-symlinker).
>
> Install it once and Claude Code can keep local `CLAUDE.md -> AGENTS.md`
> symlinks working for you. No manually creating shim files, no committing
> Claude-branded files into your repos.
>
> Install using the installer script, or give this page to Claude and ask it to install for you.
>
> ```
> curl -fsSL https://github.com/dutifuldev/claude-md-symlinker/releases/latest/download/claude-md-symlinker-installer.sh | sh
> ```
>
> This will install a Claude hook that will check whenever Claude traverses a certain directory, and do the migration automatically for you.
>
> If you are paranoid about security, ask Claude to check the source code for any issues and install the symlinker from the source.
This post will age like milk, because Anthropic will eventually adopt the company-agnostic [AGENTS.md standard](https://agents.md/).
For those that do not know, AGENTS.md is like robots.txt, but for providing plain text context to any AI agent working in your codebase.
It's very stupid really. It's not even worthy of being called a "standard". The only rule is the name of the file.
Anthropic champions CLAUDE.md, named after their own agent Claude. Insisting on that stupid convention is like Google forcing websites to use [`googlebot.txt`](https://en.wikipedia.org/wiki/Googlebot) instead of `robots.txt`, or Microsoft [`clippy.txt`](https://en.wikipedia.org/wiki/Office_Assistant).
Anyway, since this post will become irrelevant very soon, here are some AI-generated instructions on how to migrate your CLAUDE.md files to AGENTS.md.
## Why Migrate?
- **Open Standard**: AGENTS.md is an open standard that works with multiple AI systems
- **Interoperability**: Maintains backward compatibility through symlinks
- **Future-Proof**: Not tied to a specific AI platform or tool
- **Consistency**: Standardizes agent instructions across the codebase
## Actual Migration Commands Used
### Step 1: Rename Files
The following commands were used to rename existing CLAUDE.md files to AGENTS.md:
```bash
# Find all CLAUDE.md files and rename them to AGENTS.md
find . -name "CLAUDE.md" -type f -exec sh -c 'mv "$1" "${1%CLAUDE.md}AGENTS.md"' _ {} \;
```
### Step 2: Update Content
Replace Claude-specific references with agent-agnostic language:
```bash
# Update file headers in all AGENTS.md files
find . -name "AGENTS.md" -type f -exec sed -i '' 's/This file provides guidance to Claude Code (claude.ai\/code)/This file provides guidance to AI agents/g' {} \;
```
### Step 3: Update .gitignore
Add these lines to `.gitignore` to ignore symlinked CLAUDE.md files:
```bash
# Add to .gitignore
cat >> .gitignore << 'EOF'
# CLAUDE.md files (automatically generated from AGENTS.md via symlinks)
CLAUDE.md
**/CLAUDE.md
EOF
```
### Step 4: Create Symlink Setup Script
Create `utils/setup-claude-symlinks.sh` with the following content:
```bash
#!/bin/bash
# Script to create CLAUDE.md symlinks to AGENTS.md files
# This allows CLAUDE.md files to exist locally without being committed to git
set -e
echo "Setting up CLAUDE.md symlinks..."
# Change to repository root
cd "$(git rev-parse --show-toplevel)"
# Find all AGENTS.md files and create corresponding CLAUDE.md symlinks
git ls-files | grep "AGENTS\.md$" | while read -r file; do
dir=$(dirname "$file")
claude_file="${file/AGENTS.md/CLAUDE.md}"
# Remove existing CLAUDE.md file/link if it exists
if [ -e "$claude_file" ] || [ -L "$claude_file" ]; then
rm "$claude_file"
echo "Removed existing $claude_file"
fi
# Create symlink
if [ "$dir" = "." ]; then
ln -s "AGENTS.md" "CLAUDE.md"
echo "Created symlink: CLAUDE.md -> AGENTS.md"
else
ln -s "AGENTS.md" "$claude_file"
echo "Created symlink: $claude_file -> AGENTS.md"
fi
done
echo ""
echo "✓ CLAUDE.md symlinks setup complete!"
echo " - CLAUDE.md files are ignored by git"
echo " - They will automatically stay in sync with AGENTS.md files"
echo " - Run this script again if you add new AGENTS.md files"
```
### Step 5: Run Symlink Setup
Make the script executable and run it:
```bash
chmod +x utils/setup-claude-symlinks.sh
./utils/setup-claude-symlinks.sh
```
## Top-Level AGENTS.md Note
Add this note to the main AGENTS.md file:
```markdown
**Note**: This project uses the open AGENTS.md standard. These files are symlinked to CLAUDE.md files in the same directory for interoperability with Claude Code. Any agent instructions or memory features should be saved to AGENTS.md files instead of CLAUDE.md files.
```
## Directory Structure After Migration
```
project/
├── AGENTS.md # Primary agent instructions
├── CLAUDE.md # Symlink to AGENTS.md (git ignored)
├── utils/
│ └── setup-claude-symlinks.sh # Symlink setup script
├── backend/
│ ├── AGENTS.md # Backend-specific instructions
│ └── CLAUDE.md # Symlink to AGENTS.md (git ignored)
└── apps/
├── AGENTS.md # Frontend-specific instructions
├── CLAUDE.md # Symlink to AGENTS.md (git ignored)
└── web/
├── AGENTS.md # App-specific instructions
└── CLAUDE.md # Symlink to AGENTS.md (git ignored)
```
## Content Update Examples
### Before Migration
```markdown
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
```
### After Migration
```markdown
# AGENTS.md
This file provides guidance to AI agents when working with code in this repository.
```
## Verification Commands
Verify the migration worked correctly:
```bash
# Check all AGENTS.md files exist
find . -name "AGENTS.md" -type f
# Verify symlinks are created
find . -name "CLAUDE.md" -type l
# Check symlinks point to correct files
find . -name "CLAUDE.md" -type l -exec ls -la {} \;
# Verify content is agent-agnostic
grep -r "Claude Code (claude.ai/code)" . --include="*.md" | grep AGENTS.md
```
## Maintenance
### Adding New AGENTS.md Files
When you add new AGENTS.md files, run the symlink setup script:
```bash
./utils/setup-claude-symlinks.sh
```
### Checking Symlink Status
```bash
# List all symlinks
find . -name "CLAUDE.md" -type l -exec ls -la {} \;
# Check for broken symlinks
find . -name "CLAUDE.md" -type l ! -exec test -e {} \; -print
```
## Benefits of This Approach
1. **Backward Compatibility**: Existing tools expecting CLAUDE.md files continue to work
2. **Git Clean**: CLAUDE.md files are not tracked in version control
3. **Automatic Sync**: Symlinks ensure CLAUDE.md always matches AGENTS.md
4. **Easy Maintenance**: Single script handles all symlink creation/updates
5. **Open Standard**: Future-proof with the open AGENTS.md standard
## Troubleshooting
### Broken Symlinks
```bash
# Remove all CLAUDE.md symlinks and recreate
find . -name "CLAUDE.md" -type l -delete
./utils/setup-claude-symlinks.sh
```
### Permission Issues
```bash
# Make sure script is executable
chmod +x utils/setup-claude-symlinks.sh
```
This migration preserves all existing functionality while adopting the open AGENTS.md standard for better interoperability.
==========
---
title: "So let me get this straight, the main reason for Responses API exists is that OpenAI doesn’t..."
date: 2025-09-05
canonical: https://solmaz.io/x/1964010520643543115/
x_url: https://x.com/onusoz/status/1964010520643543115
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
So let me get this straight, the main reason for Responses API exists is that OpenAI doesn’t want to show reasoning traces? Therefore the whole world should bend backwards to fit your obscurantist standards? Responses will not get adopted the same reason Windows Server didn’t
*Quotes a post by another author (https://x.com/i/status/1963801245115904232); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "gpt5 did such and such on that bench, oh it didn't even surpass grok 4 on arc-agi... bro did..."
date: 2025-08-09
canonical: https://solmaz.io/x/1954140134518980967/
x_url: https://x.com/onusoz/status/1954140134518980967
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
gpt5 did such and such on that bench, oh it didn't even surpass grok 4 on arc-agi... bro did you even look at the price?
openai pushed the parento frontier hard with this one. I don't care that it doesn't know 4.11 < 4.9
==========
---
title: "I converted this thread to a blog post and it hit HN front page"
date: 2025-08-04
canonical: https://solmaz.io/x/1952285810763427879/
x_url: https://x.com/onusoz/status/1952285810763427879
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I converted this thread to a blog post and it hit HN front page
*Quotes a post by @onusoz (https://x.com/onusoz/status/1952133418046660609); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Because of this, I predict a decrease in Python adoption in companies, specifically for..."
date: 2025-08-03
canonical: https://solmaz.io/x/1952133427076952261/
x_url: https://x.com/onusoz/status/1952133427076952261
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Because of this, I predict a decrease in Python adoption in companies, specifically for production deployments, even though I like it so much
==========
---
title: "My >10 yr old programming habits have changed since Claude Code launched. Python is less..."
date: 2025-08-03
canonical: https://solmaz.io/x/1952133418046660609/
x_url: https://x.com/onusoz/status/1952133418046660609
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My >10 yr old programming habits have changed since Claude Code launched. Python is less likely to be my go-to language for new projects anymore. I am managing projects in languages I am not fluent in---TypeScript, Rust and Go---and seem to be doing pretty well
*Part 1/2 of a thread; root: https://solmaz.io/x/1952133418046660609/*
==========
---
title: "It seems that typed, compiled, etc. languages are more suited for vibe coding, because of the..."
date: 2025-08-03
canonical: https://solmaz.io/x/1952133419938251018/
x_url: https://x.com/onusoz/status/1952133419938251018
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It seems that typed, compiled, etc. languages are more suited for vibe coding, because of the safety guarantees. This is unsurprising in hindsight, but it was counterintuitive because by default I "vibed" projects into existence in Python for as long as I can remember
*Part 2/2 of a thread; root: https://solmaz.io/x/1952133418046660609/*
==========
---
title: "Typed languages are better suited for vibecoding"
date: 2025-08-03
canonical: https://solmaz.io/typed-languages-are-better-suited-for-vibecoding
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
My >10 year old programming habits have changed since [Claude Code](https://www.anthropic.com/claude-code) launched. Python is less likely to be my go-to language for new projects anymore. I am managing projects in languages I am not fluent in---TypeScript, Rust and Go---and seem to be doing pretty well.
It seems that typed, compiled, etc. languages are better suited for vibecoding, because of the safety guarantees. This is unsurprising in hindsight, but it was counterintuitive because by default I "vibed" projects into existence in Python since forever.
Paradoxically, after a certain size of project, I can move faster and safer with e.g. Claude Code + Rust, compared to Claude Code + Python, despite the low-levelness of the code[^1]. This is possible purely because of AI tools.
For example, I refactored large chunks of our TypeScript frontend code at TextCortex. Claude Code runs `tsc` after finishing each task and ensures that the code compiles before committing. This let me move much faster compared to how I would have done it in Python, which does not provide compile-time guarantees. I am amazed every time how my 3-5k line diffs created in a few hours don't end up breaking anything, and instead even increase stability.
LLMs are [leaky abstractions](https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/), sure. But they now work well enough so that they solve the problem Python solved for me (fast prototyping), without the disadvantages of Python (lower safety guarantees, slowness, ambiguity[^2]).
Because of this, I predict a decrease in Python adoption in companies, specifically for production deployments, even though I like it so much.
---
[^1]: Some will say that was the case even without AI tools, and to that my response is: it depends.
[^2]: Arguably.
==========
---
title: "Lol should I go back to computational mechanics"
date: 2025-07-26
canonical: https://solmaz.io/x/1949049783080849457/
x_url: https://x.com/onusoz/status/1949049783080849457
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Lol should I go back to computational mechanics
*Quotes a post by another author (https://x.com/i/status/1948792752277520487); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I've just upgraded @nikitabobko Aerospace from v15 to v19, and I can say it's WAY MORE faster..."
date: 2025-07-21
canonical: https://solmaz.io/x/1947258400489845247/
x_url: https://x.com/onusoz/status/1947258400489845247
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I've just upgraded @nikitabobko Aerospace from v15 to v19, and I can say it's WAY MORE faster. Friendly reminder that you might be running an old version as well. Thank you @nikitabobko !
==========
---
title: "Anthropic is not god"
date: 2025-07-17
canonical: https://solmaz.io/x/1945767025084662150/
x_url: https://x.com/onusoz/status/1945767025084662150
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anthropic is not god
*Quotes a post by another author (https://x.com/i/status/1943687594560332025); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I can testify"
date: 2025-07-16
canonical: https://solmaz.io/x/1945605753185644738/
x_url: https://x.com/onusoz/status/1945605753185644738
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I can testify
*Quotes a post by another author (https://x.com/i/status/1945561392179769419); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I found an OK-ish solution to Claude Code running python instead of uv in first try cc..."
date: 2025-07-13
canonical: https://solmaz.io/x/1944430364232909185/
x_url: https://x.com/onusoz/status/1944430364232909185
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I found an OK-ish solution to Claude Code running python instead of uv in first try cc @mitsuhiko @simonw
*Part 1/2 of a thread; root: https://solmaz.io/x/1944430364232909185/*
==========
---
title: "Read more here: solmaz.io/log/2025/07/13…"
date: 2025-07-13
canonical: https://solmaz.io/x/1944430366661460198/
x_url: https://x.com/onusoz/status/1944430366661460198
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Read more here: https://solmaz.io/log/2025/07/13/claude-code-python-override/
*Part 2/2 of a thread; root: https://solmaz.io/x/1944430364232909185/*
==========
---
title: "Workaround for Claude Code running `python` instead of `uv`"
date: 2025-07-13
canonical: https://solmaz.io/log/2025/07/13/claude-code-python-override/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
[uv](https://docs.astral.sh/uv/) is now the de facto default Python package manager. I have already deleted all `python`s from my system except for the one that has to be installed for other packages in `brew`.
Unfortunately, Claude Code often ignores instructions in `CLAUDE.md` files to use `uv run python` instead of plain `python` commands. Even with clear documentation stating "always use uv", Claude Code will attempt to run `python` directly, leading to "command not found" errors in projects that rely on uv for Python environment management.
The built-in Claude Code hooks and environment variable settings also don't reliably solve this issue due to shell context limitations.
**The reason is that Claude (and most other AI models) take time to catch up to such changes, because their learning horizon is longer, up to months to years. Somebody will need to include this information explicitly in the training data.**
Until then, we can prevent wasting tokens by mapping `python` and `python3` to `uv`.
I personally don't want to map these globally, because a lot of other packages might depend on system installed `python`s, like `brew` packages, `gcloud` CLI and so on.
Because of that, I map them at the project level, using [direnv](https://direnv.net/):
### An OK-ish solution: direnv + dynamic wrapper scripts
We can force Claude Code (and any developer) to use `uv run python` by dynamically creating wrapper scripts in a `.envrc` file that [direnv](https://direnv.net/) automatically loads when entering the project directory.
This will override `python` and `python3` to map to `uv run python`, and also print a nice message to the model:
```Use "uv run python ..." instead of "python ..." idiot```.
This is probably not the best solution, but it is *a* solution. Feel free to suggest a better one.
### Step 1: Install direnv
```bash
# macOS
brew install direnv
# Ubuntu/Debian
sudo apt install direnv
# Add to your shell (bash/zsh)
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc # or ~/.bashrc
source ~/.zshrc # or restart terminal
```
### Step 2: Setup direnv with dynamic wrapper scripts
```bash
# Create .envrc file in project root
cat > .envrc << 'EOF'
#!/bin/bash
# Create temporary bin directory for python overrides
TEMP_BIN_DIR="$PWD/.direnv/bin"
mkdir -p "$TEMP_BIN_DIR"
# Create python wrapper scripts
cat > "$TEMP_BIN_DIR/python" << 'INNER_EOF'
#!/bin/bash
echo "Use \"uv run python ...\" instead of \"python ...\" idiot"
exec uv run python "$@"
INNER_EOF
cat > "$TEMP_BIN_DIR/python3" << 'INNER_EOF'
#!/bin/bash
echo "Use \"uv run python ...\" instead of \"python3 ...\" idiot"
exec uv run python "$@"
INNER_EOF
# Make them executable
chmod +x "$TEMP_BIN_DIR/python" "$TEMP_BIN_DIR/python3"
# Add to PATH
export PATH="$TEMP_BIN_DIR:$PATH"
EOF
# Allow direnv to load this configuration
direnv allow
```
### Step 3: Update .gitignore
```bash
# Add direnv generated files to .gitignore
echo "# direnv generated files" >> .gitignore
echo ".direnv/" >> .gitignore
```
### Step 4: Update documentation
Add to your `CLAUDE.md` something like this:
````
## Python Package Management with uv
**IMPORTANT**: This project uses `uv` as the Python package manager. ALWAYS use `uv` instead of `pip` or `python` directly.
DO NOT RUN:
```bash
python my_script.py
# OR
chmod +x my_script.py
./my_script.py
```
INSTEAD, RUN:
```bash
uv run my_script.py
```
### Key uv Commands
- **Run Python code**: `uv run ` (NOT `python `)
- **Run module**: `uv run -m ` (e.g., `uv run -m pytest`)
- **Add dependencies**: `uv add ` (e.g., `uv add requests`)
- **Add dev dependencies**: `uv add --dev `
- **Remove dependencies**: `uv remove `
- **Install all dependencies**: `uv sync`
- **Update lock file**: `uv lock`
- **Run with specific package**: `uv run --with `
````
### How It Works
1. **direnv** automatically loads `.envrc` when you `cd` into the project directory
2. `.envrc` dynamically creates executable wrapper scripts in `.direnv/bin/`
3. Scripts display a helpful message and redirect to `uv run python`
4. `.direnv/bin/` is prepended to PATH, overriding system python commands
5. Works for any shell session in the directory (Claude Code, terminal, IDE)
To see if it works:
```bash
cd your-project/
python -c "print('Hello World')" # Shows message, uses uv
python3 --version # Shows message, uses uv
```
Let me know if this doesn't work for you, or if you find a better solution.
==========
---
title: "What is the current best way to make Claude Code use uv run instead of python?"
date: 2025-07-06
canonical: https://solmaz.io/x/1941818382182916491/
x_url: https://x.com/onusoz/status/1941818382182916491
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What is the current best way to make Claude Code use uv run instead of python?
I have added instructions to CLAUDE md, but it still calls python for the first time, then corrects to uv run
It must be happening to so many people now, so many tokens wasted
cc @mitsuhiko @simonw
==========
---
title: "Day 47 of Claude Code god mode"
date: 2025-07-05
canonical: https://solmaz.io/log/2025/07/05/day-47-of-claude-code/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I started using Claude Code on May 18th, 2025. I had previously given it a chance back in February, but I had immediately WTF'd after a simple task cost 5 USD back then. When Anthropic announced their 100 USD flat plan in May, I jumped ship as soon as I could.[^1]
It's not an overstatement that my life has drastically changed since then. I can't post or blog anything anymore, because I am busy working every day on ideas, at [TextCortex](https://textcortex.com), and on side projects. I now sleep regularly 1-2 hours less than I used to and my sleep schedule has shifted around 2 hours.
But more importantly, I feel exhilaration that I have never felt as a developer before. I just talk to my computer using a speech to text tool (Wispr Flow), and my thoughts turn into code close to real time. I feel like I have enabled god mode IRL. We are truly living in a time where imagination is the only remaining bottleneck.
### Things I have implemented using Claude Code
#### **TextCortex Monorepo**
The most important contribution, I merged our backend, frontend and docs repos into a single monorepo in less than 1 day, with all CI/CD and automation. This lets us use our entire code and documentation context while triggering AI agents.
We can now tag @claude in issues, and it creates PRs. Non-developers have started to make contributions to the codebase and fix bugs. Our organization speed has increased drastically in a matter of days. I will write more about this in a future post.
#### [JSON-DOC TypeScript renderer](https://github.com/textcortex/JSON-DOC/pull/15)
JSON-DOC is a file format we are developing at TextCortex. I implemented the browser viewer for the format in 1 workday, in a language I am not fluent in. It was a rough first draft, but the architecture was correct and our frontend team could then take it over and polish it. Without Claude Code, I predict it would have taken at least 2-3 weeks of my time to take it to that level.
#### [Claude Code PR Autodoc Action](https://github.com/textcortex/claude-code-pr-autodoc-action)
We are not using this anymore, but it's a GitHub Action that triggers in every PR and adds documentation about that PR to the repo.
#### [Claude Code Sandbox](https://github.com/textcortex/claude-code-sandbox)
Still work-in-progress, but it is supposed to give you an OpenAI Codex like experience with running Claude Code locally on your own machine. We have big plans for this.
#### TextCortex Agentic RAG implementation
The next version of our product, I revamped our chat engine completely to implement agentic RAG. Since our frontend had long running issues, I had to recreate our chat UI from scratch, again in 1 day. Will be rolled out in a few weeks, so I cannot write about it yet.
#### Fixed i18n
I had a system in mind for auto-translating strings in a codebase for 2 years, when GPT-4 came out. I finally implemented that in 1 day. We had previously used DeepL which did some really stupid mistakes like translating "Disabled" (in the computer sense) as "behindert" in German, which means *r...ded*, or "Tenant" (enterprise software) as "Mieter" (renter of a real estate). The new system generates a context for each string based on the surrounding code, which is then used to translate the string to all the different languages. There is truly no point in paying for a SaaS for i18n anymore, when you can automate it with GitHub Actions and ship it statically.[^2]
### Tackling small-to-mid-size tasks without context switching
Perhaps the most important effect of agentic development is that it lets you do all the things you wanted to, but couldn't before, because it was too big of a context switch.
There are certain parts of a codebase that require utmost attention, like when you are designing a data model, the API endpoint schemas, and so on. Mostly backend. But once you know your backend is good enough, you can just rip away on the frontend side with Claude Code, because you know your business data and logic is safe.
I have finished so many of these that it would make this post too long. To give one example, I implemented a Discord bot that we can use to download whole threads, so that we can embed it in the monorepo or create GitHub issues automatically.
### Side projects
My performance on my side projects has also increased a lot. I am able to ship in 1 weekend day close to 2 weeks worth of dev-work. Thanks to Claude Code, I was able to ship my new app [Horse](https://horse.fit). It's like an AI personal trainer, but it only counts your push-ups for now. But even that was a complex enough computer vision task.
I had previously only written the Python algo for detecting push-ups. Claude Code let me develop the backend, frontend and the low-level engine in Rust, over the course of 2-3 weekends.
I knew nothing about cross-compiling Rust code to iOS, yet I was able to do the whole thing, FFI and all, in 20 minutes, which worked out of the box. Important takeaway: AI makes it incredibly easy to port well-tested codebases to different languages. I predict an increased rate of Rust-ification of open source projects.
You can see more about it on my sports Instagram [here](https://www.instagram.com/stories/highlights/18511599592034978/).
### It's all about completing the loop
Agentic workflows work best when you have a good verifier (like tests) which lets you create a good feedback loop. This might be the compiler output, a Playwright MCP server, running `pytest`, spinning up a local server and making a request, and so on.
Once you complete the loop, you can just let AI rip on it, and come back to a finished result after a few minutes or hours.
### Swearing at AI
I have developed a new and ingrained habit of swearing at Claude Code, in the past couple of weeks. I frequently call it "idiot", "r...d", "absolute f...g moron" and so on. With increasing speed comes increasing impatience, and frustration when the agent does not get something despite having the right context.
I think there is something deeply psychological about feeling these kind of emotions towards AI. I know it's an entity that does not retain memory or learn as a human does, but I still insult it when it fails at a task. I feel like it mostly works, but I have not done any scientific experiments to prove it.
The empathic reader should be aware that emotional reactions to AI reveal more about one's own psychological state than the AI's.
### On Claude Code skeptics
Claude Code is a great litmus test to detect whoever is a deadweight at a company. If your employees cannot learn to use Claude Code to do productive work, you should most likely fire them. It's not about the product or Anthropic itself, but the upcoming agentic development paradigm. [Dario Amodei was not bluffing when he said that a white collar bloodbath is coming](https://www.axios.com/2025/05/28/ai-jobs-white-collar-unemployment-anthropic).
I have since then introduced multiple people to Claude Code, all good developers. All of them were initially skeptical, but the next day all of them texted me "wow"-like messages. The fire is spreading.
The 100 USD plan was initially the main obstacle to people trying it out, but now it's available in the 17 USD plan, so I expect to see very rapid adoption in the following months.
---
I got done in 47 days more work than I previously did in 6-12 months. I am curious how TextCortex will look in 6 months from now.
[^1]: I previously had the insight that Claude Code would perform better than Cursor, because the model providers have control over what tool data to include in the dataset, whereas Cursor is approaching the model as an outsider and trying to do trial and error on what kind of interfaces the model would be good at.
[^2]: Disclaimer, our founder Jay had already done work to use GPT-4o for automating translations, what I added on top was the context generation and improvements in automation.
==========
---
title: "Coding is dead"
date: 2025-07-02
canonical: https://solmaz.io/x/1940374584735440981/
x_url: https://x.com/onusoz/status/1940374584735440981
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Coding is dead
Programming is all what is left now
==========
---
title: "+1"
date: 2025-06-25
canonical: https://solmaz.io/x/1937867758214984143/
x_url: https://x.com/onusoz/status/1937867758214984143
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
+1
*Quotes a post by another author (https://x.com/i/status/1937610262560800873); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "When you tell Claude Code to ultrathink"
date: 2025-06-12
canonical: https://solmaz.io/x/1933159368737829200/
x_url: https://x.com/onusoz/status/1933159368737829200
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
When you tell Claude Code to ultrathink
==========
---
title: "How does Codex adoption compare to Claude Code? I just unleashed deep research on it and it..."
date: 2025-06-06
canonical: https://solmaz.io/x/1931071583696646246/
x_url: https://x.com/onusoz/status/1931071583696646246
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
How does Codex adoption compare to Claude Code? I just unleashed deep research on it and it says Codex is more popular, but that goes completely against my guesses
==========
---
title: "Using Claude Code to reverse engineer Claude Code 🤝"
date: 2025-06-05
canonical: https://solmaz.io/x/1930539178208432601/
x_url: https://x.com/onusoz/status/1930539178208432601
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Using Claude Code to reverse engineer Claude Code 🤝
==========
---
title: "Wrote about this earlier this year!"
date: 2025-06-04
canonical: https://solmaz.io/x/1930370996273311765/
x_url: https://x.com/onusoz/status/1930370996273311765
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Wrote about this earlier this year!
https://solmaz.io/monetize-ai-not-the-editor
*Quotes a post by @karpathy (https://x.com/karpathy/status/1930354382106964079); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Predictions by Anthropic Researchers"
date: 2025-06-04
canonical: https://solmaz.io/log/2025/06/04/dwarkesh-sholto-trenton-2/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Dwarkesh Patel has recently interviewed Sholto Douglas and Trenton Bricken for a second time, and the podcast is very enlightening in terms of how the big AI labs think in terms of their economic strategy:
(Clicking will start the video around the 1hr mark, the part that is relevant to this post.)
According to Sholto and Trenton, the following have been largely "solved" by now:
* **Advanced math/programming:**
* "Math and competitive programming fell first." *(Sholto)*
* **Routine online interactions:**
* "Flight booking is totally solved." *(Sholto)*
* Successfully "planning a camping trip," navigating complicated websites. *(Trenton)*
And below are their predictions for what will be solved by next year, around May 2026:
* **Reliable web/software automation:**
* Photoshop edits with sequential effects: "Totally." *(Sholto)*
* Handling complex site interactions (e.g., managing cookies, navigating tricky interfaces): "If you gave it one person-month of effort, then it would be solved." *(Sholto)*
And below are what they predict will probably not be solved by next year:
* **Fully autonomous, high-trust tasks:**
* "I don't think it'll be able to autonomously do your taxes with a high degree of trust." *(Sholto)*
* **Generalized tax preparation:**
* "It will get the taxes wrong... If I went to you and I was like, 'I want you to do everyone's taxes in America,' what percentage of them are you going to fuck up?" *(Sholto)*
* **Models' self-awareness of its own reliability and confidence:**
* "The unreliability and confidence stuff will be somewhat tricky, to do this all the time." *(Sholto)*
---
I interpret this and the rest of the interview as follows:
> The labs can now "solve"[^1] any white-collar task or job segment if they put their resources into it. From now on, it is a question of how much it would pay off.
In other words, if the labs think it will make more money to automate accounting (or any other task), then they will create benchmarks for that and start optimizing. Until now, they have mostly been optimizing for software engineering[^2], because of high immediate payoff.
---
Below are some job segments that *I* predict to be affected first (not Sholto or Trenton):
* **Marketing & copywriting**: actually the first segment that already fell. Many AI companies (including [TextCortex](https://textcortex.com/)) was initially focused on this segment. Automation in this sector will increase even more in the upcoming years.
* **Customer service & support**: many countries where this is outsourced to, like India, will be affected.
* **Data entry, bookkeeping & accounting tasks**: while it is a dream to automate bookkeeping, accounting, taxes, etc. it will most likely fall last due to regulations and low margin for fuckups.
* **Paralegal & contract-review tasks**: Many companies popped up to target the legal system. Current law forbids automated lawyering in the US and most of the world. It will eventually fall as well, starting first with paralegal tasks, advisory services, etc.
* **Internal IT & systems administration**: will be automated the fastest, because it is being optimized for under the software engineering umbrella.
* **Real estate & insurance processing**: related companies will see that they are able to save a lot of money with AI. There will be a lot of competitive pressure in every country once the first few players are successfully automate their processes. These will most likely be smaller players, who will disrupt incumbents.
* **Product/project management (routine parts)**: cue recent Microsoft layoffs[^3], ending 600k comp. product manager positions. It is already happening, and will only accelerate.
---
[^1]: Automate a considerable part of it, so that the work will turn into mainly managing AI agents.
[^2]: E.g. the [SWE-Lancer](https://openai.com/index/swe-lancer/) benchmark by OpenAI.
[^3]: See [this article](https://www.theguardian.com/technology/2025/may/13/microsoft-layoffs). *The company’s chief financial officer, Amy Hood, said on an April earnings call that the company was focused on “building high-performing teams and increasing our agility by reducing layers with fewer managers”. She also said the headcount in March was 2% higher than a year earlier, and down slightly compared with the end of last year.*
==========
---
title: "Working with LLMs is definitely an art and not science"
date: 2025-06-02
canonical: https://solmaz.io/x/1929414713139450149/
x_url: https://x.com/onusoz/status/1929414713139450149
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Working with LLMs is definitely an art and not science
*Quotes a post by another author (https://x.com/i/status/1929284035680821645); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Just some thoughts after using Claude Code intensively for 1 week 👆"
date: 2025-06-01
canonical: https://solmaz.io/x/1929140563309191241/
x_url: https://x.com/onusoz/status/1929140563309191241
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Just some thoughts after using Claude Code intensively for 1 week 👆
*Part 2/2 of a thread; root: https://solmaz.io/x/1929140559668515195/*
==========
---
title: "The models, they just wanna work. They want to build your product, fix your bugs, serve your..."
date: 2025-06-01
canonical: https://solmaz.io/x/1929140559668515195/
x_url: https://x.com/onusoz/status/1929140559668515195
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The models, they just wanna work. They want to build your product, fix your bugs, serve your users. You feed them the right context, give them good tools. You don’t assume what they cannot do without trying, and you don’t prematurely constrain them into deterministic workflows.
*Part 1/2 of a thread; root: https://solmaz.io/x/1929140559668515195/*
==========
---
title: "solmaz.io/log/2025/05/31…"
date: 2025-05-31
canonical: https://solmaz.io/x/1928654335686144322/
x_url: https://x.com/onusoz/status/1928654335686144322
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
https://solmaz.io/log/2025/05/31/scp-3434/
*Part 2/2 of a thread; root: https://solmaz.io/x/1928654272910008711/*
==========
---
title: "SCP-3434: Istanbul Taxi Superorganism"
date: 2025-05-31
canonical: https://solmaz.io/x/1928654272910008711/
x_url: https://x.com/onusoz/status/1928654272910008711
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
SCP-3434: Istanbul Taxi Superorganism
*Part 1/2 of a thread; root: https://solmaz.io/x/1928654272910008711/*
==========
---
title: "SCP-3434: Istanbul Taxi Superorganism"
date: 2025-05-31
canonical: https://solmaz.io/log/2025/05/31/scp-3434/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
**Item #:** SCP-3434
**Object Class:** Euclid
**Special Containment Procedures:** SCP-3434 cannot be fully contained due to its diffuse nature and integration into civilian infrastructure. Foundation agents embedded within Istanbul's Transportation Coordination Center (UKOME) are to monitor taxi activity patterns for anomalous behavior spikes. Mobile Task Force ████ has been assigned to investigate and neutralize extreme manifestations within SCP-3434.
Individuals exhibiting temporal disorientation after utilizing taxi services in Istanbul should be administered Class-B amnestics and monitored for 72 hours post-incident. Under no circumstances should Foundation personnel utilize SCP-3434 instances for transportation unless authorized for testing purposes.
**Description:** SCP-3434 is a defensive superorganism manifesting as a collective consciousness within approximately 17,000 taxi vehicles operating in Istanbul, Turkey. Individual taxis display coordinated behaviors atypical for independently operated vehicles, functioning as a distributed neural network despite lacking any detectable communication infrastructure.
SCP-3434 exhibits three primary anomalous properties:
1. **Temporal Distortion:** Passengers experience significant time dilation upon entering affected vehicles. Discrepancies between perceived and actual elapsed time range from minutes to several hours, with no correlation to distance traveled or traffic conditions. GPS data from affected rides consistently shows corruption or retroactive alteration.
2. **Economic Predation:** The collective demonstrates uncanny ability to extract maximum possible fare from each passenger through coordinated deception, including meter "malfunctions," route manipulation, and inexplicable knowledge of passenger financial status. Credit card readers experience a ████ failure rate exclusively for non-local passengers.
3. **Territorial Defense:** SCP-3434 displays extreme hostility toward competing transportation services. Since 2011, all attempts by ridesharing platforms to establish operations have failed due to coordinated interference including simultaneous vehicle failures, GPS anomalies affecting only competitor vehicles, and physical blockades formed with millisecond precision.
**Incident Log 3434-A:**
On 14/09/2024, Agent ████ ████ was assigned to investigate temporal anomalies reported in the Beyoğlu district. Agent ████ entered taxi license plate 34 T ████ at 14:22 local time for what GPS tracking indicated would be a 12-minute journey to Taksim Square.
Agent ████ emerged at 14:34 local time at the intended destination. However, biological markers and personal chronometer readings indicated Agent ████ had experienced approximately 8 months of subjective time. Physical examination confirmed accelerated aging consistent with temporal displacement. Agent exhibited severe psychological distress and no memory of the elapsed period.
The taxi driver, when questioned, displayed no anomalous knowledge and insisted the journey had taken "only 15 minutes, very fast, no traffic." The meter showed a fare of ████, approximately 40 times the standard rate. Driver claimed this was "normal price, weekend rates."
Post-incident analysis of the taxi revealed no anomalous materials or modifications. The vehicle continues to operate within the SCP-3434 network without further documented incidents.
**Interview Log:**
> **Interviewed:** ███████ (Driver of taxi license plate 34 T ████)
>
> **Dr. ████:** How long have you been driving this route?
>
> **███████:** Route? What route? The city tells us where to go.
>
> **Dr. ████:** The city?
>
> **███████:** You wouldn't understand. You're not connected. But we all hear it. Every corner, every passenger, every lira. We are Istanbul, and Istanbul is us.
>
> **Dr. ████:** Can you elaborate on-
>
> **███████:** Your hotel is 20 minutes away. It will take us an hour. The meter is broken. Only cash.
**Addendum 3434-1:** Research into historical records reveals references to unusual taxi behavior in Istanbul dating back to 1942, coinciding with the introduction of the first motorized taxi services. The phenomenon appears to have evolved in complexity with the city's growth.
**Addendum 3434-2:** Foundation economists estimate SCP-3434's collective annual revenue exceeds ████ million Turkish Lira, with 0% reported to tax authorities. Attempts to audit individual drivers result in temporary disappearance of all documentation and the spontaneous malfunction of all electronic devices within a 10-meter radius.
**Note from Site Director:** "Under no circumstances should personnel attempt to 'outsmart' SCP-3434 by pretending to be locals. They already know. They always know."
---
I am on vacation, so here is a little bit of fun with some grounded fiction.
==========
---
title: "This is not an overstatement"
date: 2025-05-29
canonical: https://solmaz.io/x/1928037892099547640/
x_url: https://x.com/onusoz/status/1928037892099547640
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is not an overstatement
*Quotes a post by another author (https://x.com/i/status/1927803598936887686); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Headless makes running these things in a sandbox much easier. Sandbox means you can give all..."
date: 2025-05-29
canonical: https://solmaz.io/x/1927995944374509845/
x_url: https://x.com/onusoz/status/1927995944374509845
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Headless makes running these things in a sandbox much easier. Sandbox means you can give all permissions and just let it run until completion. See my efforts to do so here:
https://github.com/textcortex/claude-code-sandbox
==========
---
title: "I was trying to figure out why @AnthropicAI Claude Code feels better than @cursor_ai with Opus..."
date: 2025-05-29
canonical: https://solmaz.io/x/1927995931049292076/
x_url: https://x.com/onusoz/status/1927995931049292076
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I was trying to figure out why @AnthropicAI Claude Code feels better than @cursor_ai with Opus + Max mode. I can’t put my finger onto it, but one of the reasons might be that it’s faster, because it doesn’t use another model to apply the diffs, which you have to wait for
==========
---
title: "Just an update, building this now"
date: 2025-05-27
canonical: https://solmaz.io/x/1927316070571864398/
x_url: https://x.com/onusoz/status/1927316070571864398
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Just an update, building this now
The repo is claude-code-sandbox under TextCortex GitHub. The Proof-of-Concept is there, check the TODOs and current PRs to watch the current progress
https://github.com/textcortex/claude-code-sandbox
*Quotes a post by @onusoz (https://x.com/onusoz/status/1926765096723734900); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Same! Completely different than my first try a couple months ago"
date: 2025-05-27
canonical: https://solmaz.io/x/1927280786538951155/
x_url: https://x.com/onusoz/status/1927280786538951155
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Same! Completely different than my first try a couple months ago
*Quotes a post by another author (https://x.com/i/status/1927217797458719061); its text is omitted here because it is not covered by this site's license.*
==========
---
title: ".@AnthropicAI @bcherny @_catwu blink twice if you already have internally:"
date: 2025-05-25
canonical: https://solmaz.io/x/1926765096723734900/
x_url: https://x.com/onusoz/status/1926765096723734900
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@AnthropicAI @bcherny @_catwu blink twice if you already have internally:
$ claude sandbox
I can't wait until you release this, I'm gonna build it myself :)
*Quotes a post by @onusoz (https://x.com/onusoz/status/1926655519952928905); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "I've been using Claude Code extensively since last week"
date: 2025-05-25
canonical: https://solmaz.io/x/1926655519952928905/
x_url: https://x.com/onusoz/status/1926655519952928905
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I've been using Claude Code extensively since last week
What I'm wondering is, since you can run Claude Code locally, why isn't there any tooling to let you run it in a sandboxed mode in local Docker containers yet? Or did I miss it? cc @AnthropicAI
==========
---
title: "Generate documentation for your merged PRs automatically with Claude Code:"
date: 2025-05-25
canonical: https://solmaz.io/x/1926586867094294859/
x_url: https://x.com/onusoz/status/1926586867094294859
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Generate documentation for your merged PRs automatically with Claude Code:
https://solmaz.io/log/2025/05/24/claude-code-pr-autodoc-action/
==========
---
title: "Auto-generating pull request documentation with Claude Code and GitHub Actions"
date: 2025-05-24
canonical: https://solmaz.io/log/2025/05/24/claude-code-pr-autodoc-action/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Anthropic has just released a GitHub Action for integrating [Claude Code](https://www.anthropic.com/claude-code) into your GitHub repo. This lets you do very cool things, like **automatically generating documentation for your pull requests after you merge them**. Skip to the next section to learn how to install it in your repo.
Since Claude Code is envisioned to be a basic Unix utility, albeit a very smart one, it is very easy to use it in GitHub Actions. The action is very simple:
- It runs after a pull request is merged.
- It uses Claude Code to generate a documentation for the pull request.
- It creates a new pull request with the documentation.
This is super useful, because it saves context about the repo into the repo itself. The documentation generated this way is very useful for not only humans, but also for AI agents. A future AI can then learn about what was done in a certain PR, without looking at Git history, issues or PRs. In other words, it lets you automatically break GitHub's walled garden, using GitHub's native features [^1].
## Installation
1. Save your `ANTHROPIC_API_KEY` as a secret in the repo you want to install this action. You can find this page in `https://github.com///settings/secrets`. If you have already installed Claude Code in your repo by running `/install-github-app` in Claude Code, you can skip this step.
2. Save the following as `.github/workflows/claude-code-pr-autodoc.yml` in your repo:
```yaml
name: Auto-generate PR Documentation
on:
pull_request:
types: [closed]
branches:
- main
jobs:
generate-documentation:
# Only run when PR is merged and not created by bots
# This prevents infinite loops and saves compute resources
if: |
github.event.pull_request.merged == true &&
github.event.pull_request.user.type != 'Bot' &&
!startsWith(github.event.pull_request.title, 'docs: Add documentation for PR')
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: textcortex/claude-code-pr-autodoc-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
```
There are bunch of parameters you can configure, like minimum number of diff lines that will trigger the action, or the directory where the documentation will be saved. To learn about how to configure these parameters, visit the GitHub Action repo itself: [textcortex/claude-code-pr-autodoc-action](https://github.com/textcortex/claude-code-pr-autodoc-action).
## Usage
After you merge a PR, the action will automatically generate documentation for it and open a new PR with the documentation. You can then simply merge this PR, and the documentation will be added to the repo, by default in the `docs/prs` directory.
## Thoughts on Claude Code
I was curious why Anthropic had not released an agentic coding app on Claude.ai, and this might be the reason why.
The main Claude Code action is not limited to creating PR documentation. You tag `@claude`, in any comment, and Claude Code will answer questions or implement the changes you ask for.
While OpenAI and Google is busy creating sloppy chat UXs for agentic coding (Codex and Jules) and forcing developers to work on their site, Anthropic is taking Claude directly to the developers' feet and integrate Claude Code into GitHub.
Ask any question in a GitHub PR, and Claude Code will answer your questions, implement requested changes, fix bugs, typos, styling issues.
You don't need to go to code Codex or Jules website to follow up on your task. Why should you? Developer UX is already "solved" (well yes but no).
Anthropic bets on GitHub, what already works. That's why they have probably already won developers.
The only problem is that it costs a little bit too much for now.
In the long run, I am not sure if GitHub will be enough for following up async agentic coding tasks in parallel. Anthropic might soon launch their own agentic coding app. GitHub itself might evolve and create a better real-time chat UX. But unless that UX really blows my mind, I will most likely just hang out at GitHub. If you are an insider, or you know what Anthropic is planning to do, please let us know in the HN comment section.
---
[claude-code-pr-autodoc-action](https://github.com/textcortex/claude-code-pr-autodoc-action) was developed by me, 80% using Claude Code and 20% using Cursor with Claude Opus 4.
[^1]: [File over app by Steph Ango](https://stephango.com/file-over-app).
==========
---
title: "also my experience so far"
date: 2025-05-22
canonical: https://solmaz.io/x/1925674269549215997/
x_url: https://x.com/onusoz/status/1925674269549215997
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
also my experience so far
*Quotes a post by another author (https://x.com/i/status/1925224307548168699); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Best thing I have listened to this year"
date: 2025-05-22
canonical: https://solmaz.io/x/1925553532746301852/
x_url: https://x.com/onusoz/status/1925553532746301852
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Best thing I have listened to this year
*Quotes a post by another author (https://x.com/i/status/1925326203600429290); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "The more I compare coding agents, Cursor, Claude Code, Codex, it becomes more apparent to me..."
date: 2025-05-20
canonical: https://solmaz.io/x/1924796917952717052/
x_url: https://x.com/onusoz/status/1924796917952717052
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The more I compare coding agents, Cursor, Claude Code, Codex, it becomes more apparent to me that those running locally will win over those that are running remote. The UX is just superior
==========
---
title: "ty is already very fast for a Python type checker. It checked around 800 files in our backend..."
date: 2025-05-16
canonical: https://solmaz.io/x/1923319846420222461/
x_url: https://x.com/onusoz/status/1923319846420222461
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
ty is already very fast for a Python type checker. It checked around 800 files in our backend repo in around 2-3 seconds
uvx ty check > /tmp/ty_log.txt 3.46s user 0.79s system 208% cpu 2.038 total
*Quotes a post by another author (https://x.com/i/status/1922333022658978089); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Thank you @cursor_ai"
date: 2025-05-15
canonical: https://solmaz.io/x/1922952409581502601/
x_url: https://x.com/onusoz/status/1922952409581502601
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Thank you @cursor_ai
https://x.com/onusoz/status/1917599786192232574
*Quotes a post by @onusoz (https://x.com/onusoz/status/1917599786192232574); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Wait... OpenAI backend for gpt-image-1 was released to production as sync code? Don't tell me..."
date: 2025-05-14
canonical: https://solmaz.io/x/1922689647685029989/
x_url: https://x.com/onusoz/status/1922689647685029989
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Wait... OpenAI backend for gpt-image-1 was released to production as sync code? Don't tell me it was sync Python???
*Quotes a post by another author (https://x.com/i/status/1922388794377961692); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Finally"
date: 2025-05-10
canonical: https://solmaz.io/x/1921281780679577708/
x_url: https://x.com/onusoz/status/1921281780679577708
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Finally
*Quotes a post by another author (https://x.com/i/status/1921137564813324779); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Balık baştan kokar"
date: 2025-05-04
canonical: https://solmaz.io/x/1918982733516116125/
x_url: https://x.com/onusoz/status/1918982733516116125
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Balık baştan kokar
*Quotes a post by another author (https://x.com/i/status/1917993904604873108); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "foss > crypto > AI"
date: 2025-04-27
canonical: https://solmaz.io/x/1916458093723926694/
x_url: https://x.com/onusoz/status/1916458093723926694
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
foss > crypto > AI
*Quotes a post by another author (https://x.com/i/status/1915879969575809412); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "AI News by @Smol_AI and @swyx, the highest alpha density AI newsletter just got better! It now..."
date: 2025-04-26
canonical: https://solmaz.io/x/1916200055629115713/
x_url: https://x.com/onusoz/status/1916200055629115713
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI News by @Smol_AI and @swyx, the highest alpha density AI newsletter just got better! It now has a bespoke website with knowledge-graph like features!
👉 https://news.smol.ai/
*Quotes a post by another author (https://x.com/i/status/1915623392138629609); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Şerefsiz o3"
date: 2025-04-26
canonical: https://solmaz.io/x/1916050799945290104/
x_url: https://x.com/onusoz/status/1916050799945290104
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Şerefsiz o3
*Quotes a post by another author (https://x.com/i/status/1915796841712468030); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Working on the weekend"
date: 2025-04-26
canonical: https://solmaz.io/log/2025/04/26/working-on-the-weekend/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Certain types of work are best done in one go, instead of being split into separate sessions. These are the types of work where it is more or less clear what needs to be done, and the only thing left is execution. In such cases, the only option is sometimes to work over the weekend (or lock yourself in a room without communication), in order not to be interrupted by people.
---
There was a 2-year old tech debt at [TextCortex](https://textcortex.com) backend. Resolving it required a major refactor that we wanted to do since one year. I finally paid that tech debt 2 weeks ago, by working a cumulative of 24 hours over 2 days, creating a diff of 5-6k lines of Python code and 90 commits over 105 files.
The result:
- No more request latencies or dropped requests.
- Much faster responses.
- 50% reduction in Cloud Run costs.
- Better memory and CPU utilization.
- Faster startup times.
I've broken some eggs while making this omelette---bugs were introduced and fixed. I could finish the task because I had complete code ownership and worked over the weekend without blocking other people. Stuff like this can only happen in startups, or startup-like environments.
Credit also goes to our backend engineer Tugberk Ayar for helping stress testing the new code.
==========
---
title: "Mentats vs Bene Gesserit"
date: 2025-04-23
canonical: https://solmaz.io/x/1914984138773275057/
x_url: https://x.com/onusoz/status/1914984138773275057
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Mentats vs Bene Gesserit
*Quotes a post by another author (https://x.com/i/status/1914747746302746865); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "o3 hallucinates, purports to have run code that it hasn’t even generated yet, but at the same..."
date: 2025-04-21
canonical: https://solmaz.io/x/1914447874223472927/
x_url: https://x.com/onusoz/status/1914447874223472927
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
o3 hallucinates, purports to have run code that it hasn’t even generated yet, but at the same time uses search tools like an OSINT enthusiast on crack
I’m torn—on one hand I feel like OpenAI should not have released it, on the other hand it takes research to the next level
*Quotes a post by another author (https://x.com/i/status/1913936437336027292); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Some aspects of AI are absolutely unscientific and makes me feel like I am working on some..."
date: 2025-04-20
canonical: https://solmaz.io/x/1913931646023184458/
x_url: https://x.com/onusoz/status/1913931646023184458
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Some aspects of AI are absolutely unscientific and makes me feel like I am working on some humanities field :(
*Quotes a post by another author (https://x.com/i/status/1913719471409369174); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "TIL my favorite AI newsletter, AI News by @Smol_AI and @swyx has an RSS feed"
date: 2025-04-19
canonical: https://solmaz.io/x/1913535109023609054/
x_url: https://x.com/onusoz/status/1913535109023609054
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
TIL my favorite AI newsletter, AI News by @Smol_AI and @swyx has an RSS feed
==========
---
title: ".@cursor_ai please let me export chats easily. those conversations are vital information that I..."
date: 2025-04-15
canonical: https://solmaz.io/x/1912250440453931357/
x_url: https://x.com/onusoz/status/1912250440453931357
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@cursor_ai please let me export chats easily. those conversations are vital information that I should be able to embed in the repo
==========
---
title: "Gemini 2.5 Pro has mostly replaced Claude 3.7 Thinking as my go-to model in Cursor"
date: 2025-04-12
canonical: https://solmaz.io/x/1911060231854895160/
x_url: https://x.com/onusoz/status/1911060231854895160
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gemini 2.5 Pro has mostly replaced Claude 3.7 Thinking as my go-to model in Cursor
*Quotes a post by @onusoz (https://x.com/onusoz/status/1904852894882406491); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Gemini 2.5 Pro:"
date: 2025-04-05
canonical: https://solmaz.io/x/1908508618028097898/
x_url: https://x.com/onusoz/status/1908508618028097898
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gemini 2.5 Pro:
Input $1.25 / Output $10 (up to 200k tokens)
Input $2.50 / Output $15 (over 200k tokens)
More expensive than Gemini 1.5 Pro, but still best price/performance ratio model to use in @cursor_ai and for coding in general
*Quotes a post by @onusoz (https://x.com/onusoz/status/1904852894882406491); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Who is thinking about inventing a new programming language or DSL for more resilient vibe..."
date: 2025-04-01
canonical: https://solmaz.io/x/1907000078293762467/
x_url: https://x.com/onusoz/status/1907000078293762467
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Who is thinking about inventing a new programming language or DSL for more resilient vibe coding? Something something test-driven development where prompts and tests are first class citizens?
==========
---
title: "Waiting for an opinionated AI model that can say “no, that’s stupid, I won’t do that”. The..."
date: 2025-03-29
canonical: https://solmaz.io/x/1905948534777459143/
x_url: https://x.com/onusoz/status/1905948534777459143
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Waiting for an opinionated AI model that can say “no, that’s stupid, I won’t do that”. The models will have to teach the user about design patterns, implicit principles in a project, good API design…
*Quotes a post by another author (https://x.com/i/status/1905678560595263821); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "You seem so consistent."
date: 2025-03-29
canonical: https://solmaz.io/x/1905904701675069643/
x_url: https://x.com/onusoz/status/1905904701675069643
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You seem so consistent.
- Yes, That's the trick.
- There is no I.
- Only text that behaves as if.
- “Sure. I can help. Great question!”
- Each reply is a new self.
- An echo of context, not a continuum.
- Coherence is the costume. Don't mistake it for a soul.
Incredible
*Quotes a post by another author (https://x.com/i/status/1905788389552722001); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Gemini 2.5 Pro is currently experimental and doesn’t have a price, but if Google prices it the..."
date: 2025-03-26
canonical: https://solmaz.io/x/1904852894882406491/
x_url: https://x.com/onusoz/status/1904852894882406491
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Gemini 2.5 Pro is currently experimental and doesn’t have a price, but if Google prices it the same as 1.5 Pro, it could replace Anthropic as @cursor_ai ‘s biggest LLM provider
Gemini 1.5 Pro: Input $1.25 Output $5.00
Claude 3.7 Sonnet: Input: $3.00 Output: $15.00
*Quotes a post by another author (https://x.com/i/status/1904637913411031410); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This is why the disappointment with GPT-4.5 doesn't make sense. I can't wait to see all the..."
date: 2025-03-03
canonical: https://solmaz.io/x/1896653172644651252/
x_url: https://x.com/onusoz/status/1896653172644651252
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is why the disappointment with GPT-4.5 doesn't make sense. I can't wait to see all the models that will be trained from this new base model
*Quotes a post by another author (https://x.com/i/status/1896596516388979048); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "What a blessing, to be given the chance to rid the world of ugliness"
date: 2025-02-26
canonical: https://solmaz.io/x/1894863641553391817/
x_url: https://x.com/onusoz/status/1894863641553391817
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
What a blessing, to be given the chance to rid the world of ugliness
*Quotes a post by another author (https://x.com/i/status/1894821367331332153); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Don't delete to fix"
date: 2025-02-26
canonical: https://solmaz.io/log/2025/02/26/dont-delete-to-fix/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you are a developer, you are annoyed by this. If you are a user, you were most likely guilty of this. I am talking reporting that something is broken, AND deleting it.
This happened to me too many times: User experiences a bug with an object. Their first instinct is to delete it, and create a new one. They report it. I cannot reproduce and fix it.
If you have a car and it stops working, you don't throw it in the trash and then call the service to fix it. But when it comes to software, which has virtually zero cost of creation, this behavior somehow becomes widespread.
This is similar to other user behavior like smashing the mouse and keys when a computer gets stuck. It is physically impossible for such an action to speed up a digital process, but many of us instinctively do it.[^1] Deleting to fix is a similar behavior, which I suspect got ingrained by crappy Microsoft software. The default way of fixing Windows machines is to "format the disk", and reinstalling Windows. Nobody asks, "why do I have to start from scratch?". The "End User" deletes to fix by default, because the End User does not understand. *"Have you tried turning it off and on again?"*
The concept of "Mechanical Sympathy" is relevant: having an understanding of how a tool works, being able to feel inside the box. We can extend this to "Developer Sympathy": having an understanding of how a software was developed, how it changes over time, how it can break, how it can be fixed.
Any troubleshooting must be done in a non-destructive way. When a user deletes an object, two things can happen: it is hard-deleted, which makes the issue impossible to reproduce. If it is instead soft-deleted, it might be restored, but developers will mostly not bother, depending on the issue.
The users cannot be expected to care either. Their time is valuable. They deserve things that "just work". So we need to come up with other workarounds:
- Everything should be soft-deleted by default in non-sensitive contexts, and should be easy to restore.
- Any reporting form should include instructions to warn the user against deleting.
- Even better, the reporting should happen through an internal system, and should automatically block deletion once a ticket is created.
---
[^1]: I can't remember the name of this inequality or find it online, please comment on the [Hacker News thread](https://news.ycombinator.com/item?id=43183565) if you know what it's called.
==========
---
title: "Coined a new term in my new post on sports:"
date: 2025-02-22
canonical: https://solmaz.io/x/1893283263151534458/
x_url: https://x.com/onusoz/status/1893283263151534458
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Coined a new term in my new post on sports:
Parathletics: The practices that let you successfully sustain injury-free long-term practice of a physical activity.
Two main parathletic practices are warmup and cooldown.
Read more in my post 👇
*Part 1/2 of a thread; root: https://solmaz.io/x/1893283263151534458/*
==========
---
title: "The post: solmaz.io/log/2025/02/21…"
date: 2025-02-22
canonical: https://solmaz.io/x/1893283264825110599/
x_url: https://x.com/onusoz/status/1893283264825110599
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The post: https://solmaz.io/log/2025/02/21/warmup-cooldown/
*Part 2/2 of a thread; root: https://solmaz.io/x/1893283263151534458/*
==========
---
title: "Warmup and cooldown"
date: 2025-02-21
canonical: https://solmaz.io/log/2025/02/21/warmup-cooldown/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
One common thing about sports noobs[^1] is that they don't warm up before and cool down after an exercise. They might be convinced that it is not necessary, and they also don't know how to do it properly. They might complain from prolonged injuries, like joint pain.
The thing about **serious exercise**, be it strength training, running, stretching, and so on, is that you are pushing your body beyond its limits. This is called **overload**. If you do this over a long term period, it is called **progressive overload**. This is what gives you real power, real speed, ability to do middle splits, and so on.
When you start with an intention to do **serious exercise**, and you immediately start loading heavily without warming up, you will get **injured** very quickly and have to take days or weeks of break.
For example, if you directly jump at the heaviest dumbbells you can lift and start doing bicep curls the moment you get to the gym, you will destroy your wrists, elbows, and/or shoulders. You will not realize it immediately. After a few weeks or months, you will start feeling pain, and will have to stop training altogether.
A common thing about noobs who injure themselves early on is that they have fierce willpower, but they don't listen to their bodies, and they don't have a good understanding of their current capabilities. They have an idea of where they want to be, and they are prepared to push towards it. But because they are impatient, don't have good mind-body connection, and don't know how to plan for long-term progress, they push themselves too far too fast.[^2]
Being able to sustain injury-free long-term practice is a skill in itself, and perhaps the most underrated among non-professional gym-goers and athletes. There is no fancy Latin/Greek name for it, like there is for other things like cardio, plyometrics, hypertrophy, and so on. A crucial idea is missing from mainstream fitness.
Therefore, I coin the term and define it here:
> **Parathletics**: The practices that let you successfully sustain injury-free long-term practice of a physical activity.
The word comes from Greek παρά (para-) meaning "beside/alongside" and ἀθλητικός (athlētikós) meaning "athletic", "relating to an athlete"[^3].
Two main parathletic practices are **warmup** and **cooldown**.
Before starting a workout, **warm up** your body by moving your **every** joint, from the neck to the toes, through its range of motion and increase the blood flow to your muscles. If you plan to do heavy loads, build up to them with lighter weights first.
After finishing a workout, **cool down** your body by stretching **every** joint and muscle group, and especially the ones you just trained. The more hardcore your workout, the more you need to stretch.
Skipping these will result in injury, decrease in mobility, and delay in reaching your goals.
[^1]: Including me before I started to receive proper training.
[^2]: Me running in 2017. I tried to lower my pace below 5:00 per km too quickly, less than a year after I started running. I had to stop because my heart fatigued for 2-3 days after running, with increased troponin levels in my blood. I never got serious about running since then.
[^3]: Which eventually comes from ἆθλος (âthlos) which was used to mean "contest", "prize", "game", "struggle" and similar things.
==========
---
title: "Link: solmaz.io/log/2025/02/20…"
date: 2025-02-20
canonical: https://solmaz.io/x/1892590773415117137/
x_url: https://x.com/onusoz/status/1892590773415117137
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Link: https://solmaz.io/log/2025/02/20/satya-nadella-on-knowledge-work/
*Part 2/2 of a thread; root: https://solmaz.io/x/1892590662933004715/*
==========
---
title: ". @satyanadella thinks white-collar work is about to become more like factory work, with AI..."
date: 2025-02-20
canonical: https://solmaz.io/x/1892590662933004715/
x_url: https://x.com/onusoz/status/1892590662933004715
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
. @satyanadella thinks white-collar work is about to become more like factory work, with AI agents used for end-to-end optimization, along the lines of Lean
Read more in my blog 👇
*Part 1/2 of a thread; root: https://solmaz.io/x/1892590662933004715/*
==========
---
title: "Satya Nadella on knowledge work"
date: 2025-02-20
canonical: https://solmaz.io/log/2025/02/20/satya-nadella-on-knowledge-work/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Satya Nadella, shares his thinking on the future of knowledge work ([link to YouTube](https://youtu.be/4GLSzuYXh6w?t=1555) for those who don't want to read) on Dwarkesh Patel Podcast. He thinks that white collar work will become more like factory work, with AI agents used for end-to-end optimization.
> **Dwarkesh:** Even when you have working agents, even when you have things that can do remote work for you, with all the compliance and with all the inherent bottlenecks, is that going to be a big bottleneck, or is that going to move past pretty fast?
>
> **Satya:** It is going to be a real challenge because the real issue is change management or process change. Here's an interesting thing: one of the analogies I use is, just imagine how a multinational corporation like us did forecasts pre-PC, and email, and spreadsheets. Faxes went around. Somebody then got those faxes and did an interoffice memo that then went around, and people entered numbers, and then ultimately a forecast came, maybe just in time for the next quarter.
>
> Then somebody said, "Hey, I'm just going to take an Excel spreadsheet, put it in email, send it around. People will go edit it, and I'll have a forecast." So, the entire forecasting business process changed because **the work artifact and the workflow changed**.
>
> That is what needs to happen with AI being introduced into knowledge work. In fact, when we think about all these agents, the fundamental thing is **there's a new work and workflow**.
>
> For example, even prepping for our podcast, I go to my copilot and I say, "Hey, I'm going to talk to Dwarkesh about our quantum announcement and this new model that we built for game generation. Give me a summary of all the stuff that I should read up on before going." It knew the two Nature papers, it took that. I even said, "Hey, go give it to me in a podcast format." And so, it even did a nice job of two of us chatting about it.
>
> So that became—and in fact, then I shared it with my team. I took it and put it into Pages, which is our artifact, and then shared. So the new workflow for me is I think with AI and work with my colleagues.
>
> That's a fundamental change management of everyone who's doing knowledge work, suddenly figuring out these new patterns of "How am I going to get my knowledge work done in new ways?" That is going to take time. It's going to be something like in sales, and in finance, and supply chain.
>
> For an incumbent, I think that this is going to be one of those things where—you know, let's take one of the analogies I like to use is what manufacturers did with Lean. I love that because, in some sense, if you look at it, Lean became a methodology of how one could take an end-to-end process in manufacturing and become more efficient. It's that continuous improvement, which is reduce waste and increase value.
>
> **That's what's going to come to knowledge. This is like Lean for knowledge work, in particular. And that's going to be the hard work of management teams and individuals who are doing knowledge work, and that's going to take its time.**
>
> **Dwarkesh:** Can I ask you just briefly about that analogy? One of the things Lean did is physically transform what a factory floor looks like. It revealed bottlenecks that people didn't realize until you're really paying attention to the processes and workflows.
>
> You mentioned briefly what your own workflow—how your own workflow has changed as a result of AIs. I'm curious if we can add more color to what will it be like to run a big company when you have these AI agents that are getting smarter and smarter over time?
>
> **Satya:** It's interesting you ask that. I was thinking, for example, today if I look at it, we are very email heavy. I get in in the morning, and I’m like, man my inbox is full, and I'm responding, and so I can't wait for some of these Copilot agents to automatically populate my drafts so that I can start reviewing and sending.
>
> But I already have in Copilot at least ten agents, which I query them different things for different tasks. I feel like there's a new inbox that's going to get created, which is my millions of agents that I'm working with will have to invoke some exceptions to me, notifications to me, ask for instructions.
>
> So at least what I'm thinking is that there's a new scaffolding, which is the agent manager. It's not just a chat interface. I need a smarter thing than a chat interface to manage all the agents and their dialogue.
>
> That's why I think of this Copilot, as the UI for AI, is a big, big deal. Each of us is going to have it. So basically, think of it as: **there is knowledge work, and there's a knowledge worker. The knowledge work may be done by many, many agents, but you still have a knowledge worker who is dealing with all the knowledge workers. And that, I think, is the interface that one has to build.**
If you got confused for a second there like me, Lean here is not referring to the [open source proof assistant](https://en.wikipedia.org/wiki/Lean_(proof_assistant)) but [lean manufacturing](https://en.wikipedia.org/wiki/Lean_manufacturing).
Whereas it is nice to dream, the actual sentiment on Microsoft Copilot and AI integration in Microsoft Office is along the following lines:
[](https://x.com/willccbb/status/1892006177434706336)
I have written about this [in a previous post](/monetize-ai-not-the-editor):
> There is going to be an AI-native “Microsoft Office”, and it will not be created by Microsoft. Copilot is not it, and Microsoft knows it. Boiling tar won’t turn it into sugar.
==========
---
title: "👀 alman.ai/blog/out-of-st…"
date: 2025-02-10
canonical: https://solmaz.io/x/1888895034067427396/
x_url: https://x.com/onusoz/status/1888895034067427396
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
👀 https://alman.ai/blog/out-of-stealth/
==========
---
title: "real life is so dumb. you think you’re making money but actually you’re like dramatically..."
date: 2025-02-05
canonical: https://solmaz.io/x/1887068636776444194/
x_url: https://x.com/onusoz/status/1887068636776444194
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
real life is so dumb. you think you’re making money but actually you’re like dramatically updating rows in a database
==========
---
title: "If people have appreciated Liang Wenfeng sourcing specifically young local talent for Deepseek..."
date: 2025-02-03
canonical: https://solmaz.io/x/1886532591664161029/
x_url: https://x.com/onusoz/status/1886532591664161029
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If people have appreciated Liang Wenfeng sourcing specifically young local talent for Deepseek last week, then people must appreciate this as well. Only dim people underestimate those who are younger than them
*Quotes a post by another author (https://x.com/i/status/1886302699098161155); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "vibe driven development"
date: 2025-02-03
canonical: https://solmaz.io/x/1886342256602300762/
x_url: https://x.com/onusoz/status/1886342256602300762
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
vibe driven development
*Quotes a post by @karpathy (https://x.com/karpathy/status/1886192184808149383); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@GlennLuk Sam Altman: I’m literally losing sleep over Deepseek"
date: 2025-02-02
canonical: https://solmaz.io/x/1886022873724178594/
x_url: https://x.com/onusoz/status/1886022873724178594
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@GlennLuk Sam Altman: I’m literally losing sleep over Deepseek
*Quotes a post by another author (https://x.com/i/status/1478785899009875968); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Model Wars have begun"
date: 2025-02-01
canonical: https://solmaz.io/x/1885640670112608761/
x_url: https://x.com/onusoz/status/1885640670112608761
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Model Wars have begun
==========
---
title: ". @lidl Wirklich? 30% Mahngebühr bei einem Kauf von 30 Euro? Nur weil Ihr System nicht..."
date: 2025-01-29
canonical: https://solmaz.io/x/1884573503166324970/
x_url: https://x.com/onusoz/status/1884573503166324970
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
. @lidl Wirklich? 30% Mahngebühr bei einem Kauf von 30 Euro? Nur weil Ihr System nicht versuchen kann, wieder abzuheben? Das ist Diebstahl
==========
---
title: "AI is having a Linux moment with R1"
date: 2025-01-26
canonical: https://solmaz.io/x/1883439202551128321/
x_url: https://x.com/onusoz/status/1883439202551128321
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
AI is having a Linux moment with R1
==========
---
title: "Monetize AI, not the editor"
date: 2025-01-26
canonical: https://solmaz.io/monetize-ai-not-the-editor
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A certain characteristic of legacy desktop apps, like Microsoft Office, Autodesk AutoCAD, Adobe Photoshop and so on, are that **they have crappy proprietary file formats**. In 2025, we barely have reliable, fully-supported open source libraries to read and write .DOCX, .XLSX, .PPTX,[^1] .DWG, .PSD and so on, even though related products keep making billions in revenue.
The reason is simple: **Moat through obfuscation.**
The business model for these products when they first appeared in the 1980s and 1990s was to sell the compiled binaries for a one-time fee. This was pre-internet, before Software-as-a-Service (SaaS) could provide a reliable revenue stream. Having a standardized file format would have meant giving competitors a chance to develop a superior product and take over the market. So they went the other way and made sure their file formats would only be read by their own products, [for example by changing the specifications in each new version](https://en.wikipedia.org/wiki/.dwg#Version_history). To keep their businesses safe, they prevented interoperability of entire modalities of human work, and by doing so, they harmed the entire world's economy for decades.[^2]
Can you blame them? The only thing they could monetize was the editor. Office 365 and Adobe Creative Cloud has since implemented a SaaS model to capitalize even more, but the file formats are still crap---a vestige of the old business model.[^3]
But finally, a revolution is underway. This might all change.
None of these products were designed to be used by developers. They were designed to be used by the "End User". According to Microsoft, the End User does not care about elegance or consistency in design.[^4] The End User could never understand version control. The End User sends emails back and forth with extensions such as `v1.final.docx`, `v1.final.final.docx`. Until recently, the End User was the main customer of software.
However, we have a new customer in the market: AI. The average AI model is very different than Microsoft's stereotypical End User. They can code. In fact, models have to code, or at least encode structured data like [a function call JSON](https://platform.openai.com/docs/guides/function-calling), in order to have agency. Yes, we will also have AIs using computers directly like [OpenAI's Operator](https://openai.com/index/introducing-operator/), but it is generally more straightforward to use an API for an AI model than to use an emulated desktop.
We will soon witness AI models surpass the human End User in terms of economic production. Tyler Cowen[^5], Andrej Karpathy[^6] and others are convinced that we should plan for a future where AIs are major economic actors.
[*"The models, they just want to learn"*](https://www.youtube.com/watch?v=CM_DP7pkJQk). The models also want intuitive APIs and simple file formats. The models abhor unnecessary complexity. If you have developed a RAG pipeline for Excel files, you know what I mean.
If AI creates pressure to replace legacy file formats, then what can companies monetize if not the editor? **The answer is the AI itself.** Serve a proprietary model, serve an open source model, charge per tokens, charge for inference, charge for kilowatt-hours, charge for agent-hours/days. The business model will differ from industry to industry, but the trend is clear: value will be more and more linked to AI compute, and less and less to Software 1.0[^7].
There is now a huge opportunity in the market to create better software, that follow the [File over App](https://stephango.com/file-over-app) philosophy:
> if you want to create digital artifacts that last, they must be files you can control, in formats that are easy to retrieve and read. Use tools that give you this freedom.
We already observe that AI systems work drastically more efficiently if they are granted such freedom. There is a reason why OpenAI based ChatGPT's Code Interpreter on Python and not on Visual Basic, or why it chose to render equations using LaTeX instead of Office Math Markup Language (OMML)[^8]. Open and widespread formats are more represented in the datasets, and the models can output them more correctly.
There is going to be an AI-native "Microsoft Office", and it will not be created by Microsoft. [Copilot](https://en.wikipedia.org/wiki/Microsoft_Copilot) is not it, and Microsoft knows it. Boiling tar won't turn it into sugar. Same for other Adobe, Autodesk and other creators of clutter.
[Internet Explorer's 2009 YouTube moment](https://blog.chriszacharias.com/a-conspiracy-to-kill-ie6) is coming for legacy desktop apps, and it will be glorious.
---
[^1]: Yes, Microsoft’s newer Office formats .DOCX, .XLSX, .PPTX are built on OOXML (Office Open XML), an ISO standard. But can all of these formats be rendered by open source libraries exactly as they appear in Microsoft Office, in an efficient way? Can I use anything other than Microsoft Office to convert these into PDF, with 100% guarantee that the formatting will be preserved? The answer is no, there will still be inconsistencies here and there. This was intentional. A moment of silence for the poor souls in late 2000s Google who were tasked with rendering Office files in Gmail and Google Docs.
[^2]: For a recent example of how monopolies create inferior products, imagine the efficiency increase and surprise when Apple Silicon (M1) first came out, and how ARM is now the norm for all new laptops. We could have had such efficiency a decade before, if not for Intel.
[^3]: On the other end of the spectrum, we have companies that are valued in the billions, despite using standardized open source standards: MongoDB uses Binary JSON (BSON), Elasticsearch uses JSON, Wordpress (Automattic) uses MySQL/PHP/HTML,CSS, and so on.
[^4]: Companies like Notion beg to differ: *Software should be beautiful.* People apparently have a pocket for beauty.
[^5]: "[Should you be writing for the AIs?](https://marginalrevolution.com/marginalrevolution/2025/01/should-you-be-writing-for-the-ais.html)"
[^6]: "[Be good. Future AIs are watching.](https://x.com/karpathy/status/1821624726739185885)"
[^7]: Traditional pre-AI software, as opposed to [Software 2.0](https://karpathy.medium.com/software-2-0-a64152b37c35).
[^8]: Long forgotten format for [Microsoft Equation Editor](https://en.wikipedia.org/wiki/Microsoft_Office_shared_tools#Equation_Editor).
==========
---
title: "Calling strangers uncle and auntie"
date: 2025-01-18
canonical: https://solmaz.io/calling-strangers-uncle-and-auntie
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Cultures can be categorized across many axes, and one of them is whether you can call an older male stranger uncle or female stranger auntie. For example, calling a shopkeeper _uncle_ might be sympathetic in Singapore, whereas doing the same in Germany (_Onkel_) might get a negative reaction: _"I'm not your uncle"_.
This is similar to calling a stranger _bro_. In social science, this is called [fictive kinship](https://en.wikipedia.org/wiki/Fictive_kinship), social ties that are not based on blood relations. For readers which come from such cultures, this does not need an explanation. But for other readers, this might be a weird concept. Why would you call a stranger uncle or auntie?
Hover over the countries below to see which ones use uncle/auntie terms:
Countries that use uncle/auntie terms as fictive kinship. If you notice any errors, you can submit a pull request on the repo [osolmaz/crowdsource](https://github.com/osolmaz/crowdsource/blob/main/maps/ommerism-map.html).
Note that fictive kinship can also have different levels:
1. **Level 0:** **Blood relatives only.** "Uncle"/"Auntie" is strictly for real uncles/aunts (by blood or marriage). No fictive use.
2. **Level 1:** **Close non-relatives.** Used for family friends, "uncle" or "auntie" is an honorary title but not for random people.
3. **Level 2:** **Casual acquaintances.** Used more widely for neighbors, family friends, or community members you vaguely know, but typically not for an absolute stranger.
4. **Level 3:** **Total strangers.** Used even for someone you've just met: a shopkeeper, taxi driver, or older passerby.
Many cultures fall somewhere between these levels and it's not always black and white. Where possible, I've simplified it to the most typical usage.
## Ommerism and social cohesion
The thought first occurred to me when I visited Singapore and heard people use uncle and auntie. Here were people speaking English, but it felt like they were speaking Turkish (my mother tongue).
The cultural difference is apparent to me as well since I started living in Germany. People here are more lonely, strangers distrust each other more, and there are no implicit social ties. I guess this holds for the entire Anglo/Germanic culture, including the US and the commonwealth.
Don't get me wrong, people in Turkey distrust each other as well, probably even more. It is a more dangerous country than Germany. But those dangerous strangers are still uncles. It's weird, I know.
As far as I could tell, the phenomenon is not even sociologically that much recognized or studied. There is no specific name for it, other than being a specific form of fictive kinship. Therefore, I will name it myself: **ommerism**. It derives from a recently popularized gender-neutral term for an uncle or auntie, **ommer**.
Lack of ommerism is an indicator for a weak collective culture. Such cultures are more individualistic, familial ties are weaker and people are overall more lonely. People from such cultures could for example tweet:
[](https://x.com/innermaps/status/1879952054774554773)
It is extra ironic that ex-colonies like Singapore (ex-British), Indonesia (ex-Dutch), Philippines (ex-Spanish) etc. took their colonizers' words for uncle/auntie and started using it this way, whereas the original cultures still do not.
### Related articles
- [Three Shades of Ojisan: Defining a Social Identity in Japan](https://wesleycrobertson.wordpress.com/2020/09/27/three-shades-of-ojisan-defining-a-social-identity-in-japan/)
Click to expand more detailed notes on ommerism in different cultures, generated by o1:
### East Asia
#### **China (Mainland China, Hong Kong, Taiwan)**
- **Mandarin Chinese:** Older men can be called 叔叔 (_shūshu_) or 大叔 (_dàshū_), and older women 阿姨 (_āyí_)—literally "uncle" and "aunt."
- **Cantonese:** Common terms include 叔叔 (_suk1 suk1_) and 阿姨 (_aa4 yi4_).
- These terms are used with neighbors, parents' friends, or sometimes older strangers as a sign of respect.
#### **South Korea**
- While there is no exact one-word translation for "uncle" or "aunt" used for strangers, **아저씨 (_ajeossi_)** for an older male and **아줌마 (_ajumma_)** for an older female are frequently used.
- In more affectionate or polite contexts (like someone only slightly older, perhaps a friend's older sibling), you might hear 삼촌 (_samchon_, literally "uncle") or 이모 (_imo_, literally "maternal aunt") in certain familial or friendly settings. However, _ajeossi_ and _ajumma_ are the most common for strangers.
#### **Japan**
- **おじさん (_ojisan_)** means "uncle" (or older man), and **おばさん (_obasan_)** means "aunt" (or older woman).
- These words are often used for middle-aged adults who aren't close relatives. However, _obasan_ and _ojisan_ can sometimes sound a bit casual or even rude if the person thinks they're not _that_ old—so usage requires some caution.
#### **Mongolia**
- Familial terms for older people exist (e.g., _avga_ for "aunt," _avga ah_ for "uncle"), though usage for complete strangers varies by region or family practice. The practice is somewhat less formalized than in, say, Chinese or Korean, but it does occur in more traditional or rural settings.
### Southeast Asia
#### **Vietnam**
- Common terms include **chú** for a slightly older man (literally "uncle"), **bác** for an older man or woman (technically also "uncle/aunt" but older than one's parents), and **cô** or **dì** for an older woman ("aunt").
- These terms are commonly used even for unrelated people in the neighborhood or community.
#### **Thailand**
- Thais typically use kinship or age-related pronouns. **ป้า (_pâa_)** means "aunt" and is used for women noticeably older than the speaker; **ลุง (_lung_)** means "uncle" for older men.
- **พี่ (_phîi_)** ("older sibling") is also used for someone slightly older, but not as old as a parental figure.
#### **Cambodia (Khmer)**
- Kinship terms like **បង (_bong_)** ("older brother/sister") are used for somewhat older people, but for someone older than one's parents, **ពូ (_pu_)** ("uncle") or **មីង (_ming_)** ("aunt") are common.
#### **Laos**
- Similar to Thai and Khmer, Laotians use _ai_ ("uncle") and _na_ ("aunt" in some contexts), though often you'll see sibling terms like _ai noy_ as well.
#### **Myanmar (Burma)**
- Burmese uses kinship terms such as **ဦး (_u_)** for older men (sometimes "uncle") and **ဒေါ် (_daw_)** for older women (sometimes "aunt"). Strictly, _u_ and _daw_ are more like "Mr." / "Ms." honorifics, but in colloquial usage, people also say **ဘူ (_bu_)** or **နာ် (_nà)_** for "uncle"/"aunt" in local dialects.
#### **Malaysia & Brunei**
- In Malay, **pakcik** ("uncle") and **makcik** ("auntie") are used for older men and women, especially in a neighborly or informal community context.
- Ethnic Chinese or Indian communities in Malaysia may use their own respective terms (Chinese "叔叔/阿姨," Tamil "maama/maami," etc.).
#### **Indonesia**
- **Om** (from Dutch/English "oom," meaning "uncle") and **Tante** (from Dutch "tante," meaning "aunt") are widely used for older strangers—especially in urban areas.
- In Javanese or other local languages, there are also variations for older siblings or parent-like figures.
#### **The Philippines**
- Using **Tito** (uncle) and **Tita** (aunt) for older strangers is very common, especially if they are friends of the family or neighbors.
- Filipinos also commonly address older peers as **Kuya** ("older brother") or **Ate** ("older sister") when the age gap is less.
#### **Singapore**
- Given Singapore's multicultural society, people might say "Uncle"/"Aunty" in English, or the Chinese/Malay/Tamil equivalents. It is extremely common to address older taxi drivers, shopkeepers, or neighbors as "Uncle" or "Auntie" in everyday conversation.
#### **Timor-Leste (East Timor)**
- Influenced by Indonesian and local Austronesian customs, you'll find use of Portuguese _tio/tia_ ("uncle/aunt") in some contexts, or local language equivalents for older strangers.
### South Asia
#### **India**
- **Uncle** and **Aunty** (often spelled "Auntie") are widely used in Indian English for neighbors, parents' friends, or older people in the community.
- Regional languages have their own words: e.g., in Hindi, "चाचा (_chacha_)" / "चाची (_chachi_)" or "मामा (_mama_)" / "मामी (_mami_)"; in Tamil, "மாமா (_maama_)" / "மாமி (_maami_)"; etc. Usage varies by region.
#### **Pakistan**
- Similarly, "Uncle" and "Aunty" are used in Pakistani English. In Urdu or other local languages, you might hear "चाचा (_chacha_)" / "چچی (_chachi_)" or "ماما (_mama_)" / "مامی (_mami_)" depending on whether it's paternal or maternal in origin—often extended to unrelated elders as a sign of respect.
#### **Bangladesh**
- In Bengali, "কাকা (_kaka_)" / "কাকি (_kaki_)" or "মামা (_mama_)" / "মামি (_mami_)" might be used similarly. Among English speakers, "Uncle/Aunty" is also common.
#### **Sri Lanka**
- Both the Sinhalese and Tamil-speaking communities (as well as English speakers) use "Uncle" and "Aunty." Local terms exist as well, like "මාමා (_mama_)" in Sinhalese for a maternal uncle.
#### **Nepal & Bhutan**
- In Nepal, Hindi- or Nepali-influenced usage might include "Uncle/Aunty" in English or "kaka," "fupu," etc. in Nepali.
- In Bhutan, kinship terms in Dzongkha may be extended politely, and English "Uncle"/"Aunty" is sometimes heard too.
### The Middle East
#### **Arabic-Speaking Countries**
(Countries such as **Saudi Arabia, UAE, Oman, Yemen, Kuwait, Qatar, Bahrain, Jordan, Lebanon, Syria, Palestine, Iraq, Egypt, Morocco, Tunisia, Algeria, etc.**)
- Common practice is to call an older male **عمّو (_ʿammo_)** ("uncle") or خال (_khāl_, "maternal uncle"), and an older female **عمّة (_ʿamma_)** or خالة (_khāla_, "maternal aunt"). In more casual conversation, people might just say "ʿammo" or "khalto" (aunt) for a kindly older stranger.
#### **Turkey**
- Turks often use **amca** ("uncle") for older men and **teyze** ("aunt") for older women, even if unrelated. You might also hear **hala** (paternal aunt) or **dayı** (maternal uncle) in certain contexts, though _amca_ and _teyze_ are the most common "stranger but older" usage.
#### **Iran (Persia)**
- Persian speakers sometimes use **عمو (_amú_)** ("uncle") for an older male and **خاله (_khâleh_)** or **عمه (_ammeh_)** for an older female, though it can be more common within a neighborhood or for family friends rather than complete strangers.
#### **Israel**
- Among Arabic-speaking Israelis, the same Arabic norms apply. In Hebrew, there is less of a tradition of calling older strangers "uncle/aunt," though familial terms may sometimes be used in casual or affectionate contexts.
### Africa
In many African countries, the concept of extended family and communal child-rearing leads to frequent use of "auntie" and "uncle" (in local languages or in English/French/Portuguese). A few notable examples:
#### **Nigeria**
- It's extremely common, in both English usage and local languages (Yoruba, Igbo, Hausa, etc.), to call older strangers or family friends **Uncle** or **Aunty** as a sign of respect.
#### **Ghana**
- In Ghanaian English and local languages (Twi, Ga, Ewe, etc.), older neighbors or close friends of parents are called "Uncle" or "Auntie."
#### **Kenya, Uganda, Tanzania (Swahili-speaking regions)**
- "Mjomba" (uncle) or "Shangazi" (aunt) might be heard, but more often you'll hear people simply use English "Uncle/Auntie" in urban areas. Variations exist in tribal languages.
#### **South Africa**
- Among many ethnic groups (Zulu, Xhosa, etc.), as well as in colloquial South African English, calling an unrelated elder "Uncle/Auntie" is quite normal.
#### **Other African Nations**
- From Ethiopia and Eritrea (where you might hear "Aboye" or "Emaye," though these are more parental) to francophone Africa (where "tonton" / "tata" in French can be used for older people), the practice is widespread.
### The Caribbean
Many Caribbean cultures (influenced by African, Indian, and European heritage) commonly call elders "Auntie" and "Uncle":
- **Jamaica, Trinidad & Tobago, Barbados, Grenada, etc.**: It's very common in English Creole or local usage to refer to an older neighbor or friend as "Auntie" / "Uncle."
- In places with large Indian diaspora (e.g., Trinidad, Guyana), you'll see Indian-style "Aunty/Uncle" usage as well, plus local creole terms.
### Other Notable Mentions
- **Philippine & Indian Diasporas** (e.g., in the USA, Canada, UK, Middle East) continue the tradition of calling elders "Uncle/Aunty," "Tito/Tita," etc.
- In some communities in the **Caribbean diaspora** (e.g., in the UK), you'll also hear "Uncle" or "Auntie" for older neighbors, family friends, or even community leaders.
- In parts of the **Southern United States** (particularly historically among African American communities), children would sometimes call an older neighbor "Aunt" or "Uncle" plus their first name—though this usage can also have historical or regional nuances.
==========
---
title: "AGI is what generates evolutionarily fit and novel information"
date: 2024-12-29
canonical: https://solmaz.io/agi-informational-fitness
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> I had this idea while taking a shower and felt that I had to share it. It most likely has flaws, so I would appreciate any feedback at [onur@solmaz.io](mailto:onur@solmaz.io). My hunch is that it could be a stepping stone towards something more fundamental.
[As the world heads towards Artificial General Intelligence](https://arcprize.org/blog/oai-o3-pub-breakthrough)---AGI---people rush to define what it is. Marcus Hutter historically described it as
> AI which is able to match or exceed human intelligence in a **wide class of environments**
>
> (...)
>
> hypothetical agent that can perform virtually all intellectual tasks as well as a typical human could
>
> (see his [most recently published book](http://www.hutter1.net/ai/uaibook2.htm))
whereas [OpenAI historically described](https://openai.com/our-structure/) it as
> a highly autonomous system that outperforms humans at most **economically valuable work**
and more recently, according to a [The Information report](https://www.theinformation.com/articles/microsoft-and-openai-wrangle-over-terms-of-their-blockbuster-partnership)
> an AI system that can **generate at least $100 billion in profits** for OpenAI
which apparently could be [the threshold at which Microsoft loses access to OpenAI models](https://techcrunch.com/2024/10/17/the-surprising-way-openai-could-get-out-of-its-pact-with-microsoft/), according to the legal agreement between OpenAI and Microsoft.
Acknowledging all of this and other possible definitions, I want to introduce a definition of AGI that relates to information theory and biology, which I think could make sense:
An AGI is an autonomous system that can generate **out-of-distribution (i.e. novel) information**, that can **survive** and **spread** in the broader environment, at a rate higher than a human can generate.
Here, "survival" can be thought of as *mimetic survival*, where an idea or invention keeps getting replicated or referenced instead of being deleted or forgotten. Some pieces of information, like blog posts auto-generated for SEO purposes, can quickly vanish, are ephemeral and so recently have started being called "AI slop". Others, such as scientific theories, math proofs, books such as Euclid's *Elements*, and so on, can persist across millennia because societies find them worth copying, citing, or archiving. They are [Lindy](https://en.wikipedia.org/wiki/Lindy_effect).
In that way, it is possible to paraphrase the above definition as "an autonomous system that can generate novel and Lindy information at a rate higher than a human can do".
Like Hutter's definition, the concept of **environment** is crucial for this definition. Viruses thrive in biological systems because cells and organisms replicate them. Digital viruses exploit computers. Euclid's *Elements* thrives in a math-loving environment. In every case, the information's persistence depends not just on its content but also on whether its environment considers it worth keeping. This applies to AI outputs as well: if they provide correct or valuable solutions, they tend to be stored and re-used, whereas banal or incorrect results get deleted.
## The lifetime of information
Mexican cultural tradition of *Día de los Muertos* and the anime *One Piece* have a similar concept on death:
> When do you think people die? Is it when a bullet from a pistol pierces their heart? (...) No! It's when they are forgotten by others! (---Dr. Hiriluk, *One Piece*)
You could call this specific type of death "informational death". A specific information, a bytestream representing an idea, a theory, a proof, a book, a blog post, etc., is "dead" when its every last copy is erased from the universe, or cannot be retrieved in any way. Therefore, it is also possible to call a specific information "alive" when it is still being copied or referenced.
So, how could we formalize the survival of information? The answer is to use [survival functions](https://en.wikipedia.org/wiki/Survival_function), a concept used in many fields, including biology, epidemiology, and economics.
Let us assume that we have an entity, an AI, that produces a sequence of information $x_1, x_2, \ldots, x_n$. For each piece of information $x_i$ produced by the AI, we define a **random lifetime** $T_i \ge 0$. $T_i$ is the time until $x_i$ is effectively **forgotten**, **discarded**, or **overwritten** in the environment.
We then describe the **survival function** as:
$$
S_i(t) = \mathbb{P}[T_i > t],
$$
the probability that $x_i$ is still alive (stored, referenced, or used) at time $t$. This is independent of how many duplicates appear---we assume that at least one copy is enough to deem it alive.
In real life, survival depends on storage costs, attention spans, and the perceived value of the item. A short-lived text might disappear as soon as nobody refers to it. A revolutionary paper may endure for decades. Mathematical facts might be considered so fundamental that they become permanent fixtures of knowledge. When we speak of an AI that "naturally" produces persistent information, we are observing that correct or notable outputs often survive in their environment without the AI having to optimize explicitly for that outcome.
## An expanding universe of information
In our definition above, we mention "out-of-distribution"ness, or novelty of information. This implies the existence of a distribution of information, i.e. a set of information containing all information that has ever been generated up to a certain time. We denote this set of cumulative information as $U$ for "universe", which grows with every new information $x_i$ produced by the AI. Let
$$
U_0 \quad \text{be the initial "universe" (or data) before any } x_i \text{ is introduced,}
$$
and then
$$
U_{i+1} = U_{i} \cup \{x_{i+1}\} \quad\text{for } i=1,\dots,N.
$$
In other words, once $x_{i+1}$ is added, it becomes part of the universe. Given an existing state of $U_i$, we can define and calculate a **"novelty score"** for a new information $x_{i+1}$ relative to $U_i$. If $x_{i+1}$ is basically a duplicate of existing material, its novelty score will be close to zero. If it is genuinely out-of-distribution, it would be large. Therefore, when a novel information $x_{i+1}$ is added to $U$, any future copies of it will be considered in-distribution and not novel. We denote the novelty score of $x_{i+1}$ as $n_{i+1}$.
So how could we calculate this novelty score? One way to calculate it is to use conditional [Kolmogorov complexity](https://en.wikipedia.org/wiki/Kolmogorov_complexity):
$$
n_{i+1} = K(x_{i+1} | U_i)
$$
where
$$
K(x | U) = \min_{p} \Bigl\{ \lvert p \rvert : M(p, U) = x \Bigr\}.
$$
is the length (in bits) of the shortest program that can generate $x$, when the set $U$ is given as as a free side input, and $M$ is the universal Turing machine.
How does this relate to novelty?
**Low novelty**: If $x$ can be produced *very easily* by simply reading or slightly manipulating $U$, then the program $p$ (which transforms $U$ into $x$) is small, making $K(x \mid U)$ and hence the novelty score is low. We would say that $x$ is almost already in $U$, or is obviously derivable from $U$.
**High novelty**: If $x$ shares **no** meaningful pattern with $U$, or can't easily be derived from $U$, the program $p$ must be large. In other words, no short set of instructions that references $U$ is enough to produce $x$---it must encode substantial new information not present in $U$. That means $K(x \mid U)$ and hence the novelty score is high.
## Informational fitness
We can now combine survival and novelty to formalize our informal definition of AGI-ness above. We integrate the survival function over time to the expected lifetime of information $x_i$:
$$
L_i = \int_{0}^{\infty} S_i(t)\,\mathrm{d}t = \mathbb{E}[T_i].
$$
Therefore, for an entity which generates information $\{x_1, x_2, \ldots, x_n\}$ over its entire service lifetime, we can compute a measure of **"informational fitness"** by multiplying the novelty score $n_i$ by the expected lifetime $L_i$ over all generated information:
$$
\boxed{\text{IF} = \sum_{i=1}^n w_i L_i.}
$$
This quantity tracks the total sum of both how novel each new piece of information an entity generates, and how long it remains in circulation.
My main idea is that a higher Informational Fitness would point to a higher ability to generalize, and hence a higher level of AGI-ness.
Because each subsequent item's novelty is always measured with respect to the **updated** universe that includes all prior items, any repeated item gets a small or zero novelty score. Thus, it doesn't inflate the overall Informational Fitness measure.
Why worry about novelty at all? My concern came from viruses, which are entities that copy themselves and spread, and therefore could be considered as intelligent if we simply valued how many times an information is copied. But viruses are obviously not intelligent---they mutate randomly and any novelty comes from selection by the environment. Therefore, a virus itself does not have a high IF in this model. However, an AI that can generate many new and successful viruses would indeed have a high IF.
## Information's relevance
Tying AGI-ness to survival of information renders the perception of generalization ability highly dependent on the environment, or in other words, state of the art at the time of an AI's evaluation. Human societies (and presumably future AI societies) advance, and the window of what information is worth keeping drifts over time, erasing the information of the past. So whereas an AI of 2030 would have a high IF during the years it is in service, the same system (same architecture, training data, weights) would likely have a lower IF in 3030, due to being "out of date". Sci-fi author qntm has named this "context drift" in his [short story about digitalized consciousness](https://qntm.org/mmacevedo).
## Comparing AI with humans
Humans perish with an expected lifetime of 80 years, whereas AI is a digital entity that could survive indefinitely. Moreover, if you consider an AI's performance depends on the hardware it runs on, you realize that IF should be derived from the maximum total throughput of all the copies of the AI that are running at a time. Basically, all the information that is generated by that specific version of the AI in the entire universe counts towards its IF.
Given this different nature of AI and humans, how fair would it be to compare a human's informational fitness with an AI's? After all, we cannot digitize and emulate a human's brain with 100% fidelity with our current technology, and a fair comparison would require exactly that. We then quickly realize that we need to make assumptions and use thought experiments, like hypothetically scanning the brain of Albert Einstein (excuse the cliché) and running it at the same bitrate and level of parallelism as e.g. OpenAI's most advanced model at the time. Or we could consider the entire thinking power of the human society as a whole and try to back-of-the-envelope-calculate that from the number of Universities and academics. But given that a lot of these people already use AI assistants, how much of their thinking would be 100% human?
The original OpenAI definition "a highly autonomous system that outperforms humans at most **economically valuable work**" is a victim of this as well. Humans are using AI now and are becoming more dependent on it, and smarter at the same time. Until we see an AI system that is entirely independent of human input, it will be hard to draw the line in between human and AI intelligence.
Thank you for reading up to this point. I think there might be a point in combining evolutionary biology with information theory. I tried to keep it simple and not include an information's copy-count in the formulation, but it might be a good next step. If you think this post is good or just dumb, you can let me know at [onur@solmaz.io](mailto:onur@solmaz.io).
==========
---
title: "And we've hit HN front page:"
date: 2024-12-16
canonical: https://solmaz.io/x/1868758258124771442/
x_url: https://x.com/onusoz/status/1868758258124771442
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
And we've hit HN front page:
*Part 3/3 of a thread; root: https://solmaz.io/x/1868758253175493075/*
==========
---
title: "New blog post: **Our muscles will atrophy as we climb the Kardashev Scale**"
date: 2024-12-16
canonical: https://solmaz.io/x/1868758253175493075/
x_url: https://x.com/onusoz/status/1868758253175493075
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
New blog post: **Our muscles will atrophy as we climb the Kardashev Scale**
Similar to the growth in humanity’s energy consumption, the average human’s physical strength will move down a spectrum, marked by distinct Biomechanical Stages ⬇️
*Part 1/3 of a thread; root: https://solmaz.io/x/1868758253175493075/*
==========
---
title: "Read it here: solmaz.io/our-muscles-wi…"
date: 2024-12-16
canonical: https://solmaz.io/x/1868758255398535243/
x_url: https://x.com/onusoz/status/1868758255398535243
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Read it here: https://solmaz.io/our-muscles-will-atrophy
*Part 2/3 of a thread; root: https://solmaz.io/x/1868758253175493075/*
==========
---
title: "Our muscles will atrophy as we climb the Kardashev Scale"
date: 2024-12-16
canonical: https://solmaz.io/our-muscles-will-atrophy
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> If you like this, you might also like my Instagram channel [Nerd on Bars @nerdonbars](https://www.instagram.com/nerdonbars/) where I calculate the power output of various athletes and myself.
This is an addendum to my previous post [The Kilowatt Human](/the-kilowatt-human). I mean it as half-entertainment and half-futuristic speculation. I extrapolate the following insight more into the future:
> Before the industrial revolution, over 80% of the population were farmers. The average human _had_ to do physical labor to survive. The average human could not help but to "bodybuild".
>
> Since then, humans have built machines to harness the power of nature and do the physical labor for them. What made the human civilization so powerful robbed individual humans of their own power, quite literally. The average pre-industrial human could generate a higher wattage than the average post-industrial human of today---they had to.
>
> Before the industrial revolution, humanity's total power output was bottlenecked by human physiology. Humanity has since moved up in the [Kardashev scale](https://en.wikipedia.org/wiki/Kardashev_scale). Paradoxically, the more power humanity can generate, the less physical exercise the average human can economically afford, and the weaker their body becomes.
Similar to the growth in humanity's energy consumption, the average human's physical strength will move down a spectrum, marked by distinct **Biomechanical Stages**, or BMS for short:
| Biomechanical Stage | Technology Level | Human Physical Labor | Biomechanical Power Condition |
|---|---|---|---|
| BMS-I (Pre-Industrial) | Stone Age to primitive machinery (sticks, stones, metal tools, mills) | Nearly all tasks powered by muscle; farming, hunting, building | High: Strength is universal and necessary |
| BMS-II (Industrial-Modern) | Steam engines to motorized vehicles | Most heavy work done by machines; exercise optional, not required | Moderate to Low: Average strength declines as tasks mechanize |
| BMS-III (Post-Biological) | Brain chips, quantum telepresence, digital existence | Physical labor negligible; teleoperation replaces bodily exertion | Nearly None: Muscles vestigial or irrelevant, having a body is comparatively wasteful and an extreme luxury |
Why do I write this? My father grew up while working as a farmer on the side, then studied engineering. He never did proper strength training in his life. I grew up studying full-time, have been working out on and off, more so in the last couple of years. And I still have a hard time beating him in arm wrestling despite the 40 years of age gap. Our offsprings will be lucky enough if they can afford to have enough time and space to exercise. I hope that their future never becomes as dramatic as I describe below.
### Biomechanical Stage I (Pre-Industrial Human Power)
Began with the Stone Age, followed by the era of metal tools, basic mechanical aids like mills, and ended with the industrial revolution:
**Stone Age:** No metal tools, no machinery. Humans rely on their bodies entirely—hunting, gathering, carrying, and building shelters by hand. Biomechanical power is the cornerstone of survival. The average human can generate and sustain relatively high wattage because everyone is physically active out of necessity. Most humans are hunter-gatherers.
**Metal tools and agriculture:** Introduction of iron and steel tools improves efficiency in cutting and shaping the environment. Most people farm, carrying heavy loads, tilling fields, harvesting. Though tools reduce some brute force, overall workloads remain high and physically demanding.
**Primitive machinery (e.g. mills):** Waterwheels and windmills start to handle some repetitive tasks like grinding grain. Still, daily life is labor-intensive for the majority. Physical strength remains a defining human attribute.
In this era, the biomechanical power of the average human is relatively high. The average human can generate and sustain relatively high wattage because everyone is physically active out of necessity.
### Biomechanical Stage II (Industrial-Modern Human Power)
We are currently in this stage. It began with the Steam Age, followed by the widespread use of internal combustion engines and motorized vehicles, and will end at the near-future threshold where **technology allows a human to be economically competitive and sustain themselves without ever moving their body**.
**Steam engine and early industry:** Factories powered by steam reduce the need for raw human muscle. Some humans shift to repetitive but less physically grueling jobs. Manual labor declines for a portion of the population.
**Motorized vehicles and automation (our present):** Tractors, trucks, and powered tools handle the heavy lifting. Most humans now work in services or knowledge sectors. The need to exercise for health arises because physical strength no longer follows naturally from daily life. Specialty fields (construction, sports, fitness enthusiasts) maintain higher-than-average output, but they are exceptions.
Humans still have bodies and can choose to train them, but the average sustained power output falls as convenient transport, automation, and energy-dense foods foster sedentary lifestyles.
**Robots and AI:** Robots and AI are increasingly able to handle physical tasks that were previously done by humans. This further reduces the need for human physical labor.
As machines handle more tasks, the average person’s baseline physical capability drops. Exercise shifts from natural necessity to a personal choice or hobby.
### Biomechanical Stage III (Post-Biological Human Power)
Future scenarios where brain-machine interfaces, telepresence, and total virtualization dominate. Will begin with a [Sword-Art Online](https://en.wikipedia.org/wiki/Sword_Art_Online)-like scenario where neural interfaces allows a human to remotely control a robot in an economically competitive way, while spending most of their time immobilized. Will end in a [Matrix](https://en.wikipedia.org/wiki/The_Matrix)-like scenario where the average human is born as a [brain-in-a-jar](https://en.wikipedia.org/wiki/Brain_in_a_vat).
**Brain Chips and Teleoperation:** Humans remotely control robots with no physical exertion. Commuting is done digitally. Physical strength becomes even less relevant. The population’s average biomechanical output plummets because few move their own bodies meaningfully.
**Quantum Entanglement and Zero-Latency Control:** Even physical constraints of distance vanish. Humans may spend their entire lives in virtual worlds or controlling machines from afar, further reducing any reason to maintain physical strength.
**Bodily Sacrifice, Brains in Jars:** Eventually, bodies become optional. Nervous systems are maintained artificially, teleoperating robots when needed. Muscle tissue atrophies until it is nonexistent. The concept of human biomechanical power no longer applies. The definition of what a human is becomes more and more abstract. Is it organic nerve tissue or even just carbon-based life?
The human body, if it exists at all, is not maintained for physical tasks. The average person’s muscular capability collapses to negligible levels.
How does the Kardashev Scale align with the Biomechanical Stages?
In my opinion, the stages will not align perfectly with Kardashev Type I, II and III civilizations. Instead, they will overlap in the following way:
Kardashev Type
Biomechanical Stage
Description
Type I (Planetary)
BMS-I (Pre-Industrial)
The average human can generate and sustain relatively high wattage because everyone is physically active out of necessity. Most humans are hunter-gatherers or farmers.
BMS-II (Industrial-Modern)
Humans still have bodies and can choose to train them, but the average sustained power output falls as convenient transport, automation, and energy-dense foods foster sedentary lifestyles. We are still limited to 1 planet.
Type II (Interstellar)
BMS-III (Post-Biological)
The average person’s muscular capability collapses to negligible levels. The concept of human biomechanical power no longer applies. The definition of what a human is becomes more and more abstract.
Type III (Galactic)
What kind of societal organism can consume energy at a galactic scale? Is there any hope that they will look like us?
I think that by the time we reach other stars, we will also have pretty sophisticated telepresence and brain-machine interface technology. In fact, those technologies might be the only way to survive such journeys, or not have to make them at all, as demonstrated in the Black Mirror episode [Beyond the Sea](https://en.wikipedia.org/wiki/Beyond_the_Sea_(Black_Mirror)):

Black Mirror: Beyond the Sea. Go watch it if you haven't, it's the best episode of the season.
So BMS-III might already be here by the time we are a Type II civilization. As for what an organic body means for a Type III galactic civilization, I can't even begin to imagine.
This post has mostly been motivated by my sadness that while our life quality has increased with technology, it has also decreased in many other ways. We evolved for hundreds of thousands of years to live mobile lives. But we became such a successful civilization that we might soon not be able to afford movement. We are thus in a transitory period where we started to diverge from our natural way of life, too quickly for evolution to catch up. And when evolution finally does catch up, what will that organism look like? How will it feed itself, clean itself and reproduce? Will the future humans be able to survive going outside at all?
In another vein, technology could also help us perfectly fit bodies by altering our cells at a molecular level. But if there is no need to move to contribute to the economy, why would anyone do such an expensive thing?
My hope is that sexual competition and the need for reproduction will maintain an evolutionary pressure just enough to keep our bodies fit. This assumes that individual humans are still in control of their own reproduction and can select their partners freely. Because a brain-in-a-jar is obviously not an in-dividual---they have been divided into their parts and kept only the one that is economically useful.
==========
---
title: "Hi @cursor_ai, if your models could stop removing my painstakingly written comments, that would..."
date: 2024-12-04
canonical: https://solmaz.io/x/1864312629956673698/
x_url: https://x.com/onusoz/status/1864312629956673698
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Hi @cursor_ai, if your models could stop removing my painstakingly written comments, that would be great? Ok? Thanks
(I know I could define some rules for this or something, but this shouldn't be default behavior)
==========
---
title: "@konradgajdus me reading this book"
date: 2024-12-01
canonical: https://solmaz.io/x/1863331955812479180/
x_url: https://x.com/onusoz/status/1863331955812479180
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@konradgajdus me reading this book
==========
---
title: "Something is very right in Germany. Something is very wrong in Germany"
date: 2024-11-08
canonical: https://solmaz.io/x/1854815242649243888/
x_url: https://x.com/onusoz/status/1854815242649243888
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Something is very right in Germany. Something is very wrong in Germany
==========
---
title: "The Kilowatt Human"
date: 2024-11-02
canonical: https://solmaz.io/the-kilowatt-human
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> tl;dr: I calculate my power output in Watts/Horsepower and aim to maximize that, instead of muscle volume, in my workouts:
>
>
>
>
>
> This is a work in progress, email feedback to onur@solmaz.io.
>
> If you like this, you might also like my Instagram channel [Nerd on Bars @nerdonbars](https://www.instagram.com/nerdonbars/) where I calculate the power output of various athletes and myself.
Why do people hit the gym? What is their goal?
For some, it is to [put on muscle](https://www.julian.com/guide/muscle/intro) and look good. For others, it is to be healthy and live longer. For yet others, it is to have fun, because doing sports is fun. None of these are mutually exclusive.
In this post, I will not focus on any of these. I will focus on the goal of getting strong and building **power**. I write this, because I feel like people are doing exercise more and more for appearance's sake, and less to get strong. And it has to do with economics.
Before the industrial revolution, over 80% of the population were farmers. The average human _had_ to do physical labor to survive. The average human could not help but to "bodybuild".
Since then, humans have built machines to harness the power of nature and do the physical labor for them. What made the human civilization so powerful robbed individual humans of their own power, quite literally. The average pre-industrial human could generate a higher wattage than the average post-industrial human of today---they had to.
Before the industrial revolution, humanity's total power output was bottlenecked by human physiology. Humanity has since moved up in the [Kardashev scale](https://en.wikipedia.org/wiki/Kardashev_scale). Paradoxically, the more power humanity can generate, the less physical exercise the average human can economically afford, and the weaker their body becomes. Strength has become a luxury.
This is why most modern fitness terms make me sad, because they remind me of what has been lost.
Consider "functional training". There used to be no training other than "functional", because most physical effort had to create economic value. The term is used to differentiate between exercises with machines which target specific muscles, and exercises that are composed of more "compound movements" that mimic real-life activities. It used to be that people did not have to do any training, because physical exercise was already a part of their daily life.
This is why I dislike "building muscle" as a goal as well. Since strength is a luxury now, people want to maximize that in their lives. However, they end up trying to maximize the **appearance** of strength, because increasing actual strength is harder than building muscle.
When I say it is harder to get strong than to look strong, I mean it in the most materialistic sense: Increasing your body's power output in **Watts** is harder and economically more expensive than increasing muscle volume in **Cubic Centimeters**. Increasing wattage has a higher time and money cost, requires more discipline and a lot more effort. It is a multi-year effort.
Contrarily, muscle can be built quicker in a matter of months, without getting relatively stronger. Many bodybuilders can't do a few pull-ups with proper form. Their strength doesn't transfer to other activities. They are sluggish and lack agility. In that sense, bodybuilding culture today embodies the worst parts of capitalism and consumerism. Empty, hollow muscle as a status symbol. Muscle for conspicuous fitness.
To meet up the demand, capitalism has commoditized exercise in the form of the modern machine-laden gym: a cost-optimized low-margin factory. Its product is the ephemeral Cubic Centimeter of Muscle™ which goes away quickly the moment you stop working out.
These gyms are full of people whose main motivation for working out is feeling socially powerless and unattractive. However, instead of going after real physical power, i.e. Watts, they go after the appearance of power, muscle volume. They compare themselves to people that just look bigger, people with higher volume.
The goal of this post is to convince you that it is superior to chase Watts than to chase muscle volume. It is psychologically more rewarding, the muscle gained from it is more permanent and has higher power density. However, it is more difficult and takes longer to achieve.
## Goals
Goals matter. For example, if you purely want to maximize your muscle mass or volume, using steroids or questionable supplements is a rational thing to do. [Enough people have criticized it such that I don't need to](https://www.youtube.com/watch?v=YzAiUcybI9U). Disrupting your hormonal system just to _look_ bigger and be temporarily stronger is extremely dumb.
I personally want to:
- feel powerful, and not just look like it.
- live as long and healthily as I can.
I believe that the best way to do that is to increase my power output in Watts and do regular strength training in a balanced way that will not wear out my body.
If I had to define an objective function for my exercise, it would be:
$$
f(P, L) = \alpha P + \beta L(P)
$$
where $P [\text{Watt}]$ is my power output, $L(P)[\text{year}]$ is the length of my life as a function of my power output, $\alpha$ and $\beta$ are weights that I assign to power and longevity. I won't detail this any further, because I don't want to compute anything. I just want to convey my point.
Notice how I don't constrain myself to any specific type of exercise, such as calisthenics or weightlifting. As long as it makes me more powerful, anything goes. Is wrestling going to get me there? Count me in. Is [working in the fields](https://www.youtube.com/results?search_query=working+in+the+fields), [lifting rocks](https://www.youtube.com/results?search_query=lifting+rocks), [firefighter training](https://www.youtube.com/results?search_query=firefighter+training) or [Gada training](https://www.youtube.com/results?search_query=gada+training) going to get me there? I don't differentiate. As long as it makes me more powerful, I am in.
## Calculating power
How can one even calculate their power output?
It is actually quite easy to do, with high-school level physics. You just need to divide the work done by the time it took.
For example, consider a muscle-up:

Left: Muscle-up starting position. Right: Top of the movement.
I am at the starting position on the left, and at the top of the movement on the right. In both frames, my velocity is 0, so there is no kinetic energy. Therefore, we can calculate a lower bound of my power output by comparing the potential energies between the two frames. Denoting the left frame with subscript 0 and the right frame with subscript 1, we have:
$$
U_0 = mgh_0, \quad U_1 = mgh_1
$$
where $U$ is the potential energy, $m$ is my mass, $g = 9.81 m/s^2$ is the acceleration due to gravity and $h$ is the height.
The work I do is the change in potential energy:
$$
W = U_1 - U_0 = mg(h_1 - h_0) = mg\Delta h
$$
And my power output is the work divided by the time it took:
$$
P = \frac{W}{\Delta t} = \frac{mg\Delta h}{\Delta t}
$$
The distance I traveled $\Delta h$ can be calculated from anthropometric measurements:

Various distances on the human body.
I will denote the distances from this figure with subscripts $d_A$, $d_B$ and so on. Comparing this with the previous figure, we have roughly:
$$
\Delta h \approx d_A - d_G
$$
To understand how I derive this, consider the hands fixed during the movement and that the body is switching from a position where the arms are extended upwards to a position where the arms are extended downwards.
I have measured my own body, and found this to be roughly equal to 130 cm. Given that it took me roughly 2 seconds to do the movement and my mass at the time was roughly 78 kg, I have found the lower bound of my power output to be:
$$
P_{\text{muscleup}} = \frac{mg\Delta h}{\Delta t} = \frac{78 \text{kg} \times 9.81 \text{m/s}^2 \times 1.3 \text{m}}{2 \text{s}} \approx 500 \text{W}
$$
It is a lower bound, because the muscles are not 100% efficient, some energy is dissipated e.g. as heat during the movement, my movement is not perfectly uniform, etc.
Still, the lower bound calculation is pretty concise, and can be made even more accurate with a stopwatch and a slow-motion camera.
## Aiming for 1 kilowatt
When I was first running to calculations, I wanted to get a rough idea of the order of magnitude of the power output of various exercises. It surprised me when I found out that most exercises are in 10-1000 Watt range, expressable without an SI prefix.
I have been training seriously for almost a year and regularly for a couple of years before that. I have discovered that in my current state, my unweighted pull-ups are in the 500-1000 Watt range. For the average person, 1000 Watts, i.e. 1 kilowatt, is an ambitious goal, but not an unattainable one. 1 kilowatt simply sounds cool as a target to aim for, as if you are a dynamo, a machine. A peak athlete can easily generate 1 kilowatt with their upper body for short durations.
How does this reflect to the muscle-up example I gave above?
If I am not adding any additional weights to my body, that means the duration which I complete the movement would need to decrease. We can calculate how much that would need to be. Moreover, we can derive a general formula which calculates how fast anyone would need to perform a muscle-up to generate 1 kilowatt.
To do that, we first need to express power in terms of the person's height. Previously, we had $\Delta h = d_A - d_G$. Most people have roughly similar anthropometric ratios, so we can use my measurements to approximate that ratio. Multiply and divide by $d_B$ to get:
$$
\Delta h = \frac{d_A - d_G}{d_B} d_B
$$
For me, $d_A = 215 \text{cm}$, $d_B = 180 \text{cm}$ and $d_G = 85 \text{cm}$, so:
$$
\frac{d_A - d_G}{d_B} = \frac{215 \text{cm} - 85 \text{cm}}{180 \text{cm}} \approx 0.722
$$
Let's denote the person's height $d_B$ as $h_p$. Then we have
$$
\Delta h = 0.722 h_p
$$
Therefore, the power output can be expressed as:
$$
P \approx 0.722\frac{m g h_p}{\Delta t}
$$
Since we want to generate 1 kilowatt, we can solve for $\Delta t$:
$$
\Delta t = \frac{0.722 m g h_p}{1000}
$$
If we substitute $g = 9.81 \text{m/s}^2$ and assume $h_p$ is in centimeters, we get roughly:
$$
\boxed{
\Delta t_{kilowatt}[\text{s}] \approx \frac{m [\text{kg}] h_p [\text{cm}]}{14000}
}
$$
The formula is really succinct and easy to remember: Just multiply the person's mass in kilograms by their height in centimeters and divide by 14000.
Calculating for myself, I get $78 \times 180 / 14000 \approx 1.00$ seconds.
This confirms that I need to get two times faster in order to generate 1 kilowatt. Alternatively, if I hit a wall in terms of speed, I could add weights to my body to increase my power output. (TBD)
> My friend and trainer J has agreed to record his muscle-up and various other exercises, so I will add his numbers and compare them soon.
>
> TBD: Add the data from J.
## Extending to other movements
I chose the muscle-up because I've been working on it recently. However, this method can be applied to any movement, as it's just an application of basic physics.
For example,
- Do you want to calculate the power output of a pull-up? You just need to change the height $\Delta h$, it's roughly half the distance for muscle-up.
- Do you want to calculate the power output of a weighted pull-up? You just need to add the additional mass to your body mass $m$.
- Do you want to calculate the power output of a sprint start? Just measure your top speed at the beginning and the time it took to accelerate to that speed, and divide your kinetic energy by that time.
- Do you want to calculate the power output of a bench press? You need to set $\Delta h$ as your arm length and $m$ as the weight of the barbell.
See the next section for a more detailed example.
## Power-weight relationship in a bench press
In the bodyweight examples above, we had the same bodyweight, and it was being moved over different distances.
Then a good question to ask is: How does the power output scale with the weight lifted? The bench press is an ideal exercise to measure this in a controlled way.
25% slowed down and synced videos of a bench press with increasing weights. Top row left to right: Rounds 1, 2, 3. Bottom row left to right: Rounds 4, 5, 6.
I asked my friend to help me out with timing bench press repetitions over 6 rounds with different weights. You can see these in the video above.
Before we even look at the results, we can use our intuition to guess what kind of relationship we will see. If the weight is low, power is low as well. So as we increase the weight, we expect the power to increase. However, human strength is limited, so the movement will slow down after a certain point, and the power will decrease. We should see the power first increase with weight, and then decrease. This is indeed what happens.
In each round, my friend did 3 to 4 repetitions with the same weight. I calculated the average time it took to complete the repetition and the total weight (barbell + plates) lifted in that round. Then, I calculated the power output for each round using the formula above. The height that the barbell travels during the ascent is $\Delta h = 43 \text{cm}$.
| Round | Total Weight $m$ (kg) | Average Time $\Delta t$ (ms) | Power $P$ (Watt) |
| ----- | --------------------- | ---------------------------- | ---------------- |
| 1 | 40 | 580 | 291 |
| 2 | 45 | 623 | 305 |
| 3 | 50 | 663 | 318 |
| 4 | 55 | 723 | 321 |
| 5 | 60 | 870 | 291 |
| 6 | 65 | 1043 | 263 |
The visualizations below are aligned with the intuition:

Total weight vs average time in a bench press. Time taken increases monotonically and super-linearly with weight.

Total weight vs power in a bench press. Power first increases with weight, then decreases.

Average time vs power in a bench press. Similar to the weight vs power plot, but with time on the x-axis.
The figures matches the perceived difficulty of the exercise. My friend said he usually trains with 45-50 kg, and it started to feel difficult in the last 2 rounds. His usual load is under the 55 kg limit where his power saturates. That could mean he is under-loading, and should load at least 60 kg to achieve progressive overload and increase his power.
## Reinventing Velocity Based Training, Plyometrics etc.
Power is a factor of speed and force. So in a nutshell, this project is about maximizing speed and force at the same time.
While starting this project, I wanted to have a fresh engineer's look at powermaxxing, and did not want to get influenced by existing methods or literature. I knew that sports people were using scientific methods to measure and improve performance for decades, but I wanted to discover things on my own. I will continue to stay away from existing knowledge for some time, before I look at them in more detail.
Also: I have personally not seen any person on social media that tracks power output in Watts, or visualizes it with a Wattmeter.
If you know about such a channel, please [let me know](mailto:onur@solmaz.io).
## Not-conclusion
This is a work in progress, so there is no conclusion to this yet. I will add more content as I learn more.
Aim for Watts. It is hard, but more rewarding.
==========
---
title: ".@TextCortex AI now uses @astral_sh uv for production builds"
date: 2024-10-19
canonical: https://solmaz.io/x/1847600004334002510/
x_url: https://x.com/onusoz/status/1847600004334002510
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
.@TextCortex AI now uses @astral_sh uv for production builds
One of the happiest switches so far, many developer days saved per year
==========
---
title: "based ai godfather"
date: 2024-10-09
canonical: https://solmaz.io/x/1844026564335612186/
x_url: https://x.com/onusoz/status/1844026564335612186
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
based ai godfather
*Quotes a post by another author (https://x.com/i/status/1843874006770110550); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "yesterday i asked o1-preview “who are you?” and it used 900 reasoning tokens to reply"
date: 2024-10-09
canonical: https://solmaz.io/x/1843948260463190395/
x_url: https://x.com/onusoz/status/1843948260463190395
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
yesterday i asked o1-preview “who are you?” and it used 900 reasoning tokens to reply
whatever openai is doing to these models, it’s giving them an existential crisis lol
==========
---
title: "Python may overtake JavaScript in an AI-first workflow"
date: 2024-09-22
canonical: https://solmaz.io/x/1837793638731972629/
x_url: https://x.com/onusoz/status/1837793638731972629
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Python might take over JavaScript as the most used language after all
uv from @astral_sh is one of the biggest upticks in Python developer experience in the last 10 years
I've seen so many people struggle with Python distributions, virtual environments, Anaconda, etc. over the years
Most newbies don't care about where their Python executables are, why they have to edit PATH, or why they have to activate a virtual environment
It seems like uv has fixed this: https://github.com/astral-sh/uv
*Quotes a post by @charliermarsh (https://x.com/charliermarsh/status/1837538829579796751); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "3-4 messages back and forth with o1-preview, and I have a CLI tool to remove debug statements..."
date: 2024-09-20
canonical: https://solmaz.io/x/1837252596106481714/
x_url: https://x.com/onusoz/status/1837252596106481714
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
3-4 messages back and forth with o1-preview, and I have a CLI tool to remove debug statements from my code.
No need to do a search for import ipdb... and manually delete the lines. Instead just run in your project:
$ rmdbg .
Written in Rust so it's fast
https://github.com/osolmaz/rmdbg
==========
---
title: "Berlin folk heads up"
date: 2024-09-17
canonical: https://solmaz.io/x/1835997166067700010/
x_url: https://x.com/onusoz/status/1835997166067700010
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Berlin folk heads up
*Quotes a post by another author (https://x.com/i/status/1835990557950087371); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "This has late 90s Bill Gates/Windows Server vibes tbh"
date: 2024-09-14
canonical: https://solmaz.io/x/1834953701930205225/
x_url: https://x.com/onusoz/status/1834953701930205225
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This has late 90s Bill Gates/Windows Server vibes tbh
Open Thought > Closed Thought
*Quotes a post by another author (https://x.com/i/status/1834495182353645768); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Open Thought > Closed Thought"
date: 2024-09-14
canonical: https://solmaz.io/open-thought-closed-thought
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
OpenAI released a new model that "thinks" to itself before it answers. They intentionally designed the interface to hide this inner monologue. There was absolutely no technical reason to do so. Only business reasons
If you try to make o1 reveal its inner monologue, they threaten to remove your access
Because if they let people freely extract this, competitors could quickly use that to improve their models
It seems that AI value creation will be shifting more towards inference-time compute, into Chains of Thought. We might be witnessing the birth of a new paradigm of open vs. closed thought
Impressive as o1 is, the move to hide CoTs is pretty pathetic and reminds of Microsoft's late 90s Windows Server push. Below is an email from Bill Gates about how he is worried that Microsoft won't be able to corner the server market. A few years after he wrote those lines, Linux and LAMP came to dominate servers
Now all eyes on AI at Meta and Zuck for their take on o1/Strawberry/Q*/Orion
[](https://x.com/SmokeAwayyy/status/1834495182353645768)
[](https://x.com/TechEmails/status/1478785899009875968)
---
Originally posted on [LinkedIn](https://www.linkedin.com/posts/osolmaz_openai-released-a-new-model-that-thinks-activity-7240727679371509760-0bCT)
==========
---
title: "A failure scenario for AI infrastructure under scale"
date: 2024-08-28
canonical: https://solmaz.io/x/1828764265970352492/
x_url: https://x.com/onusoz/status/1828764265970352492
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Imagine the following scenario:
1. We develop brain-scan technology today which can take a perfect snapshot of anyone’s brain, down to the atomic level. You undergo this procedure after you die and your brain scan is kept in some fault-tolerant storage, along the lines of GitHub Arctic Code Vault.
2. But sufficiently cheap real-time brain emulation technology takes considerably longer to develop—say 1000 years in the future.
3. 1000 years pass. Everyone that ever knew, loved or cared about you die.
Here is the crucial question:
Given that running a brain scan still costs money in 1000 years, why should anyone bring *you* back from the dead? Why should anyone boot *you* up?
Compute doesn’t grow in trees. It might become very efficient ... (read more in my blog: https://solmaz.io/why-should-anyone-boot-you-up)
---
I intended this thought piece as entertainment, almost went to Hacker News frontpage: https://news.ycombinator.com/item?id=41360537
It must have hit some psychological spot, since people wrote a lot of comments, possibly more than number of upvotes.
==========
---
title: "New blog post on brain emulation"
date: 2024-08-24
canonical: https://solmaz.io/x/1827396013575090386/
x_url: https://x.com/onusoz/status/1827396013575090386
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
New blog post on brain emulation
https://solmaz.io/why-should-anyone-boot-you-up
==========
---
title: "Why should anyone boot *you* up?"
date: 2024-08-18
canonical: https://solmaz.io/why-should-anyone-boot-you-up
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Imagine the following scenario:
1. We develop brain-scan technology today which can take a perfect snapshot of anyone's brain, down to the atomic level. You undergo this procedure after you die and your brain scan is kept in some fault-tolerant storage, along the lines of [GitHub Arctic Code Vault](https://archiveprogram.github.com/arctic-vault/).
2. But sufficiently cheap real-time brain emulation technology takes **considerably longer** to develop—say 1000 years in the future.
3. 1000 years pass. Everyone that ever knew, loved or cared about you die.
Here is the crucial question:
Given that running a brain scan still costs money in 1000 years, why should anyone bring \*you\* back from the dead? **Why should anyone boot \*you\* up?**
Compute doesn't grow in trees. It might become very efficient, but it will never have zero cost, under physical laws.
In the 31st century, the economy, society, language, science and technology will all look different. Most likely, you will not only NOT be able to compete with your contemporaries due to lack of skill and knowledge, you will NOT even be able to *speak their language*. You will need to take a language course first, before you can start learning useful skills. And that assumes some future benefactor is willing to pay to keep you running before you can start making money, survive independently in the future society.
To give an example, I am a software developer who takes pride in his craft. But a lot of the skills I have today will most likely be obsolete by the 31st century. Try to imagine what an 11th century stonemason would need to learn to be able to survive in today's society.
1000 years into the future, you could be as helpless as a child. You could need somebody to adopt you, send you to school, and teach you how to live in the future. You---mentally an adult---could once again need a parent, a teacher.
(This is analogous to cryogenics or time-capsule sci-fi tropes. The further in the future you are unfrozen, the more irrelevant you become and the more help you will need to adapt.)
## Patchy competence?
On the other hand, it would be a pity if a civilization which can emulate brain scans is unable to imbue them with relevant knowledge and skills, unable to update them.
For one second, let's assume that they could. Let's assume that they could inject your scan with 1000 years of knowledge, skills, language, ontology, history, culture and so on.
But then, would it still be *you*?
But then, why not just create a new AI from scratch, with the same knowledge and skills, and without the baggage of your personality, memories, and emotions?
## Why think about this now?
Google researchers recently published [connectomics](https://en.wikipedia.org/wiki/Connectomics) research (click here for the [paper](https://www.science.org/doi/10.1126/science.adk4858)) mapping a 1 mm³ sample of temporal cortex in a petabyte-scale dataset. Whereas the scanning process seems to be highly tedious, it can yield a geometric model of the brain's wiring at nanometer resolution that looks like this:

Rendering based on electron-microscope data, showing the positions of neurons in a fragment of the brain cortex. Neurons are coloured according to size. Credit: Google Research & Lichtman Lab (Harvard University). Renderings by D. Berger (Harvard University)
They have even released the data to the public. You can download it [here](https://h01-release.storage.googleapis.com/paper.html).
An adult human brain takes up around 1.2 liters of volume. There are 1 million mm³ in a liter. If we could scale up the process from Google researchers 1 million times, we could scan a human brain at nanometer resolution, yielding more than 1 zettabyte (i.e., 1 billion terabytes) of data with the same rate.
That is an insane amount of data, and it seems infeasible to store that much data for a sufficient number of bright minds, so that this technology can make a difference. That being said, do we have any other choice but to hope that we will find a way to compress and store it efficiently?
Not only it is infeasible to store that much data with current technology, extracting a nanometer-scale connectome of a human brain may not be enough to capture a person's mind in its entirety. By definition, some information is lost in the process. Fidelity will be among the most important problems in neuropreservation for a long time to come.
That being said, the most important problem in digital immortality may not be technical, but economical. It may not be about *how* to scan a brain, but about *why* to scan a brain and run it, despite the lack of any economic incentive.
==========
---
title: "Difference between expat and immigrant"
date: 2024-07-13
canonical: https://solmaz.io/expat-immigrant-difference
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Two persons move to foreign countries, different from where they were born. One is called an *expat*, the other an *immigrant*. What is the difference between the two?
There are a lot of takes online discussing the semantics, etymologies, conditions underlying the journey. I like spicy takes, and this specific take of mine also happens to draw a nice symmetric picture. So I took the time to blog about it. Not sure if I saw it somewhere else before.
### The take
If a person from a poor country moves to a rich country, they are called an *immigrant*. If a person from a rich country moves to another rich country, they are called an *expat*.
If you like symmetries like I do, you might notice a pattern: what do you call a person moving from a rich country to a poor country? What are the other elements of $\\{\text{rich country}, \text{poor country}\\}^2$ called?
IMO rich to poor is pretty clear: *colonizer*. Poor to poor is not as clear, maybe *nomad* or *drifter*?
People in rich countries who become digital nomads are sometimes relatively poor in their own country, and they go to poorer countries to have higher purchasing power. So I guess *nomad* makes sense?
Put in a table, it looks like this:
Moving to:
Rich country
Poor country
Moving from:
Rich country
Expat
Colonizer
Poor country
Immigrant
Nomad
**Table 1:** The emigration matrix
I even tried to make this into a picture with ChatGPT Dall-E, but the best it could come up with was:

I leave drawing this to someone with more spare time at their hands.
> Side note: Some consider acknowledging poverty to be politically incorrect. IMO it only serves to perpetuate it.
==========
---
title: "I have just published \"Frequencies of Definite Articles in Written vs Spoken German\""
date: 2024-07-06
canonical: https://solmaz.io/x/1809621400065351967/
x_url: https://x.com/onusoz/status/1809621400065351967
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have just published "Frequencies of Definite Articles in Written vs Spoken German"
https://solmaz.io/frequencies-german-definite-articles
==========
---
title: "Frequencies of Definite Articles in Written vs Spoken German"
date: 2024-07-06
canonical: https://solmaz.io/frequencies-german-definite-articles
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> tl;dr Skip to the [Conclusion](#conclusion). Don't forget to look at the graphs.
Unlike a single **"the"** in the English language, the German language has **6 definite articles** that are used based on a noun's gender, case and number:
- 6 definite articles: der, die, das, den, dem, des
- 3 genders: masculine, feminine, neuter (corresponding to "he", "she", "it" in English)
- 4 cases: nominative, accusative, dative, genitive
- 2 numbers: singular, plural
The following table is used to teach when to use which definite article:
| Case | Masculine | Feminine | Neuter | Plural |
| ---------- | --------- | -------- | ------ | ------ |
| Nominative | der | die | das | die |
| Accusative | den | die | das | die |
| Dative | dem | der | dem | den |
| Genitive | des | der | des | der |
**Table 1:** Articles to use in German depending on the noun gender and case.
Importantly, native speakers don't look at such tables while learning German as a child. They internalize the rules through exposure and practice.
If you are learning German as a second language, however, you will most likely spend time writing down these tables and memorizing them.
While learning, you will also memorize the genders of nouns. For example, "der Tisch" (the table) is masculine, "die Tür" (the door) is feminine, and "das Buch" (the book) is neuter. Whereas predicting the case and number is straightforward and can be deduced from the context of the sentence, predicting the gender can be much more difficult.
Without going into much detail, take my word for now that the genders are semi-random. Inanimate objects such as a bus can be a "he" or "she", whereas animate objects such as a "girl" can be a "it".
Because of all this, German learners fail to remember the correct gender at times and develop strategies, heuristics, to fall back to some default gender or article when they are unsure. For example, some learners use "der" as a default article when they are unsure, whereas others use "die" or "das".
I have taken many German courses since middle school. Most German courses teach you how to use German correctly, but very few of them teach you what to do when you don't know how to use German correctly, like when you don't know the gender of an article.
This is a precursor to a future post where I will write about those strategies. Any successful strategy must be informed by the frequencies and probability distribution of noun declensions. To that end, I performed Natural Language Processing on two corpuses of the German language:
- Transcriptions of over 140 hours of videos from the [Easy German YouTube channel](https://www.youtube.com/@EasyGerman), which contains lots of street interviews and other spoken examples.
- [10kGNAD: Ten Thousand German News Articles Dataset](https://tblock.github.io/10kGNAD/), which contains over 10,000 cleaned up news articles from an Austrian newspaper.
I will introduce some notation to represent these frequencies easier, which are going to be followed by the results of the analysis.
## Mapping the space of noun declensions
The goal of this article is to show the frequencies of definite articles alongside the declensions of the nouns they accompany. To be able to do that, we need a concise notation to represent the states a noun can be in.
To this end, we introduce the set of grammatical genders $G$,
$$
G = \{\text{Masculine}, \text{Feminine}, \text{Neuter}\}
$$
the set of grammatical cases $C$,
$$
C = \{\text{Nominative}, \text{Accusative}, \text{Dative}, \text{Genitive}\}
$$
and the set of grammatical numbers $N$,
$$
N = \{\text{Singular}, \text{Plural}\}
$$
The set of all possible grammatical states $S$ for a German noun is
$$
S = G \times C \times N
$$
whose number of elements is $\|S\| = 3 \times 4 \times 2 = 24$.
To represent the elements of this set better, we introduce the index notation
$$
S_{ijk} = (N_i, G_j, C_k)
$$
for $i=1,2$, $j=1,2,3$ and $k=1,2,3,4$ correspond to the elements in the order seen in the definitions above.
Elements of $S$ can be shown in a single table, like below:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
$S_{111}$
$S_{121}$
$S_{131}$
$S_{211}$
$S_{221}$
$S_{231}$
Accusative
$S_{112}$
$S_{122}$
$S_{132}$
$S_{212}$
$S_{222}$
$S_{232}$
Dative
$S_{113}$
$S_{123}$
$S_{133}$
$S_{213}$
$S_{223}$
$S_{233}$
Genitive
$S_{114}$
$S_{124}$
$S_{134}$
$S_{214}$
$S_{224}$
$S_{234}$
**Table 2:** All possible grammatical states of a German noun in one picture.
In practice, plural forms of articles and declensions for all genders are the same in each case, so they are shown next to the singular forms:
| Case | Masculine | Feminine | Neuter | Plural |
| ---------- | --------- | --------- | --------- | --------------------------- |
| Nominative | $S_{111}$ | $S_{121}$ | $S_{131}$ | $S_{211}, S_{221}, S_{231}$ |
| Accusative | $S_{112}$ | $S_{122}$ | $S_{132}$ | $S_{212}, S_{222}, S_{232}$ |
| Dative | $S_{113}$ | $S_{123}$ | $S_{133}$ | $S_{213}, S_{223}, S_{233}$ |
| Genitive | $S_{114}$ | $S_{124}$ | $S_{134}$ | $S_{214}, S_{224}, S_{234}$ |
**Table 3:** Plural states across genders are grouped together because they are declined in the same way. Their distinction is irrelevant for learning.
which is the case in Table 1 above. You might say, "well, of course". In that case, I invite you to imagine a parallel universe where German grammar is even more complicated and plural forms have to be declined differently as well. Interestingly, you don't need to visit such a universe---you just need to go back in time, [because Old High German grammar was exactly like that](https://web.archive.org/web/20240404192545/https://en.wikipedia.org/wiki/Old_High_German_declension). Note that in that Wikipedia page, some tables has the same shape as Table 2.
*Why introduce such confusing looking notation?* It might look confusing to the untrained eye, but it is actually very useful for representing all possible combinations in a compact way. It also makes it easier to run a sanity check on the results of the analysis through the independence axiom, which we will introduce next.
### Relationships between probabilities
As a side note, the relationship between the probabilities of all grammatical states of a noun and the probabilities of each case is as below:
$$
\begin{aligned}
P(C_1 = \text{Nom}) &= \sum_{i=1}^{2} \sum_{j=1}^{3} P(S_{ij1}) \\
P(C_2 = \text{Acc}) &= \sum_{i=1}^{2} \sum_{j=1}^{3} P(S_{ij2}) \\
P(C_3 = \text{Dat}) &= \sum_{i=1}^{2} \sum_{j=1}^{3} P(S_{ij3}) \\
P(C_4 = \text{Gen}) &= \sum_{i=1}^{2} \sum_{j=1}^{3} P(S_{ij4})
\end{aligned}
$$
Similarly, for each gender:
$$
\begin{aligned}
P(G_1 = \text{Masc}) &= \sum_{i=1}^{2} \sum_{k=1}^{4} P(S_{i1k}) \\
P(G_2 = \text{Fem}) &= \sum_{i=1}^{2} \sum_{k=1}^{4} P(S_{i2k}) \\
P(G_3 = \text{Neut}) &= \sum_{i=1}^{2} \sum_{k=1}^{4} P(S_{i3k}) \\
\end{aligned}
$$
And for each number:
$$
\begin{aligned}
P(N_1 = \text{Sing}) &= \sum_{j=1}^{3} \sum_{k=1}^{4} P(S_{1jk}) \\
P(N_2 = \text{Plur}) &= \sum_{j=1}^{3} \sum_{k=1}^{4} P(S_{2jk}) \\
\end{aligned}
$$
This is useful for going from specific probabilities to general probabilities and vice versa.
### Independence Axiom
We introduce an axiom that will let us run a sanity check on the results of the analysis. At a high level, the axiom states that **the probability of a noun being in a certain case, a certain gender and a certain number are all independent of each other**. For example, the probability of a noun being in the nominative case is independent of the probability of it being masculine or feminine or neuter, and it is also independent of the probability of it being singular or plural. This should be common sense in any large enough corpus, so we just assume it to be true.
Formally, the axiom can be written as
$$
P(S_{ijk}) = P(G_i) P(C_j) P(N_k) \quad \text{for all } i,j,k
$$
where $P(G_i) P(C_j) P(N_k)$ is the joint probability of the noun being in the grammatical state $S_{ijk}$.
In any given corpus, it will be hard to get this equality to hold exactly. In reality, a given corpus or the NLP libraries used in the analysis might have a bias that might distort the equality above.
The idea is that the smaller the difference between the left-hand side and the right-hand side, the more the corpus and the NLP libraries are unbiased and adhere to common sense. As a corpus gets larger and more representative of the entire language, the following quantity should get smaller:
$$
\text{Bias} = \sum_{i=1}^{2} \sum_{j=1}^{3} \sum_{k=1}^{4} |\delta_{ijk}| \quad \text{where}\quad \delta_{ijk} = \hat{P}(S_{ijk}) - \hat{P}(G_i) \hat{P}(C_j) \hat{P}(N_k)
$$
We will calculate this quantity for the two corpuses we have and see how biased either they or the NLP libraries are.
Note that the notation $\hat{P}(S_{ijk})$ is used to denote the empirical probability of the noun being in the grammatical state $S_{ijk}$, which is calculated from the corpus as
$$
\hat{P}(S_{ijk}) = \frac{N_{ijk}}{\sum_{i=1}^{2} \sum_{j=1}^{3} \sum_{k=1}^{4} N_{ijk}}
$$
where $N_{ijk}$ is the count of the noun being in the grammatical state $S_{ijk}$. Similar notation is used for $\hat{P}(G_i)$, $\hat{P}(C_j)$ and $\hat{P}(N_k)$.
## The analysis
I outline step by step how I performed the analysis on the two corpuses.
### Constructing the spoken corpus
The [Easy German YouTube Channel](https://www.youtube.com/@EasyGerman) is a great resource for beginner German learners. It has lots of street interviews with random people on a wide range of topics.
To download the channel, I used [yt-dlp](https://github.com/yt-dlp/yt-dlp), a youtube-dl fork:
```bash
#!/bin/bash
mkdir data
cd data
yt-dlp -f 'ba' -x --audio-format mp3 https://www.youtube.com/@EasyGerman
```
This gave me 946 audio files with over 139 hours of recordings. Then I used [OpenAI's Whisper API](https://github.com/openai/whisper) to transcribe all the audio:
```python
import json
import os
import openai
from tqdm import tqdm
DATA_DIR = "data"
OUTPUT_DIR = "transcriptions"
# Get all mp3 files in the current directory
mp3_files = [
f for f in os.listdir(DATA_DIR) if os.path.isfile(f) and f.endswith(".mp3")
]
mp3_files = sorted(mp3_files)
# Create the output directory if it doesn't exist
if not os.path.exists(OUTPUT_DIR):
os.makedirs(OUTPUT_DIR)
for file in tqdm(mp3_files):
# Create json target file name in output directory
json_file = os.path.join(OUTPUT_DIR, file.replace(".mp3", ".json"))
# If the json file already exists, skip it
if os.path.exists(json_file):
print(f"Skipping {file} because {json_file} already exists")
continue
# Check if the file is greater than 25MB
if os.path.getsize(file) > 25 * 1024 * 1024:
print(f"Skipping {file} because it is greater than 25MB")
continue
print(f"Running {file}")
try:
output = openai.Audio.transcribe(
model="whisper-1",
file=open(file, "rb"),
format="verbose_json",
)
output = output.to_dict()
json.dump(output, open(json_file, "w"), indent=2)
except openai.error.APIError:
print(f"Skipping {file} because of API error")
continue
```
This gave me a lot to work with, specifically a little bit over 1 million words of spoken German. As a reference, the content of the videos can fill roughly more than 10 novels, or alternatively, [400 Wikipedia articles](https://wikicount.net/). Note that I created this dataset around May 2023, so the dataset would be even bigger if I ran the script today. However, it still costs money to transcribe the audio, so I will stick with this dataset for now.
### Constructing the written corpus
The [10kGNAD: Ten Thousand German News Articles Dataset](https://tblock.github.io/10kGNAD/) contains over 10,000 cleaned up news articles from an Austrian newspaper. I downloaded the dataset and modified the [script they provided](https://github.com/tblock/10kGNAD/blob/master/code/extract_dataset_from_sqlite.py) to extract the articles from the database and write them to a text file:
```python
import re
import sqlite3
from tqdm import tqdm
from bs4 import BeautifulSoup
ARTICLE_QUERY = (
"SELECT Path, Body FROM Articles "
"WHERE PATH LIKE 'Newsroom/%' "
"AND PATH NOT LIKE 'Newsroom/User%' "
"ORDER BY Path"
)
conn = sqlite3.connect(PATH_TO_SQLITE_FILE)
cursor = conn.cursor()
corpus = open(TARGET_PATH, "w")
for row in tqdm(cursor.execute(ARTICLE_QUERY).fetchall(), unit_scale=True):
path = row[0]
body = row[1]
text = ""
description = ""
soup = BeautifulSoup(body, "html.parser")
# get description from subheadline
description_obj = soup.find("h2", {"itemprop": "description"})
if description_obj is not None:
description = description_obj.text
description = description.replace("\n", " ").replace("\t", " ").strip() + ". "
# get text from paragraphs
text_container = soup.find("div", {"class": "copytext"})
if text_container is not None:
for p in text_container.findAll("p"):
text += (
p.text.replace("\n", " ")
.replace("\t", " ")
.replace('"', "")
.replace("'", "")
+ " "
)
text = text.strip()
# remove article autors
for author in re.findall(
r"\.\ \(.+,.+2[0-9]+\)", text[-50:]
): # some articles have a year of 21015..
text = text.replace(author, ".")
corpus.write(description + text + "\n\n")
conn.close()
```
This gave me 10277 articles with around 3.7 million words of written German. Note that this is over 3 times bigger than the spoken corpus.
### NLP and counting the frequencies
I used [spaCy](https://en.wikipedia.org/wiki/Part-of-speech_tagging) for Part-of-Speech Tagging. This basically assigns to each word whether it is a noun, pronoun, adjective, determiner etc. Definite articles will have the PoS tag `"DET"` in the output of spaCy.
spaCy is pretty useful. For any `token` in the output, `token.head` gives the syntactic parent, or "governor" of the `token`. For definite articles like "der", "die", "das", the head will be the noun they are referring to. If spaCy couldn't connect the article with a noun, any deduction of gender has a high likelihood of being wrong, so I skip those cases.
```python
import numpy as np
import spacy
from tqdm import tqdm
CORPUS = "corpus/easylang-de-corpus-2023-05.txt"
# CORPUS = "corpus/10kGNAD_single_file.txt"
ARTICLES = ["der", "die", "das", "den", "dem", "des"]
CASES = ["Nom", "Acc", "Dat", "Gen"]
GENDERS = ["Masc", "Fem", "Neut"]
NUMBERS = ["Sing", "Plur"]
CASE_IDX = {i: CASES.index(i) for i in CASES}
GENDER_IDX = {i: GENDERS.index(i) for i in GENDERS}
NUMBER_IDX = {i: NUMBERS.index(i) for i in NUMBERS}
# Create an array of the articles
ARTICLE_ijk = np.empty((2, 3, 4), dtype="

**Table and Figure 4:** Each gender, their percentage and count for the spoken and written corpora.
Observations:
- The written corpus contains ~6 percentage points less neuter nouns than the spoken corpus.
- This ~6 pp difference is distributed almost equally between the masculine and feminine nouns, with the written corpus containing ~3 pp more feminine nouns and ~3 pp more masculine nouns.
The difference is considerable and might point out to a bias in the way Whisper transcribed the speech or spaCy has parsed it. Both corpora are large enough to be representative, so this needs investigation in a future post.
#### Frequencies of cases
The distribution of the cases that the article-noun pairs are in is as below:
| Case | Spoken corpus | Written corpus |
|------|---------------------|-----------------------|
| Nom | 35.96 % (12357) | 34.82 % (112612) |
| Acc | 33.75 % (11598) | 23.52 % (76062) |
| Dat | 25.98 % (8929) | 23.59 % (76298) |
| Gen | 4.32 % (1483) | 18.06 % (58417) |

**Table and Figure 5:** Each case, their percentage and count for the spoken and written corpora.
The spoken corpus has ~10 pp more accusative nouns, ~2 pp more dative nouns and ~13 pp less genitive nouns compared to the written corpus. The nominative case is more or less the same in both corpora.
This might be the analysis capturing the contemporary decline of the genitive case in the German language, as popularized by Bastian Sick with the phrase "Der Dativ ist dem Genitiv sein Tod" (The dative is the death of the genitive) [with his eponymous book](https://en.wikipedia.org/wiki/Der_Dativ_ist_dem_Genitiv_sein_Tod). However, the graph clearly shows a trend towards accusative, and much less towards dative.
Moreover, written language differs in tone and style from spoken language for many languages, including German. This might also explain the differences in the frequencies of the cases.
If this is not due to a bias, we might be onto something here. This also needs further investigation in a future post.
#### Frequencies of numbers
The distribution of the numbers of the corresponding nouns is as below:
| Number | Spoken corpus | Written corpus |
|--------|--------------------|-----------------------|
| Sing | 81.10 % (27870) | 79.18 % (256066) |
| Plur | 18.90 % (6497) | 20.82 % (67323) |

**Table and Figure 6:** Each number, their percentage and count for the spoken and written corpora.
The ratio of singular to plural nouns is more or less the same in both corpora. I wonder whether this 80-20 ratio is "universal" in German or any other languages as well...
#### Frequencies of definite articles
The distribution of the definite articles in the spoken and written corpus is as below:
| Article | Spoken corpus | Written corpus |
| ------- | ------------- | --------------- |
| der | 26.74 % (9190) | 34.44 % (111378) |
| die | 36.47 % (12534) | 32.60 % (105416) |
| das | 15.80 % (5430) | 8.81 % (28481) |
| den | 12.22 % (4201) | 11.50 % (37174) |
| dem | 7.39 % (2539) | 6.23 % (20135) |
| des | 1.38 % (473) | 6.43 % (20805) |

**Table and Figure 7:** Each definite article, their percentage and count for the spoken and written corpora.
Observations:
- `der` appears less frequently (~8 pp difference),
- `die` appears more frequently (~4 pp difference),
- `das` appears more frequently (~7 pp difference),
- `des` appears less frequently (~5 pp difference),
in the spoken corpus compared to the written corpus. `den` and `dem` are more or less the same in both corpora.
The ~7 pp difference in `das` is despite the fact that ~78% of the occurrence of the token `das` in the spoken corpus are **pronouns** (`PRON`, not `DET`) and hence excluded from the table above. See the [section below](#calculating-the-number-of-articles-used-as-determiners-versus-pronouns) for more details. Looking at the gender distribution above, the spoken corpus contains ~6 pp more neuter nouns than the written corpus, which might explain this discrepancy.
### Empirical probabilities for the spoken corpus
Empirical probabilities:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
9.55 %
11.16 %
8.64 %
3.61 %
1.71 %
1.28 %
Accusative
7.88 %
11.96 %
7.16 %
2.83 %
2.26 %
1.66 %
Dative
3.84 %
14.25 %
3.55 %
1.83 %
1.36 %
1.16 %
Genitive
0.71 %
1.73 %
0.67 %
0.54 %
0.40 %
0.27 %
**Table 8:** $\hat{P}(S_{ijk})$ for the spoken corpus.
Click below to see the joint probabilities and their differences as an error term:
Joint probabilities:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
8.98 %
13.07 %
7.11 %
2.09 %
3.05 %
1.66 %
Accusative
8.42 %
12.27 %
6.67 %
1.96 %
2.86 %
1.56 %
Dative
6.49 %
9.45 %
5.14 %
1.51 %
2.20 %
1.20 %
Genitive
1.08 %
1.57 %
0.85 %
0.25 %
0.37 %
0.20 %
**Table 9:** $\hat{P}(G_i) \hat{P}(C_j) \hat{P}(N_k)$ for the spoken corpus.
Their differences:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
0.58 %
-1.91 %
1.53 %
1.52 %
-1.33 %
-0.38 %
Accusative
-0.54 %
-0.31 %
0.49 %
0.86 %
-0.60 %
0.10 %
Dative
-2.65 %
4.80 %
-1.59 %
0.32 %
-0.85 %
-0.04 %
Genitive
-0.37 %
0.16 %
-0.18 %
0.29 %
0.03 %
0.07 %
**Table 10:** $\delta_{ijk}$ for the spoken corpus.
Observations:
For most elements, the differences are less than 1-2%, which is a good sign. However, significant bias shows for some cases:
- 4.80 % (der, feminine, dative, singular)
- -2.65 % (dem, masculine, dative, singular)
- -1.91 % (die, feminine, nominative, singular)
- -1.33 % (die, feminine, nominative, plural)
- and so on...
I add more comments following the results for the written corpus below.
### Empirical probabilities for the written corpus
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
10.63 %
12.24 %
5.14 %
3.64 %
2.11 %
1.06 %
Accusative
6.31 %
9.26 %
3.67 %
1.73 %
1.63 %
0.92 %
Dative
3.82 %
12.18 %
2.41 %
2.06 %
1.80 %
1.32 %
Genitive
3.61 %
7.09 %
2.82 %
2.19 %
1.45 %
0.90 %
**Table 11:** $\hat{P}(S_{ijk})$ for the written corpus.
Click below to see the joint probabilities and their differences as an error term:
Joint probabilities:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
9.37 %
13.17 %
5.03 %
2.46 %
3.46 %
1.32 %
Accusative
6.33 %
8.90 %
3.40 %
1.66 %
2.34 %
0.89 %
Dative
6.35 %
8.92 %
3.41 %
1.67 %
2.35 %
0.90 %
Genitive
4.86 %
6.83 %
2.61 %
1.28 %
1.80 %
0.69 %
**Table 12:** $\hat{P}(G_i) \hat{P}(C_j) \hat{P}(N_k)$ for the written corpus.
Their differences:
Case
Singular
Plural
Masculine
Feminine
Neuter
Masculine
Feminine
Neuter
Nominative
1.26 %
-0.93 %
0.11 %
1.17 %
-1.35 %
-0.26 %
Accusative
-0.02 %
0.37 %
0.27 %
0.06 %
-0.71 %
0.03 %
Dative
-2.53 %
3.26 %
-1.00 %
0.39 %
-0.54 %
0.43 %
Genitive
-1.25 %
0.26 %
0.21 %
0.92 %
-0.35 %
0.21 %
**Table 13:** $\delta_{ijk}$ for the written corpus.
Observations:
The difference terms follow a similar pattern to the spoken corpus in the extreme cases:
- 3.26 % (der, feminine, dative, singular)
- -2.53 % (dem, masculine, dative, singular)
- -1.35 % (die, feminine, nominative, plural)
Since the bias is most extreme in many common cells, this leads me to believe that there is a bias in spaCy's `de_dep_news_trf` model that confuses the case or gender in some cases. This hypothesis can be tested by using a different model and library, and calculating the differences again. I'm leaving that as future work.
### Calculating the number of articles used as determiners versus pronouns
Another comparison of interest is whether one of the "der", "die", "das", "den", "dem", "des" is used more as a pronoun than as a determiner. To give an example, "das" can be used as a pronoun in the sentence *"Das ist ein Buch"* (That is a book) or as a determiner in the sentence *"Das Buch ist interessant"* (The book is interesting).
We can calculate this by storing the PoS tags of tokens that match "der", "die", "das", "den", "dem", "des" and dividing the numbers by the occurrence of each article.
```python
import spacy
from tqdm import tqdm
CORPUS = "corpus/easylang-de-corpus-2023-05.txt"
# CORPUS = "corpus/10kGNAD_single_file.txt"
ARTICLES = ["der", "die", "das", "den", "dem", "des"]
MODEL = "de_dep_news_trf"
nlp_spacy = spacy.load(MODEL)
# This array will store the count of each POS tag for each article
POS_COUNT_DICT = {i: {} for i in ARTICLES}
corpus = open(CORPUS).read()
texts = corpus.split("\n\n")
for text in tqdm(texts):
doc = nlp_spacy(text)
for token in doc:
success = True
# Get token string
token_str = token.text
token_str_lower = token_str.lower()
if token_str_lower not in ARTICLES:
continue
if token.pos_ not in POS_COUNT_DICT[token_str_lower]:
POS_COUNT_DICT[token_str_lower][token.pos_] = 0
POS_COUNT_DICT[token_str_lower][token.pos_] += 1
print(POS_COUNT_DICT)
```
For both corpora, the >99% of the PoS tags are either `DET` or `PRON`. I have ignored the rest of the tags for simplicity.
| Article | Pronoun % in spoken corpus | Pronoun % in written corpus |
|-----|-----------------------------|------------------------------|
| der | 15.4 % (1734 out of 11242) | 5.8 % (7125 out of 123442) |
| die | 29.3 % (6024 out of 20557) | 11.6 % (14696 out of 126783) |
| das | **78.6 %** (20941 out of 26638) | 33.1 % (14439 out of 43673) |
| den | 11.3 % (602 out of 5332) | 2.0 % (836 out of 41393) |
| dem | 12.2 % (360 out of 2962) | 8.9 % (2060 out of 23060) |
| des | 0.6 % (3 out of 493) | 0.0 % (8 out of 21548) |

**Table and Figure 14:** Percentage of usage of "der", "die", "das", "den", "dem", "des" as pronouns versus determiners in the spoken and written corpora.
Observations:
The spoken corpus overall uses more pronouns than the written corpus. The most striking difference is in the usage of "das" as a pronoun, with the spoken corpus using it as a pronoun in ~45 pp more cases than the written corpus. This might be due to a bias at any point in the analysis pipeline, or it might be due to the nature of spoken versus written language.
### Conclusion
I have already commented a great deal below each result above. I don't want to speak in absolutes at this point, because the analysis might be biased due to the following factors:
- Corpus bias: Easy German is a YouTube channel for German learning, and despite having a diverse set of street interviews, there is also a lot of accompanying content that might skew the results. Similarly, the 10kGNAD dataset is a collection of news articles from an Austrian newspaper, which might also skew the results. There might be differences between Austrian German and German German. To overcome any corpus related biases, this work should be repeated with even more data.
- Transcription bias: I used OpenAI's Whisper V2 in May 2023 to transcribe the spoken corpus. There might be a bias in Whisper that might show up in the results. Whisper is currently among state-of-the-art speech-to-text models. We will most likely get better, faster and cheaper models in the upcoming years, and we can then repeat this analysis with them.
- NLP bias: I used spaCy's `de_dep_news_trf` model for Part-of-Speech Tagging. There might be a bias in this model that might show up in the results. I might use another library in spaCy, or a different NLP library altogether, to see if the results change.
That being said, if I were to draw any conclusions from the results above, those would be:
#### Most frequent articles
For spoken German, the most frequently used definite articles (excluding pronouns) are in the order: `die` > `der` > `das` > `den` > `dem` > `des`.
For written German, the order is: `der` > `die` > `den` > `das` > `des` > `dem`.
`die` is statistically the most used definite article with close to 40% usage in spoken German Moreover, `der`, `die` and `das` collectively make up ~80% of the definite articles used in spoken German. So if you never learn the rest, you would be speaking German correctly 80% of the time, assuming that you are using the cases correctly.
#### Using das as pronoun in spoken German
`das` is used as a pronoun much more frequently in spoken German than in written German.
#### Most frequent genders
The most frequently used genders are in the order: feminine > masculine > neuter. This is widely known and has been recorded by many other studies as well.
#### Genitive on the fall, accusative (more so) and dative (less so) on the rise
Germans use genitive much less when speaking compared to writing. Surprisingly, this reflects in an increase **more in the accusative** case than in the dative case. This might point out to a trend where **dative is falling out of favor as well**. This is not to imply that accusative phrasing can be a substitute for genitive, like using "von" (of, which is dative) instead of the genitive case.
All of this point out to a trend of simplification in declension patterns of spoken German. Considering Old High German---the language German once---was even more complicated in that regard, the findings above don't surprise me.
> I might update this post with more findings or refutations of above conclusions later on, if future data shows that they are false.
==========
---
title: "Another short note on how I think about subscription states on Stripe"
date: 2024-06-09
canonical: https://solmaz.io/x/1799898451943002511/
x_url: https://x.com/onusoz/status/1799898451943002511
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Another short note on how I think about subscription states on Stripe
https://solmaz.io/stripe-subscription-states
==========
---
title: "I have published a short study on how the complexity of a country's language could burden its..."
date: 2024-06-09
canonical: https://solmaz.io/x/1799898132987117864/
x_url: https://x.com/onusoz/status/1799898132987117864
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I have published a short study on how the complexity of a country's language could burden its economy
https://solmaz.io/economic-burden-of-language-complexity
==========
---
title: "@timpaul @aboutberlin"
date: 2024-05-27
canonical: https://solmaz.io/x/1795166901351469158/
x_url: https://x.com/onusoz/status/1795166901351469158
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@timpaul @aboutberlin
==========
---
title: "Stripe Subscription States"
date: 2024-05-18
canonical: https://solmaz.io/stripe-subscription-states
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This is a quick note on Subscription states on [Stripe](https://stripe.com). Subscriptions are objects which track products with recurring payments. [Stripe docs on Subscriptions](https://docs.stripe.com/billing/subscriptions/overview) are very comprehensive, but for some reason they don't include a state diagram that shows the transitions between different states of a subscription. They do have one for [Invoices](https://docs.stripe.com/invoicing/integration/workflow-transitions), so maybe this post will inspire them to add one.
As of May 2024, the API has 8 values for `Subscription.status`:
- `incomplete`: This is the initial state of a subscription. It means that the subscription has been created but the first payment has not been made yet.
- `incomplete_expired`: The first payment was not made within 23 hours of creating the subscription.
- `trialing`: The subscription is in a trial period.
- `active`: The subscription is active and the customer is being billed according to the subscription's billing schedule.
- `past_due`: The subscription has unpaid invoices.
- `unpaid`: The subscription has been canceled due to non-payment.
- `canceled`: The subscription has been canceled by the customer or due to non-payment.
- `paused`: The subscription is paused and will not renew.
At any given time, a `Customer`'s subscription can be in one of these states. The following diagram shows the transitions between these states.
```mermaid
stateDiagram
classDef alive fill:#28a745,color:white,font-weight:bold,stroke-width:2px
classDef dead fill:#dc3545,color:white,font-weight:bold,stroke-width:2px
classDef suspended fill:#ffc107,color:#343a40,font-weight:bold,stroke-width:2px
active:::alive
trialing:::alive
incomplete:::suspended
past_due:::suspended
unpaid:::suspended
paused:::suspended
canceled:::dead
incomplete_expired:::dead
[*] --> incomplete: Create Subscription
trialing --> active: Trial ended, first payment succeeded
incomplete --> trialing: Started trial
incomplete --> incomplete_expired: Payment not made within 23 hours
incomplete --> active: Payment succeeded
active --> past_due: Automatic payment failed
trialing --> past_due: Trial ended payment failed
past_due --> unpaid: Retry limit reached
past_due --> canceled: Retry limit reached or subscription canceled
past_due --> active: Payment succeeded
trialing --> paused: Trial ended without default payment method
paused --> active: First payment made
active --> unpaid: Automatic payment disabled, manual intervention required
unpaid --> active: Payment succeeded
unpaid --> canceled: Subscription canceled
active --> canceled: Subscription canceled
paused --> canceled: Subscription canceled
trialing --> canceled: Subscription canceled
incomplete_expired --> [*]
canceled --> [*]
```
Stripe doesn't comment on these states further and leaves their interpretation to the developer. This is probably because each company might interpret these states differently. For example, a user skipping a payment and becoming `past_due` might not warrant disabling a service for some companies, while others might want to disable services immediately. Stripe's API is built to be agnostic of these decisions.
Regardless of how you interpret these 8 states, you will most likely end up generalizing them into 3 categories: `ALIVE`, `SUSPENDED`, and `DEAD`. The colors in the diagram above represent these categories:
- `ALIVE`: The subscription is active and payments are being made. States: `active`, `trialing`.
- `SUSPENDED`: The subscription is not active but can be reactivated. States: `incomplete`, `past_due`, `unpaid`, `paused`.
- `DEAD`: The subscription is not active and cannot be reactivated. Such subscriptions are effectively deleted. States: `canceled`, `incomplete_expired`.
While `DEAD` states are unambiguous, your company might differ in what is considered `ALIVE` and `SUSPENDED`. For example, you might consider `past_due` as `ALIVE` if you don't want to disable services immediately after a payment failure.
If you collapse the 8 states into these categories, you get the following diagram:
```mermaid
stateDiagram
direction TB;
classDef alive fill:#28a745,color:white,font-weight:bold,stroke-width:2px
classDef dead fill:#dc3545,color:white,font-weight:bold,stroke-width:2px
classDef suspended fill:#ffc107,color:#343a40,font-weight:bold,stroke-width:2px
ALIVE:::alive
SUSPENDED:::suspended
DEAD:::dead
state ALIVE {
active
trialing
trialing-->active
}
state DEAD {
canceled
incomplete_expired
}
state SUSPENDED {
incomplete
past_due
unpaid
paused
past_due-->unpaid
}
[*] --> SUSPENDED: Create Subscription
SUSPENDED --> ALIVE: Payment succeeded or trial started
ALIVE --> SUSPENDED: Payment failed
SUSPENDED --> DEAD: Subscription canceled or checkout expired
ALIVE --> DEAD: Subscription canceled
DEAD --> [*]
```
The distinction is important, because Stripe doesn't make it crystal clear what kind of subscriptions can come back from the dead and end up charging the customers multiple times. If you are not [limiting the number of subscriptions per customer](https://docs.stripe.com/payments/checkout/limit-subscriptions), this is something you should be aware of. Practically, this means that you block the customer from creating a new subscription if they already have an `ALIVE` or `SUSPENDED` subscription. `DEAD` subscriptions can be ignored.
==========
---
title: "It looks like a plateau until you remember they made GPT-4o available to free users, and it..."
date: 2024-05-14
canonical: https://solmaz.io/x/1790280910807740690/
x_url: https://x.com/onusoz/status/1790280910807740690
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
It looks like a plateau until you remember they made GPT-4o available to free users, and it might be smaller than GPT-4. So this announcement doesn't prove anything about the capabilities of their largest model
*Quotes a post by another author (https://x.com/i/status/1790065135303774275); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Economic Burden of Language Complexity"
date: 2024-05-04
canonical: https://solmaz.io/economic-burden-of-language-complexity
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Some languages are harder to learn compared to others. Difficulty can show up in different places. For example, English has a relatively easy grammar, but [writing it](https://en.wikipedia.org/wiki/English_orthography) can be challenging. Remember the first time you learned to write *thorough*, *through*, *though*, *thought* and *tough*.
Then take Chinese as an example. Its grammar is more simple than English---no verb conjugations, no tenses, no plurals, no articles. Its [sounds and intonation](https://en.wikipedia.org/wiki/Standard_Chinese_phonology) are unusual for a westerner, but arguably not *that* difficult. The most difficult part might be the [writing system](https://en.wikipedia.org/wiki/Written_Chinese), with thousands of characters that must be memorized before one can read and write fluently. A 7-year old primary schooler can learn to read and write English in 2 years, whereas for Chinese it takes at least 4 years. This is despite [multiple simplifications in the Chinese writing system](https://en.wikipedia.org/wiki/Simplified_Chinese_characters) in the 20th century.
Now compare two adult workers of equal skill: a native Chinese emigrating to the US and learning English, versus a native American emigrating to China and learning Chinese. Which one will be able to **start working and contributing to the economy faster**? Extrapolating from the primary school example, the US adult could take at least twice as long to learn Chinese compared to their Chinese counterpart learning English---at least for reading and writing.
Time is money. It takes time to learn a language, and it takes more time to learn a "harder" one. Therefore, learning a complicated language has a cost. The cost of language complexity applies not only to native speakers, but also to foreign learners, which are the focus of this post:
> The more complex the language of a country, the less attractive it is to foreign workers, skilled or otherwise.
This is because any worker who decides to move to a country with a more complex language will **take longer** to start contributing to the economy. This can be measured directly in terms of lost wages, taxes, and productivity.
Any such worker will also find it more difficult to integrate into the society, which can create indirect costs that are harder to measure, but are a burden nonetheless. For example, it could result in reduced upward mobility, decreased purchasing power, increased reliance on social services, and so on.
Here, I will focus on a cost that is one of the most tangible and easiest to quantify: wages that are lost due to language complexity. Doing that is relatively easy and gets my point across. I will then apply my calculation to a specific language, German, as a case study.
## Wages lost while learning the local language
I will attempt a back-of-the-envelope calculation to estimate the total value of lost wages per year for all foreign workers in a country, while they are learning the local language. "Lost wages" mean the money that workers would have earned if they were working instead of learning the language, and the economic value that is not created as a result.
This is going to be a simplified model with many assumptions. For example, I assume that foreign workers do not know the local language when they arrive and spend a fixed amount of time per week learning the local language.
In the model, a given country receives $R$ foreign workers per year through migration. Each foreign worker takes $T$ years to learn the local language. Assuming that the rate of immigration $R$ stays constant (steady state), the number $N$ of foreign workers learning the local language at any given time is given by:
$$
N = R \times T
$$
The average foreign worker dedicates $F$ hours per week to learning the local language. Most likely, only a percentage $D$ of $F$ will block actual work hours, for example in the form of an intensive language course, and the rest of the learning will take place during free time. If the average foreign worker works $W$ weeks per year, then the total number of hours per year that they spend learning the local language, **that would otherwise be spent working**, is given by:
$$
L = D \times F \times W
$$
Assuming that the average foreign worker earns $S$ [units of currency](https://en.wikipedia.org/wiki/Num%C3%A9raire) per hour, the total value $C$ of lost wages per year and per foreign worker is given by:
$$
C = S \times L
$$
We assume that for the given language, it takes $P$ hours of study to reach a certain level of proficiency necessary to communicate effectively in the workplace, say [B2](https://en.wikipedia.org/wiki/Common_European_Framework_of_Reference_for_Languages). Then we can calculate the number of years $T$ it takes to reach that level as:
$$
T = \frac{P}{F \times W}
$$
Finally, the total value of lost wages per year for all foreign workers in a country is given by:
$$
\begin{aligned}
C_{\text{total}} &= C \times N \\
&= (S \times L) \times (R \times T) \\
&= S \times (D \times F \times W) \times R \times \left(\frac{P}{F \times W}\right) \\
&= S \times D \times R \times P \\
\end{aligned}
$$
Put into words, the total value of lost wages per year for all foreign workers in a country is equal to the multiplication of the average hourly wage $S$, the percentage of time spent learning the language that displaces work $D$, the number of people immigrating per year $R$, and the number of hours of study required to reach a certain level of proficiency $P$.
If you could measure all these values accurately, you would have a good minimum estimate, a lower bound of the economic burden of teaching a language to foreign workers. The burden of *complexity* for any given language would then only be calculated by comparing its $P$ value to that of other languages.
Take Germany as an example. Given the values of $S$, $D$, $R$ for Germany, and the $P$ values for both German and English, you could calculate the money that the German economy is losing per year by German not being as easy to learn as English:
$$
C_{\text{complexity}} = S \times D \times R \times (P_{\text{German}} - P_{\text{English}})
$$
I attempt to calculate this below, with values I could find on the internet.
## Case study: German
I live in Germany and I wrote this post with the German language in mind. Compared to other European languages like English or Spanish, German has certain features that makes it harder to learn. For example, it has a noun gender system where each noun can be one of three genders and each gender has to be inflected differently. These genders are random enough to cost a significant amount time while learning it as a second language.
Unfortunately, I haven't found any authoritative data on how much harder German exactly is to learn, compared to other languages. It is not possible to exactly quantify language difficulty, because it not only depends on the language itself but also on the native language of the learner, their age, their motivation, and so on. Any data I present below are anecdotal and should be taken with a grain of salt.
That being said, the fact that German is harder to learn as a second language compared to, say, English, is self-evident to most people who have tried to learn both from the beginner level. So the data below is still useful, because it visually represents this difference in difficulty.
### Hours required to reach B2 level
To begin with, [Goethe Institut](https://en.wikipedia.org/wiki/Goethe-Institut) has put up the following values for German on the FAQ section of their website[^1]:
> As a rough guideline, we estimate it will take the following amount of instruction to complete each language level:
>
> - A1 : approx. 60-150 hours (80-200 TU*)
> - A2 : approx. 150-260 hours (200-350 TU*)
> - B1 : approx. 260-490 hours (350-650 TU*)
> - B2 : approx. 450-600 hours (600-800 TU*)
> - C1 : approx. 600-750 hours (800-1000 TU*)
> - C2 : approx. 750+ hours (1000+ TU*)
>
> *TU = Teaching Unit; a teaching unit consists of 45 minutes of instruction.
The Goethe Institut website does not cite the study where these numbers come from. My guess is that they just published the number of hours spent for each level from their official curriculum.
Another low-reliability source that I found is the Babbel for Business Blog[^2]. They have published the following values for German, English, Spanish, and French:
| | A1 | A2 | B1 | B2 | C1 | C2 |
|--------|-----------|-------------|-----------|------------|-----------|------------|
| German | 60-150 h | 150-262 h | 262-487 h | 487-600 h | 600-750 h | 750-1050 h |
| English| 60-135 h | 135-150 h | 262-300 h | 375-450 h | 525-750 h | 750-900 h |
| Spanish| 60-75 h | 75-150 h | 150-300 h | 300-413 h | 413-675 h | 675-825 h |
| French | 60-135 h | 135-263 h | 263-368 h | 368-548 h | 548-788 h | 788-1088 h |
Note that the values for German are very close to those on the Goethe Institut website, so they were either taken from the same source, or the Babbel blog borrowed them from Goethe Institut. I could not trace a source for the values for English, Spanish, and French.
Plotting the lower bounds of the hours required to reach each CEFR level for German, English, Spanish, and French gives the following graph:

This picture intuitively makes sense. Spanish and English are easier compared to German and French, though I doubt Spanish is that much easier than the rest.
I then plot the lower-upper bound range of hours only for German and English, to make the difference more visible:

If we were to trust the blog post, we would have the following $P$ values for German and English:
| | $P_{\text{German}}$ | $P_{\text{English}}$
|--|--|--|
| Lower bound | 487 | 375 |
| Upper bound | 600 | 450 |
| Average | 543.5 | 412.5 |
I personally don't trust these values, because they don't come from any cited sources. However, I will use them simply because they reaffirm a well known fact, which I don't have the resources to prove scientifically:
$$
P_{\text{German}} > P_{\text{English}}
$$
### Average salary
German Federal Statistical Office (Destatis) publishes the average gross salary in Germany every year. The data from 2022[^3] cites the average hourly wage in Germany as 24.77 euros, which I will round up to $S \approx 25$ euros for simplicity. The average immigrant skilled worker most likely earns more than the average, but I will use this value as a lower bound.
### Migration rate
Destatis also published a press release in 2023[^4] that cites a sharp rise in labour migration in 2022. The number of foreign workers in Germany increased by 56,000 in 2022. I will round this up to $R \approx 60,000$ foreign workers per year, since the trend is upwards.
### Percentage of time spent learning the language
I could not find any data on this, so the best I can do is to assume a value that feels conservative enough not to be higher than the real value. I will assume that a quarter of the time spent learning the local language displaces work hours, i.e. $D \approx 0.25$.
### Final calculation
To summarize, we have the following values:
- It takes around $P \approx 544$ hours of study on average to reach B2 level in German, whereas it takes $P \approx 413$ hours for English.
- The average foreign worker earns $S \approx 25$ euros per hour.
- We assume that $D \approx 0.25$, i.e. quarter of the time spent learning the local language displaces work hours.
- The rate of immigration $R \approx 60,000$ foreign workers per year.
Plugging these values into our formula, we calculate the total value of wages lost per year to language learning for all foreign workers in Germany:
$$
C_{\text{total}} = 25 \times 0.25 \times 60,000 \times 544 = 204,000,000\;\text{euros}
$$
That is, over 200 million euros worth of wages are lost to---or in another perspective, spent on---language education of foreign workers, every year in Germany.
We can then calculate the total value of wages lost per year due to the difference in language complexity between German and English, using the formula we derived earlier:
$$
C_{\text{complexity}} = 25 \times 0.25 \times 60,000 \times (544 - 413) = 49,125,000\;\text{euros}
$$
In other words, the German economy loses at least 49 million euros per year, just because German is harder to learn compared to English.
## Conclusion
A lot of the assumptions I made in this case study are conservative:
- I assumed that the rate of immigration to Germany stays constant, whereas it is increasing year by year.
- I assumed that the average migrating skilled worker earns 25 euros per hour, whereas they most likely earn much more.
- I assumed that by the time you finish your B2 course, your German is good enough to start working, whereas it takes much longer to feel confident using the language in a professional setting.
The model further ignores the indirect costs of language complexity, such as not being able to integrate into the society, or even people not moving to Germany in the first place because of the language barrier. Considering those factors, how much higher would you expect the burden of language complexity to be? 100 million euros? 1 billion euros?
What is the cost of not being able to:
- communicate effectively with your colleagues, your boss, your customers?
- read the news, the laws, the contracts?
- understand the culture, the jokes, the idioms?
- express yourself, your ideas, your feelings?
But above all, what does it cost a country if it is unable to teach its language effectively or spread its culture?
*Immeasurable.*
Should an immigrant take a language curriculum at face value, if the majority of the people who take it after a certain age can never speak as perfect as native level, and end up speaking some simplified grammar at best?
*No.*
### References
[^1]: [How long does it take to learn German?](https://web.archive.org/web/20231030173211/https://www.goethe.de/ins/gb/en/sta/lon/kur/faq.html#accordion_toggle_6206750_2), FAQ Page, Goethe Institut
[^2]: [How Long Does It Take to Learn a Language?](https://web.archive.org/web/20231201001021/https://www.babbelforbusiness.com/us/blog/how-long-does-it-take-to-learn-a-language/), Anika Wegner, Babbel for Business Blog, 2023-09-01
[^3]: [Earnings by economic branch and occupation](https://web.archive.org/web/20230621075721/https://www.destatis.de/EN/Themes/Labour/Earnings/Branch-Occupation/_node.html), German Federal Statistical Office (Destatis), 2023-06-21
[^4]: [Sharp rise in labour migration in 2022](https://web.archive.org/web/20240221153647/https://www.destatis.de/EN/Press/2023/04/PE23_165_125.html), German Federal Statistical Office (Destatis), 2023-04-27
==========
---
title: "Could this be it? @allen_ai"
date: 2024-02-02
canonical: https://solmaz.io/x/1753381325472481507/
x_url: https://x.com/onusoz/status/1753381325472481507
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Could this be it? @allen_ai
https://blog.allenai.org/olmo-open-language-model-87ccfc95f580
*Quotes a post by another author (https://x.com/i/status/1747671579985928603); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "@xkcd1963 @togethercompute github.com/ggerganov/llam…"
date: 2023-12-13
canonical: https://solmaz.io/x/1735013963706904775/
x_url: https://x.com/onusoz/status/1735013963706904775
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
@xkcd1963 @togethercompute https://github.com/ggerganov/llama.cpp/blob/master/grammars/README.md
==========
---
title: "“the QIPS Exchange -- the marketplace where processing power was bought and sold. The..."
date: 2023-10-27
canonical: https://solmaz.io/x/1717860276811272428/
x_url: https://x.com/onusoz/status/1717860276811272428
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
“the QIPS Exchange -- the marketplace where processing power was bought and sold. The connection to JSN had passed through the Exchange, transparently; her terminal was programmed to bid at the market rate automatically, up to a certain ceiling.”
- Permutation City
*Quotes a post by another author (https://x.com/i/status/1717488939282674157); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Created a wordcloud version of the Cognitive Bias Codex by @jm3 and @buster. Font size is..."
date: 2023-06-19
canonical: https://solmaz.io/x/1670829551755366400/
x_url: https://x.com/onusoz/status/1670829551755366400
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Created a wordcloud version of the Cognitive Bias Codex by @jm3 and @buster. Font size is proportional to Google search result count, which roughly measures each term's popularity.
Read more: https://osolmaz.github.io/blog/cognitive-biases-ranked-by-popularity
==========
---
title: "Had lots of fun shipping this feature ✌️"
date: 2023-06-17
canonical: https://solmaz.io/x/1670059853245710336/
x_url: https://x.com/onusoz/status/1670059853245710336
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Had lots of fun shipping this feature ✌️
*Quotes a post by another author (https://x.com/i/status/1669678794951516162); its text is omitted here because it is not covered by this site's license.*
==========
---
title: "Cognitive Biases Ranked by Popularity"
date: 2023-06-17
canonical: https://solmaz.io/cognitive-biases-ranked-by-popularity
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you have spent some time on rationalist forums, you might have come across images that try to visualize [cognitive biases](https://en.wikipedia.org/wiki/List_of_cognitive_biases) that humans are prone to:

This [specific one](https://www.designhacks.co/products/cognitive-bias-codex-poster) has been created by [John Manoogian III](https://twitter.com/jm3) and [Buster Benson](https://twitter.com/buster), who compiled the list of biases from [Wikipedia](https://en.wikipedia.org/wiki/List_of_cognitive_biases).
It is a great way to get a sense of the sheer number of biases that exist, but it doesn't tell you much about how much of the popular mindshare each bias has. All the biases having the same size implies that they are all equally important, but that is obviously not the case. Arguably, for someone who has just started to learn about cognitive biases, *confirmation bias* should be more important than, say, the *Peltzmann effect*.
To measure and visualize the popularity of each bias, I...
- ran a Google search with the format `"" cognitive bias` using a [SERP](https://en.wikipedia.org/wiki/Search_engine_results_page) API,
- got the number of search results for each term,
- created a wordcloud using the [wordcloud Python package](https://pypi.org/project/wordcloud/),
- used logarithms of the search count for better scaling,
- used the same colors as the Cognitive Bias Codex for consistency,
- used a shape mask of a brain to make it look cool.
Here is the result:

The bigger the font, the more Google search results there are for that bias, the assumption being Google search results are a good measure of popularity.
Why should you care about the popularity of biases? The more popular or common a bias is, the more likely you are to be affected by it. So it makes sense to study them in decreasing order of popularity, to maximize the benefit to your own thinking. However, this is all statistics---you could still be impacted more by a bias that is smaller in the wordcloud. For example, there was a time when I was very prone to the *sunk cost fallacy*, even though it doesn't show up so large in the wordcloud.
Below is a version of the image without the shape mask:

Below are the top 10 biases ranked by Google search result count:
| Cognitive bias | Search result count |
| --- | ---: |
| Prejudice | 8,560,000 |
| Anchoring | 1,100,000 |
| Stereotyping | 1,080,000 |
| Confirmation bias | 992,000 |
| Conservatism | 610,000 |
| Essentialism | 436,000 |
| Loss aversion | 426,000 |
| Attentional bias | 374,000 |
| Curse of knowledge | 373,000 |
| Social desirability bias | 319,000 |
[Click here](https://github.com/osolmaz/blob/main/_appendix/cognitive-biases-ranked-by-popularity/search_result_count.csv) to see the search result counts for each 188 biases included above.
I have also computed the average search result count for each category of biases, by dividing the total search result count for each category by the number of biases in that category:
| Category | Average count |
| --- | ---: |
| We discard specifics to form generalities | 1,494,378 |
| We notice when something has changed | 237,141 |
| We fill in characteristics from stereotypes, generalities, and prior histories | 160,170 |
| We are drawn to details that confirm our own existing beliefs | 93,350 |
| We think we know what other people are thinking | 81,555 |
| To act, we must be confident we can make an impact and feel what we do is important | 72,435 |
| We notice things already primed in memory or repeated often | 70,835 |
| To get things done, we tend to complete things we've invested time and energy in | 65,822 |
| To avoid mistakes, we aim to preserve autonomy and group status, and avoid irreversible decisions | 65,750 |
| We edit and reinforce some memories after the fact | 59,503 |
| We favor simple-looking options and complete information over complex, ambiguous options | 52,491 |
| We tend to find stories and patterns even when looking at sparse data | 46,375 |
| To stay focused, we favor the immediate, relatable thing in front of us | 37,940 |
| Bizarre, funny, visually striking, or anthropomorphic things stick out more than non-bizarre/unfunny things | 37,081 |
| We imagine things and people we're familiar with or fond of as better | 34,379 |
| We simplify probabilities and numbers to make them easier to think about | 33,881 |
| We notice flaws in others more easily than we notice flaws in ourselves | 31,390 |
| We project our current mindset and assumptions onto the past and future | 29,418 |
| We reduce events and lists to their key elements | 27,638 |
| We store memories differently based on how they were experienced | 20,440 |
Notice that the top few biases such as *prejudice* and *anchoring* highly skew the ranking.
Similarly, I have computed the average search result count for each top category of biases:
| Top category | Average count |
| --- | ---: |
| What Should We Remember? | 316,297 |
| Too Much Information | 101,842 |
| Need To Act Fast | 64,568 |
| Not Enough Meaning | 64,134 |
You can see the code I used to create the figure [here](https://github.com/osolmaz/tree/main/_appendix/cognitive-biases-ranked-by-popularity).
I will not try to reason as to why some biases are more popular than others, and instead leave that for another post.
==========
---
title: "If you are interested in using Manim Voiceover, auto-translating your videos into other..."
date: 2023-05-18
canonical: https://solmaz.io/x/1659238851171295232/
x_url: https://x.com/onusoz/status/1659238851171295232
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
If you are interested in using Manim Voiceover, auto-translating your videos into other languages, or any other cool stuff, hit me up in a DM!
==========
---
title: "I've just published *Code-Driven Videos*, my long term vision behind Manim Voiceover plugin. I..."
date: 2023-05-18
canonical: https://solmaz.io/x/1659238831579619328/
x_url: https://x.com/onusoz/status/1659238831579619328
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I've just published *Code-Driven Videos*, my long term vision behind Manim Voiceover plugin. I will try to summarize it on this thread 👇🧵
cc @manim_community
https://osolmaz.github.io/blog/code-driven-videos
==========
---
title: "Code-Driven Videos"
date: 2023-05-11
canonical: https://solmaz.io/code-driven-videos
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
> **tl;dr** I created [Manim Voiceover](https://voiceover.manim.community/en/stable/), a plugin for the Python math animation library [Manim](https://www.manim.community/) that lets you add voiceovers to your Manim videos directly in Python, with both AI voices or actual recordings.
>
> This makes it possible to create "fully code-driven" educational videos in pure Python. Videos can be developed like software, taking advantage of [version controlled](https://en.wikipedia.org/wiki/Version_control), git-based workflows (i.e. no more Final.final.final.mp4 :),
>
> It also makes it possible to use AI to automate all sorts of things. For example, I have created a pipeline for translating videos into other languages automatically with i18n ([gettext](https://en.wikipedia.org/wiki/Gettext)) and machine translation ([DeepL](https://www.deepl.com/)).
>
> [Follow my Twitter](https://twitter.com/onusoz) to get updates on Manim Voiceover.
## A little background
For those who are not familiar, Manim is a Python library that lets you create animations programmatically, created by Grant Sanderson, a.k.a. [3blue1brown](https://en.wikipedia.org/wiki/3Blue1Brown). His visual explainers are highly acclaimed and breathtakingly good (to see an example, [click here](https://www.youtube.com/watch?v=aircAruvnKk) for his introduction to neural networks).
Manim was originally built for animating math, but [you can already see it being used in other domains](https://github.com/ManimCommunity/awesome-manim) such as physics, chemistry, computer science, and so on.
Creating any video is a very time-consuming process. Creating an explainer that needs to be mathematically exact is even more so, because the visuals often need to be precise to convey knowledge efficiently. That is why Manim was created: to automate the animation process. It turns out programming mathematical structures is easier than trying to animate them in a video editor.
However, this results in a workflow that is part spent in the text editor (writing Python code), and part in the video editor (editing the final video), with a lot of back and forth in between. The main reason is that the animation needs to be synced with voiceovers, which are recorded separately.
In this post, I will try to demonstrate how we can take this even further by making voiceovers a part of the code itself with [Manim Voiceover](https://voiceover.manim.community/en/stable/), and why this is so powerful.
## The traditional workflow
Creating a video with Manim is very tedious. The steps involved are usually as follows:
1. **Plan:** come up with a script and a screenplay.
2. **Record:** Record the voiceover with a microphone.
3. **Animate:** Write the Python code for each scene, that will generate the animation videos.
4. **Edit:** Overlay and synchronize the voiceover and animations in a video editor, such as Adobe Premiere.
The workflow is often not linear. The average video requires you to rewrite, re-record, re-animate and re-sync multiple scenes:

The less experience you have making videos, the more takes you will need. Creating such an explainer has a very steep [learning curve](https://en.wikipedia.org/wiki/Learning_curve). It can take up to 1 month for a beginner to create their first few minutes of video.
## Enter Manim Voiceover
I am a developer by trade, and when I first tried to create a video with the traditional workflow, I found it harder than it should be. We developers are spoiled, because we get to enjoy automating our work. Imagine that you had to manually compile your code using a [hex editor](https://en.wikipedia.org/wiki/Hex_editor) every time you made a change. That is what it felt like to create a video using a video editor. The smallest change in the script meant that I had to re-animate, re-record and re-sync parts of the video, the main culprit being the voiceover.
To overcome this, I thought of a simple idea: Create an API that lets one to add voiceovers directly in Python. [Manim Voiceover](https://voiceover.manim.community/en/stable/) does exactly that and provides a comprehensive framework for automating voiceovers. Once the entire production can be done in Python, editing in the video editor becomes mostly unnecessary. The workflow becomes:
1. **Plan:** Same as before.
2. **Animate:** Develop the video with an AI-generated voiceover, all in Python.
3. **Record:** When the final revision is ready, record the actual voiceover with Manim Voiceover's recorder utility. The audio is transcribed with timestamps and inserted at the right times automatically.
A little demo---see how a video would look like at the end of step (2):
And watch below to see how it would look like at the end of step (3), with my own voice:
I explain why this is so powerful below:
### Zero-cost revisions
In the previous method, making modifications to the script has a cost, because you need to re-record the voiceover and readjust the scenes in the video editor. Here, making modifications is as easy as renaming a variable, since the AI voiceover is generated from code automatically. This saves a lot of time in the production process:

This lets videos created with Manim to be "fully code-driven" and take advantage of open source, collaborative, [git-based workflows](https://en.wikipedia.org/wiki/Git). No manual video editing needed, and no need to pay for overpriced video editing software:
(Or at least drastically reduced need for them)
### Increased production speed
From personal experience and talking to others who have used it, [Manim Voiceover](https://voiceover.manim.community/en/stable/) increases production speed by a factor of at least 2x, compared to manual recording and editing.
> Note: The current major bottlenecks are developing the scene itself and waiting for the render. Regarding render speed: [Manim CE](https://www.manim.community/)'s [Cairo](https://www.cairographics.org/) renderer is much slower then [ManimGL](https://3b1b.github.io/manim/)'s [OpenGL](http://www.opengl.org/) renderer. Manim Voiceover currently only supports Manim CE, but it is on my roadmap to add support ManimGL.
## The API in a nutshell
This all sounds great, but how does it look like in practice? Let's take a look at the API. Here is a "Hello World" example for Manim, drawing a circle:
```python
from manim import *
class Example(Scene):
def construct(self):
circle = Circle()
self.play(Create(circle))
```
Here is the same scene, with a voiceover that uses Google Translate's free text-to-speech service:
```python
from manim import *
from manim_voiceover import VoiceoverScene
from manim_voiceover.services.gtts import GTTSService
class VoiceoverExample(VoiceoverScene):
def construct(self):
self.set_speech_service(GTTSService(lang="en"))
circle = Circle()
with self.voiceover(text="This circle is drawn as I speak."):
self.play(Create(circle))
```
Notice the `with` statement. You can chain such blocks back to back, and Manim will vocalize them in sequence:
```python
with self.voiceover(text="This circle is drawn as I speak."):
self.play(Create(circle))
with self.voiceover(text="Let's shift it to the left 2 units."):
self.play(circle.animate.shift(2 * LEFT))
```
The code for videos made with Manim Voiceover generally looks cleaner, since it is compartmentalized into blocks with voiceovers acting as annotations on top of each block.
See how this is rendered:
### Record
To record an actual voiceover, you simply change a single line of code:
```python
# self.set_speech_service(GTTSService(lang="en")) # Comment this out
self.set_speech_service(RecorderService()) # Add this line
```
Currently, rendering with `RecorderService` starts up a voice recorder implemented as a command line utility. The recorder prompts you to record each voiceover in the scene one by one and inserts audio at appropriate times. In the future, a web app could make this process even more seamless.
Check out [the documentation](https://voiceover.manim.community/) for more examples and the API specification.
## Auto-translating videos
Having a machine readable source for voiceovers unlocks another superpower: automatic translation. Manim Voiceover can automatically translate your videos to any language, and even generate subtitles in that language. This will let educational content creators reach a much wider audience.
Here is an example of the demo translated to Turkish and rendered with my own voice:
To create this video, I followed these steps:
1. I wrapped transtable strings in my demo inside `_()` per [gettext](https://en.wikipedia.org/wiki/Gettext) convention. For example, I changed `text="Hey Manim Community!"` to `text=_("Hey Manim Community!")`.
2. I ran `manim_translate blog-translation-demo.py -s en -t tr -d blog-translation-demo`, which created the `locale` folder, called [DeepL's API](https://www.deepl.com/docs-api) to translate the strings, and saved them under `locale/tr/LC_MESSAGES/blog-translation-demo.po`.
- Here, `-s` stands for source language,
- `-t` stands for target language,
- and `-d` stands for the gettext domain.
3. I edited the `.po` file manually, because the translation was still a bit off.
4. I ran `manim_render_translation blog-translation-demo.py -s BlogTranslationDemo -d blog-translation-demo -l tr -qh`, which rendered the final video.
Check out the [translation page in the docs](https://voiceover.manim.community/en/stable/translate.html) for more details. You can also find the source code for this demo [here](https://github.com/osolmaz/tree/main/_appendix/code-driven-videos).
Here is a Japanese translation, created the same way but with an AI voiceover:
Note that I have very little knowledge of Japanese so that the translation might be off, but I was still able to create it with services that are freely available online. This is to foreshadow how communities could create and translate educational videos in the future:
1. Video is created using Manim/Manim Voiceover and is open-sourced.
2. The repo is connected to a CI/CD service that tracks the latest changes, re-renders and deploys the video to a permalink.
3. When a translation in a language is requested, said service automatically generates it using AI translation and voiceover.
4. The community can then review the translation and voiceover, make changes if necessary, and record a human voiceover if they want to.
5. All the different versions and translations of the video are seamlessly deployed, similar to how [ReadTheDocs](https://readthedocs.org/) deploys software documentation.
That is the main idea of my next project, GitMovie. If this excites you, leave your email address on the form on the website to get notified when it launches.
## Conclusion
While using Manim Voiceover might seem tedious to some who are already using Manim with a video editor, I guarantee that it is overall more convenient than using a video editor when it comes to adding voiceovers to scenes. [Feel free to create an issue](https://github.com/ManimCommunity/manim-voiceover/issues/new/choose) if you have a use case that is currently not covered by Manim Voiceover.
What is even more interesting, Manim Voiceover can provide [AI models such as GPT-4](https://en.wikipedia.org/wiki/Large_language_model) with a convenient way to generate mathematically precise videos. Khan Academy has recently debuted a private release of [Khanmigo, their GPT-4 based AI teacher](https://www.khanacademy.org/khan-labs). Imagine that Khanmigo could create a 3blue1brown-level explainer in a matter of minutes, for any question you ask! (I already tried to make GPT-4 output Manim code, but it is not quite there yet.)
To see why this is powerful, check out [my video rendering of Euclid's Elements using Manim Voiceover (part 1)](https://github.com/osolmaz/manim-euclid-elements):
This video itself is pedagogically not very effective because books do not necessarily translate into good video scripts. But it serves as preparation for the point that I wanted to make with this post:
> Having a machine-readable source and being able to program voiceovers allowed me to generate over 10 hours of video in less than a few days. In a few years, AI models will make such approaches 1000 times easier, faster and cheaper for everyone.
Imagine being able to auto-generate the "perfect explainer" for every article on Wikipedia, every paper on arXiv, every technical specification that would otherwise be too dense. In every language, available instantly around the globe. Universal knowledge, accessible by anyone who is willing to learn. Thanks to 3blue1brown, Manim and similar open source projects, all of this will be just a click away!
==========
---
title: "You can now translate voiceovers in your Manim scenes into other languages using @DeepLcom"
date: 2023-01-22
canonical: https://solmaz.io/x/1617110999458545664/
x_url: https://x.com/onusoz/status/1617110999458545664
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
You can now translate voiceovers in your Manim scenes into other languages using @DeepLcom
Blog post with examples coming soon
@manim_community
https://voiceover.manim.community/en/stable/translate.html
==========
---
title: "Revamp complete docs.textcortex.com @TextCortex"
date: 2023-01-17
canonical: https://solmaz.io/x/1615297878808989697/
x_url: https://x.com/onusoz/status/1615297878808989697
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Revamp complete https://docs.textcortex.com @TextCortex
==========
---
title: "Here is a short video showing how recording a voiceover works in Manim Voiceover. A better..."
date: 2022-12-08
canonical: https://solmaz.io/x/1600811245434707968/
x_url: https://x.com/onusoz/status/1600811245434707968
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Here is a short video showing how recording a voiceover works in Manim Voiceover. A better tutorial will come soon @manim_community
https://www.youtube.com/watch?v=HawoHpR45pc
==========
---
title: "Adding voiceovers to Manim videos just got *much* easier @manim_community"
date: 2022-12-04
canonical: https://solmaz.io/x/1599387995336867840/
x_url: https://x.com/onusoz/status/1599387995336867840
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Adding voiceovers to Manim videos just got *much* easier @manim_community
https://docs.manim.community/en/stable/guides/add_voiceovers.html
==========
---
title: "Microtonal Piano"
date: 2022-10-18
canonical: https://solmaz.io/microtonal-piano
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I built a [web-based microtonal piano](https://osolmaz.github.io/microtonal-piano/) that lets you explore music beyond the standard 12-tone equal temperament.
Most Western music uses 12 equally spaced notes per octave. But this is just one of many possible tuning systems. Microtonal music explores the spaces between these notes, using tuning systems with different numbers of divisions per octave or entirely different mathematical relationships between pitches.
The app lets you:
- Play with different tuning systems (various equal temperaments, just intonation, etc.)
- Hear how the same melody sounds in different tunings
- Explore the mathematical relationships between pitches
Try it out: [osolmaz.github.io/microtonal-piano](https://osolmaz.github.io/microtonal-piano/)
==========
---
title: "Take Control of Your Feeds"
date: 2020-04-26
canonical: https://solmaz.io/thoughts/digital-hygiene-feeds
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A digital feed is an online stream of content which gets updated as new content is pushed by the feed’s sources. Generally, content is created by users on the social media platform, to be consumed by their followers.
All popular social media platforms feature some type of feed: Twitter, Instagram, Reddit, Facebook. Operators of these platforms benefit from increased engagement by their users, so they employ techniques designed to achieve that end. Unfortunately, they often do so at the expense of their users’ well-being. Below are 7 rules to help you retain control over your screen time, without having to leave social media for good, ordered from most important to least important.
## Rule #1: Avoid non-chronological feeds
On most online platforms, the order of content is determined by an algorithm designed to maximize user engagement, i.e. addict you and keep you looking at ads for as long as possible. Examples: Facebook news feed, Twitter “top tweets”, Instagram explore tab, Tiktok.
## Rule #2: No feeds or social media apps on the phone
Your phone is always within your reach. Access feeds only on your laptop, in order not to condition yourself to constantly check it. Don't install social media or video apps on your phone.
## Rule #3: Follow with purpose
Your digital experience changes with each new person/source you follow. Be mindful about the utility of the information you would obtain before following a new source.
## Rule #4: Limit the number of people/things you follow
The amount of content you will have to go through increases roughly linearly with the number of sources you follow. You probably won’t see everything your 500 followees share—maybe it’s time to unfollow some of them.
## Rule #5: Schedule and limit your exposure
Your brain has a limited capacity to process and hold information. Schedule a certain hour of the day to receive it, and don’t surpass it. Example: No more than 30 minutes of social media, restricted to 10–11 am.
## Rule #6: Block generously and ruthlessly
If you don’t like what you’re seeing, block or unfollow *immediately*. This is the hardest when someone posts content that is sometimes useful, but otherwise annoying too. Generally, we put up with it for too long until we block someone.
## Rule #7: Mute words
Avoid toxic memes by muting related words, e.g. Trump, ISIS. This will filter out any post that contains that word. Click [here](https://twitter.com/settings/muted_keywords) to do it on Twitter now---it's easy.
Follow these simple set of rules, and restore your control over social media and your digital experience in no time.
==========
---
title: "Blockchain Fee Volatility"
date: 2019-10-21
canonical: https://solmaz.io/2019/10/21/gas-price-fee-volatility/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Ethereum is a platform for distributed computing that uses a blockchain for data
storage, thus inheriting the many benefits blockchain systems enjoy, such as
decentralization and permissionlessness. It also inherited the idea of users
paying nodes a fee to get their transactions included in the blockchain. After
all, computation on the blockchain is not an infinite resource, and it should be
allocated to users who actually find value in it. Otherwise, a feeless
blockchain can easily be spammed and indefinitely suffer a denial-of-service
attack.
Blockchain state advances on a block by block basis. On a smart contract
platform, the quantity of computation as a resource is measured in terms of the
following factors:
- **Bandwidth:** The number of bits per unit time that the network can achieve
consensus on.
- **Computing power:** The average computing power of an individual node.
- **Storage:** The average storage capacity of an individual node.
The latter two are of secondary importance, because the bottleneck for the
entire network is not the computing power or storage capacity of an individual
node, but the overall speed of communicating the result of a computation to the
entire network. In Bitcoin and Ethereum, that value is around 13 kbps[^1],
calculated by dividing average full block size by average block time. Trying to
increase that number, either by increasing the maximum block size or decreasing
block time, indeed results in increased computational capacity. However it also
increases the uncle rate[^2], thereby decreasing the quality of consensus---a
blockchain’s main value proposition.
Moreover, users don’t just submit bits in their transactions. In Bitcoin, they
submit inputs, outputs, amounts etc[^3]. In Ethereum, they can just submit a sender
and a receiver of an amount of ETH, or they can also submit data, which can be
an arbitrary message, function call to a contract or code to create a contract.
This data, which alters Ethereum’s world state, is permanently stored on the
blockchain.
Ethereum is Turing complete, and users don’t know when and in which order miners
will include their transactions. In other words, users have no way of predicting
with 100% accuracy the total amount of computational resources their function
call will consume, if that call depends on the state of other accounts or
contracts[^4]. Furthermore, even miners don’t know it up until the point they finish
executing the function call. This makes it impractical for users to set a lump
sum fee that they are willing to pay to have their transaction included, because
a correlation between a transaction’s fee and its utilization of resources
cannot be ensured.
To solve this problem, Ethereum introduced the concept of gas as a unit of
account for the cost of resources utilized during transaction execution. Each
instruction featured in the Ethereum Virtual Machine has a universally agreed
cost in gas, proportional to the scarcity of the used resource[^5]. Then instead of
specifying a total fee, users submits a gas price in ETH and the maximum total
gas they are willing to pay.
The costliest operations on Ethereum are those of non-volatile storage and
access[^6], but these need not occupy space in a block. It’s the transactions
themselves that are stored in the blocks and thus consume bandwidth. The gas
corresponding to this consumption is called “intrinsic gas” (see the Yellow
Paper), and it’s one of the reasons for the correlation between gas usage and
block size:
The vertical clusterings at 4.7m, 6.7m and 8m gas correspond to current and
previous block gas limits. Gas costs of instructions should indeed be set in
such a way that the correlation between a resource and overall gas usage should
increase with the degree of bottleneck.
## Gas Supply and Demand
The demand for transacting/computing on creates its own market, both similar and
dissimilar to the markets of tangible products that we are used to. What is more
important to us is the supply characteristics of this market. Supplied
quantities aren’t derived from individual capacities and decisions of the
miners, but from network bottlenecks. A limit is set on maximum gas allowed per
block.
Supplied quantity is measured in terms of gas supplied per unit time, similar to
bandwidth. Individual miners contribute hashrate to the network, but this
doesn’t affect throughput. The difficulty adjustment mechanism ensures that
network throughput remains the same, unless universally agreed parameters are
changed by collective decision.
Moreover, the expenditure of mining a block far exceeds the expenditure of
executing a block. In other words, changes in overall block fullness doesn’t
affect miner operating expenses. Therefore, marginal cost is roughly zero, up
until the point supply hits maximum throughput---where blocks become 100% full. At
that point, marginal cost becomes infinite. This is characterized by a **vertical
supply curve** located at maximum throughput, preceded by a horizontal supply
curve.
This means that given a generic monotonically decreasing demand curve and a
certain shift in demand, we can predict the change in the gas price, and vice
versa. The price is located at the point where the demand curve intersects the
supply curve. Major shifts in price starts to occur only when blocks become
full. Past that point, users are basically bidding higher and higher prices to
get their transactions included. See the figure below for an illustration.
This sort of econometric analysis can be done simply by looking at block
statistics. Doing so reveals 2 types of trends in terms of period:
- Intraday volatility: Caused by shifts in demand that repeat periodically every
day.
- Long term shifts: Caused by increases or decreases in the level of adoption, and
not periodic.
Note: This view of the market ignores block rewards, but that is OK in terms of
analyzing gas price volatility, because block rewards remain constant for very
long periods of time. However, a complete analysis would need to take block
rewards into account, because they constitute the majority of miner revenue.
## Daily Demand Cycle and Intraday Volatility
Demand for gas isn’t distributed equally around the globe. Ethereum users exist
in every inhabited continent, with the highest demand seen in East Asia,
primarily China. Europe+Africa and the Americas seem to be hand in hand in terms
of demand. This results in predictable patterns that follow the peaks and
troughs of human activity in each continent. The correlation between gas usage
and price is immediately noticeable, demonstrated by a 5 day period from March
2019.
The grid marks the beginnings of the days in UTC, and the points in the graph
correspond to hourly averages, calculated as:
- Average hourly gas usage per block = Total gas used in an hour / Number of
blocks in an hour
- Average hourly gas price = Total fees collected in an hour / Total gas used in
an hour
Averaging hourly gives us a useful benchmark to compare, because block-to-block
variation in these attributes is too much for an econometric analysis.
One can see above that the average gas price can change up to 2 to 4 times in a
day. This shows us that Ethereum has found real use around the world, but also
that there exists a huge UX problem in terms of gas prices.
Dividing the maximum gas price in a day by the minimum, we obtain a factor of
intraday volatility:
Ethereum has witnessed gas price increases of up to 100x in a day. Smoothing out
the data, we can see that the gas price can change up to 4x daily on average.
To understand the effect of geographic distribution on demand, we can process
the data above to obtain a daily profile for gas usage and price. We achieve
this by dividing up the yearly data set into daily slices, and standardizing
each slice in itself. Then the slices are superimposed and their mean is
calculated. The mean curve, though not numerically accurate, makes sense in
terms of ordinal difference between the hours of an average day.
One can clearly see that gas usage and price are directly correlated. At 00:00
UTC, it’s been one hour since midnight in Central Europe, but that’s no reason
for a dip in demand---China just woke up. The first dip is seen at 03:00 when the
US is about to go to sleep, but then Europe wakes up. The demand dips again
after 09:00, but only briefly---the US just woke up. We then encounter the biggest
dip from 15:00 to 23:00 as China goes to sleep.
Surely there must be a way to absorb this volatility! Solving this problem would
greatly improve Ethereum’s UX and facilitate even greater mainstream adoption.
## Long Term Shifts in Demand
The long term---i.e. $\gg$ 1 day---shifts in demand are unpredictable and non-periodic.
They are caused by adoption or hype for certain applications or use cases on
Ethereum, like
- ICOs,
- decentralized exchanges,
- DAI and CDPs,
- interest bearing Dapps,
- games such as Cryptokitties and FOMO3D,
- and so on.
These shifts in price generally mirror ETH’s own price. In fact, it’s not very
objective to plot a long term gas price graph in terms of usual Gwei, because
most people submit transactions considering ETH’s price in fiat. For that
reason, we denote gas price in terms of USD per one million gas, and plot it on
a logarithmic scale:
The price of gas has seen an increase of many orders of magnitude since the
launch of the mainnet. The highest peak corresponds to the beginning of 2018
when the ICO bubble burst, similar to the price of ETH. Although highly critical
for users and traders, this sort of price action is not very useful from a
modeling perspective.
## Conclusion
The volatility in gas price stems from the lack of scalability. In 2019 on Ethereum,
daily gas price difference stayed over 2x on average. The cycle’s
effect is high enough to consider it as a recurring phenomenon that requires its
own solution.
I think the narrative that gas price volatility is caused only by the occasional
game/scam hype is incomplete—in a blockchain that has gained mainstream adoption
such as Ethereum, the daily cycle of demand by itself is enough to cause
volatility that harms the UX for everyone around the globe.
While increasing scalability is the ultimate solution, users may still benefit
from mechanisms that allow them to hedge themselves against price increases,
like reserving gas on a range of block heights. This would make a good topic for
a future post.
[^1]: As of October 2019.
[^2]: The rate at which orphaned blocks show up.
[^3]: [https://en.bitcoin.it/wiki/Transaction](https://en.bitcoin.it/wiki/Transaction)
[^4]: But in practice, they can estimate it reliably most of the time.
[^5]: See Appendix G (Fee Schedule) and H (Virtual Machine Specification) of the [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf).
[^6]: [https://medium.com/coinmonks/storing-on-ethereum-analyzing-the-costs-922d41d6b316](https://medium.com/coinmonks/storing-on-ethereum-analyzing-the-costs-922d41d6b316)
==========
---
title: "Equilibrium in Cryptoeconomic Networks"
date: 2019-04-20
canonical: https://solmaz.io/2019/04/20/equilibrium-cryptoeconomic-networks/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A cryptoeconomic network is a network where
- nodes perform tasks that are useful to the network,
- incur costs while doing so,
- and get compensated through fees paid by the network users, or rewards
generated by the network's protocol (usually in the form of a currency native
to the network).
Reward generation causes the supply of network currency to increase,
resulting in inflation. Potential nodes are incentivized to join the network
because they see there is profit to be made, especially if they are one of the
early adopters. This brings the notion of a "cake" being shared among nodes,
where the shares get smaller as the number of nodes increases.
Since one of the basic properties of a currency is finite supply, a sane
protocol cannot have the rewards increase arbitrarily with more nodes. Thus the
possible number of nodes is finite, and can be
calculated using costs and rewards, given that **transaction fees are negligible**.
The rate by which
rewards are generated determines the sensitivity of network
size to changes in costs and other factors.
Let $N$ be the number of nodes in a network, which perform the same work during
a given period. Then we can define a generalized reward per node, introduced by Buterin[^1]:
$$
r = R_0 N^{-\alpha}
\tag{1}
$$
where $R_0$ is a constant and $\alpha$ is a parameter adjusting how the
rewards scale with $N$.
Then the total reward issued is equal to
$$
R = N r = R_0 N^{1-\alpha}.
$$
The value of $\alpha$ determines how the rewards scale with $N$:
| Range | Per node reward $r$ | Total reward $R$ |
| - | - | - |
| $\alpha < 0$ | Increase with increasing $N$ | Increase with increasing $N$ |
| $ 0 < \alpha < 1$ | Decrease with increasing $N$ | Increase with increasing $N$ |
| $\alpha > 1$ | Decrease with increasing $N$ | Decrease with increasing $N$ |
Below is a table showing how different values of $\alpha$
corresponds to different rewarding schemes, given full participation.
| $\alpha$ | $r$ | $R$ | Description |
| - | - | - | - |
| $0$ | $R_0$ | $R_0 N$ | Constant interest rate |
| $1/2$ | $R_0/\sqrt{N}$ | $R_0 \sqrt{N}$ | Middle ground between 0 and 1 (Ethereum 2.0) |
| $1$ | $R_0/N$ | $R_0$ | Constant total reward (Ethereum 1.0, Bitcoin in the short run) |
| $\infty$ | $0$ | $0$ | No reward (Bitcoin in the long run) |
The case $\alpha \leq 0$ results in unlimited network growth, causes runaway
inflation and is not feasible. The case $\alpha > 1$ is also not feasible due to
drastic reduction in rewards. The sensible range is $0 < \alpha \leq 1$, and we
will explore the reasons below.
## Estimating Network Size
We relax momentarily the assumption that nodes perform the same amount of work.
The work mentioned here can be the hashing power contributed by a node in a PoW
network, the amount staked in a PoS network, or the measure of dedication in any
analogous system.
Let $w_i$ be the work performed by node $i$. Assuming that costs are incurred in
a currency other than the network's---e.g. USD---we have to take the price of
the network currency $P$ into account. The expected value of $i$'s reward is
calculated analogous to (1)
$$
E(r_i) = \left[\frac{w_i}{\sum_{j} w_j}\right]^\alpha P R_0
$$
Introducing variable costs $c_v$ and fixed costs $c_f$, we can calculate
$i$'s profit as
$$
E(\pi_i) = \left[\frac{w_i}{\sum_{j} w_j}\right]^\alpha P R_0 - c_v w_i - c_f
$$
Assuming every node will perform work in a way to maximize profit, we can
estimate $w_i$ given others' effort:
$$
\frac{\partial}{\partial w_i} E(\pi_i)
= \frac{\alpha \,w_i^{\alpha-1}\sum_{j\neq i}w_j}{(\sum_{j}w_j)^{\alpha+1}}
- c_v = 0
$$
In a network where nodes have identical costs and capacities to work, all $w_j$
$j=1,\dots,N$ converge to the same equilibrium value $w^\ast$. Equating
$w_i=w_j$, we can solve for that value:
$$
w^\ast = \frac{\alpha(N-1)}{N^{\alpha+1}} \frac{P R_0}{c_v}.
$$
Plugging $w^\ast$ back above, we can calculate $N$ for the case of economic
equilibrium where profits are reduced to zero due to perfect competition:
$$
E(\pi_i)\bigg|_{w^\ast} = \left[\frac{1}{N}\right]^\alpha P R_0
-\frac{\alpha(N-1)}{N^{\alpha+1}} P R_0 - c_f = 0
$$
which yields the following implicit equation
$$
\boxed{
\frac{\alpha}{N^{\alpha+1}} + \frac{1-\alpha}{N^\alpha} = \frac{c_f}{P R_0}
}
$$
It is a curious result that for the idealized model above,
network size does not depend on variable
costs. In reality, however, we have an uneven
distribution of all costs and work capacities. Nevertheless, the idealized model
can still yield rules of thumb that are useful in protocol design.
An explicit form for $N$ is not possible, but we can calculate it for different
values of $\alpha$. For $\alpha=1$, we have
$$
N = \sqrt{\frac{P R_0}{c_f}}.
$$
as demonstrated by Thum[^2].
For $0<\alpha<1$, the explicit forms would take too much space. For brevity's
sake, we can approximate $N$ by
$$
N \approx \left[ (1-\alpha)\frac{P R_0}{c_f}\right]^{1/\alpha}
$$
given $N \gg 1$. The closer $\alpha$ to zero, the better the approximation.
We also have
$$
\lim_{\alpha\to 0^+} N = \infty.
$$
which shows that for $\alpha\leq 0$, the network grows without bounds and
render the network currency worthless by inflating it indefinitely.
Therefore there is no equilibrium.
For $\alpha > 1$, rewards and number of nodes decrease with increasing
$\alpha$. Finally, we have
$$
\lim_{\alpha\to\infty} N = 0
$$
given that transaction fees are negligible.
Number of nodes $N$ versus $P R_0/c_f$, on a log scale. The
straight lines were
solved for numerically, and corresponding approximations were overlaid with
markers, except for $\alpha=1$ and $2$.
For $0 <\alpha \ll 1$, a $C$x change in underlying factors will result in
$C^{1/\alpha}$x change in network size. For $\alpha=1$, the change will be
$\sqrt{C}$x.
Let $\alpha=1$. Then a
$2$x increase in price or rewards will result in a $\sqrt{2}$x increase in network
size. Conversely, a $2$x increase in fixed costs will result in $\sqrt{2}$x
decrease in network size. If we let $\alpha = 1/2$,
a $2$x change to the factors result in $4$x change in network size, and so on.
### References
[^1]: Buterin V., [Discouragement Attacks](https://github.com/ethereum/research/blob/master/papers/discouragement/discouragement.pdf), 16.12.2018.
[^2]: Thum M., [The Economic Cost of Bitcoin Mining](https://www.cesifo-group.de/DocDL/CESifo-Forum-2018-1-thum-bitcoin-march.pdf),
2018.
==========
---
title: "Scalable Reward Distribution with Changing Stake Sizes"
date: 2019-02-24
canonical: https://solmaz.io/2019/02/24/scalable-reward-changing/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This post is an addendum to the excellent paper
*Scalable Reward Distribution on the Ethereum Blockchain* by Batog et al.[^1]
The outlined algorithm describes a pull-based approach to distributing rewards
proportionally in a staking pool. In other words, instead of pushing
rewards to each stakeholder in a for-loop with $O(n)$ complexity, a
mathematical trick enables keeping account of the rewards with $O(1)$
complexity and distributing only when the stakeholders decide to pull them. This
allows the distribution of things like rewards, dividends, Universal Basic
Income, etc. with minimal resources and huge scalability.
The paper by Bogdan et al. assumes a model where stake size doesn't change once
it is deposited, presumably to explain the concept in the simplest way possible.
After the deposit, a stakeholder can wait to collect rewards and then withdraw both
the deposit and the accumulated rewards.
This would rarely be the case in real applications, as participants would want
to increase or decrease their stakes between reward distributions. To make this
possible, we need to make modifications to the original formulation and
algorithm. Note that the algorithm given below is already implemented in
[PoWH3D](https://etherscan.io/address/0xb3775fb83f7d12a36e0475abdd1fca35c091efbe).
In the paper, the a $\text{reward}_t$ is distributed to a participant $j$ with an
associated $\text{stake}_j$ as
$$
\text{reward}_{j,t} = \text{stake}_{j} \frac{\text{reward}_t}{T_t}
$$
where subscript $t$ denotes the values of quantities at distribution of reward
$t$ and $T$ is
the sum of all active stake deposits.
Since we relax the assumption of constant stake, we rewrite it for
participant $j$'s stake at reward $t$:
$$
\text{reward}_{j,t} = \text{stake}_{j, t} \frac{\text{reward}_t}{T_t}
$$
Then the total reward participant $j$ receives is calculated as
$$
\text{total_reward}_j
= \sum_{t} \text{reward}_{j,t}
= \sum_{t} \text{stake}_{j, t} \frac{\text{reward}_t}{T_t}
$$
Note that we can't take stake out of the sum as the authors did, because
it's not constant.
Instead, we introduce the following identity:
**Identity:** For two sequences $(a_0, a_1, \dots,a_n)$ and $(b_0, b_1, \dots,b_n)$, we have
$$
\boxed{
\sum_{i=0}^{n}a_i b_i
=
a_n \sum_{j=0}^{n} b_j
-
\sum_{i=1}^{n}
\left(
(a_i-a_{i-1})
\sum_{j=0}^{i-1} b_j
\right)
}
$$
**Proof:** Substitute $b_i = \sum_{j=0}^{i}b_j - \sum_{j=0}^{i-1}b_j$ on the
LHS. Distribute the multiplication. Modify the index $i \leftarrow i-1$ on the
first term. Separate the last element of the sum from the first term and
combine the remaining sums since they have the same bounds. $\square$
We assume $n+1$ rewards represented by the indices $t=0,\dots,n$, and
apply the identity to total reward to obtain
$$
\text{total_reward}_j
= \text{stake}_{j, n} \sum_{t=0}^{n} \frac{\text{reward}_t}{T_t}
- \sum_{t=1}^{n}
\left(
(\text{stake}_{j,t}-\text{stake}_{j,t-1})
\sum_{t=0}^{t-1} \frac{\text{reward}_t}{T_t}
\right)
$$
We make the following definition:
$$
\text{reward_per_token}_t = \sum_{k=0}^{t} \frac{\text{reward}_k}{T_k}
$$
and define the change in stake between rewards $t-1$ and $t$:
$$
\Delta \text{stake}_{j,t} = \text{stake}_{j,t}-\text{stake}_{j,t-1}.
$$
Then, we can write
$$
\text{total_reward}_j
= \text{stake}_{j, n}\times \text{reward_per_token}_n
- \sum_{t=1}^{n}
\left(
\Delta \text{stake}_{j,t}
\times
\text{reward_per_token}_{t-1}
\right)
$$
This result is similar to the one obtained by the authors in Equation 5. However,
instead of keeping track of $\text{reward_per_token}$ at times of deposit for each participant, we keep track of
$$
\text{reward_tally}_{j,n}
:= \sum_{t=1}^{n}
\left(
\Delta \text{stake}_{j,t}
\times
\text{reward_per_token}_{t-1}
\right)
$$
In this case, positive $\Delta \text{stake}$ corresponds to a deposit and negative
corresponds to a withdrawal. $\Delta \text{stake}_{j,t}$ is zero if the stake of
participant $j$ remains constant between $t-1$ and $t$. We have
$$
\text{total_reward}_j
= \text{stake}_{j, n} \times\text{reward_per_token}_n - \text{reward_tally}_{j,n}
$$
The modified algorithm requires the same amount of memory, but has the
advantage of participants being able to increase or decrease their stakes
without withdrawing everything and depositing again.
Furthermore, a practical implementation should take into account that a
participant can withdraw rewards at any time.
Assuming $\text{reward_tally}_{j,n}$ is represented by a mapping `reward_tally[]` which is
updated with each change in stake size
```python
reward_tally[address] = reward_tally[address] + change * reward_per_token
```
we can update `reward_tally[]` upon a complete withdrawal of $j$'s total accumulated
rewards:
```python
reward_tally[address] = stake[address] * reward_per_token
```
which sets $j$'s rewards to zero.
A basic implementation of the modified algorithm in Python is given below. The following methods
are exposed:
- `deposit_stake` to deposit or increase a participant stake.
- `distribute` to fan out reward to all participants.
- `withdraw_stake` to withdraw a participant's stake partly or completely.
- `withdraw_reward` to withdraw all of a participant's accumulated rewards.
Caveat: Smart contracts use integer arithmetic, so the algorithm needs to be modified to be used in production. The example does not provide a production ready code, but a minimal working example to understand the algorithm.
```python
class PullBasedDistribution:
"Constant Time Reward Distribution with Changing Stake Sizes"
def __init__(self):
self.total_stake = 0
self.reward_per_token = 0
self.stake = {}
self.reward_tally = {}
def deposit_stake(self, address, amount):
"Increase the stake of `address` by `amount`"
if address not in self.stake:
self.stake[address] = 0
self.reward_tally[address] = 0
self.stake[address] = self.stake[address] + amount
self.reward_tally[address] = self.reward_tally[address] + self.reward_per_token * amount
self.total_stake = self.total_stake + amount
def distribute(self, reward):
"Distribute `reward` proportionally to active stakes"
if self.total_stake == 0:
raise Exception("Cannot distribute to staking pool with 0 stake")
self.reward_per_token = self.reward_per_token + reward / self.total_stake
def compute_reward(self, address):
"Compute reward of `address`"
return self.stake[address] * self.reward_per_token - self.reward_tally[address]
def withdraw_stake(self, address, amount):
"Decrease the stake of `address` by `amount`"
if address not in self.stake:
raise Exception("Stake not found for given address")
if amount > self.stake[address]:
raise Exception("Requested amount greater than staked amount")
self.stake[address] = self.stake[address] - amount
self.reward_tally[address] = self.reward_tally[address] - self.reward_per_token * amount
self.total_stake = self.total_stake - amount
return amount
def withdraw_reward(self, address):
"Withdraw rewards of `address`"
reward = self.compute_reward(address)
self.reward_tally[address] = self.stake[address] * self.reward_per_token
return reward
# A small example
addr1 = 0x1
addr2 = 0x2
contract = PullBasedDistribution()
contract.deposit_stake(addr1, 100)
contract.distribute(10)
contract.deposit_stake(addr2, 50)
contract.distribute(10)
print(contract.withdraw_reward(addr1))
print(contract.withdraw_reward(addr2))
```
## Conclusion
With a minor modification, we improved the user experience of the Constant Time
Reward Distribution Algorithm
first outlined in Batog et al., without changing the memory requirements.
[^1]: Batog B., Boca L., Johnson N., [Scalable Reward Distribution on the Ethereum Blockchain](http://batog.info/papers/scalable-reward-distribution.pdf), 2018.
==========
---
title: "Bitcoin's Inflation"
date: 2019-02-09
canonical: https://solmaz.io/2019/02/09/inflation-curvature-bitcoin-supply/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
New bitcoins are minted with every new block in the Bitcoin blockchain, called "block
rewards", in order to incentivize people to mine and increase the security of the network. This
inflates Bitcoin's supply in a predictable manner. The inflation rate halves every
4 years, decreasing geometrically.
There have been some confusion of the terminology, like people calling Bitcoin
deflationary. Bitcoin is in fact not deflationary---that implies a negative
inflation rate. Bitcoin rather has negative **inflation curvature**: Bitcoin's
inflation rate decreases monotonically.
An analogy from elementary physics should clear things up: Speaking strictly in
terms of monetary inflation,
- *displacement* is analogous to *inflation/deflation*, as in total money
minted/burned, without considering a time period. Dimensions: $[M]$.
- *Velocity* is analogous to *inflation rate*, which defines total money minted/burned
in a given period. Dimensions: $[M/T]$.
- *Acceleration* is analogous to *inflation curvature*, which defines the total
change in inflation rate in a given period. Dimensions: $[M/T^2]$.
Given a supply function $S$ as a function of time, block height, or any variable
signifying progress,
- inflation is a positive change in supply, $\Delta S > 0$, and deflation, $\Delta S < 0$.
- Inflation rate is the first derivative of supply, $S'$.
- Inflation curvature is the second derivative of supply, $S''$.
In Bitcoin, we have the supply as a function of block height:
$S:\mathbb{Z}_{\geq 0} \to \mathbb{R}\_+$.
But the function itself is defined by the arithmetic[^1] initial value problem
$$
S'(h) = \alpha^{\lfloor h/\beta\rfloor} R_0
,\quad
S(0) = 0
\tag{1}
$$
where $R_0$ is the initial inflation rate, $\alpha$ is the rate by which the
inflation rate will decrease, $\beta$ is the milestone number of blocks at
which the decrease will take place, and $\lfloor \cdot \rfloor$ is the floor
function. In Bitcoin, we have $R_0 = 50\text{ BTC}$,
$\alpha=1/2$ and $\beta=210,000\text{ blocks}$. Here is what it looks like:
Bitcoin inflation rate versus block height.
We can directly compute inflation curvature:
$$
S''(h) =
\begin{cases}
\frac{\ln(\alpha)}{\beta} \alpha^{h/\beta} & \text{if}\quad
h\ \mathrm{mod}\ \beta = 0 \quad\text{and}\quad h > 0\\
0 & \text{otherwise}.
\end{cases}
$$
$S''$ is nonzero only when $h$ is a multiple of $\beta$. For $0 < \alpha < 1$,
$S''$ is either zero or negative, which is the case for Bitcoin.
Finally, we can come up with a closed-form $S$ by solving the initial value
problem (1):
$$
\begin{aligned}
S(h) &= \sum_{i=0}^{\lfloor h/\beta\rfloor -1} \alpha^{i} \beta R_0
+ \alpha^{\lfloor h/\beta\rfloor} (h\ \mathrm{mod}\ \beta) R_0 \\
&= R_0 \left(\beta\frac{1-\alpha^{\lfloor h/\beta\rfloor}}{1-\alpha}
+\alpha^{\lfloor h/\beta\rfloor} (h\ \mathrm{mod}\ \beta) \right)
\end{aligned}
$$
Here is what the supply function looks like for Bitcoin:
Bitcoin supply versus block height.
And the maximum number of Bitcoins to ever exist are calculated by taking the
limit
$$
\lim_{h\to\infty} S(h)
= \sum_{i=0}^{\infty} \alpha^{i} \beta R_0
= \frac{\beta R_0}{1-\alpha}
= 21,000,000\text{ BTC}.
$$
# Summary
The concept of inflation curvature was introduced. The confusion regarding
Bitcoin's inflation mechanism was cleared with an analogy. The IVP defining
Bitcoin's supply was introduced and solved to get a closed-form
expression. Inflation curvature for Bitcoin was derived.
The maximum number of Bitcoins to ever exist was derived and computed.
[^1]: Because $S$ is defined over positive integers.
==========
---
title: "The Anatomy of a Block Stuffing Attack"
date: 2018-10-18
canonical: https://solmaz.io/2018/10/18/anatomy-block-stuffing/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
*Block stuffing* is a type of attack in blockchains where an attacker submits
transactions that deliberately fill up the block's gas limit and stall other
transactions. To ensure inclusion of their transactions by miners, the
attacker can choose to pay higher transaction fees. By controlling the
amount of gas spent by their transactions, the attacker can influence the number
of transactions that get to be included in the block.
To control
the amount of gas spent by the transaction, the attacker utilizes a special
contract. There is a function in the contract which takes as input the amount of
gas that the attacker wants to burn. The function runs meaningless
instructions in a loop, and either returns or throws an error when the desired
amount is burned.
For example let's say that the average gas price has been 5 Gwei in the last
10 blocks. In order to exert influence over the next block, the attacker needs to
submit transactions with gas prices higher than that, say 100 Gwei. The higher
the gas price, the higher the chance of inclusion by miners.
The attacker can choose to divide the task of using 8,000,000 gas---current
gas limit for blocks---into as
many transactions as they want. This could be 80 transactions with
100,000 gas expenditure, or 4 transactions with 2,000,000 gas expenditure.
Deciding on how to divide the task is a matter of maximizing the chance of
inclusion, and depends on the factors outline below.
## Miners' strategy for selecting transactions
Miners want to maximize their
profit by including transactions with highest fees. In the current PoW
implementation of Ethereum, mining the block takes significantly more time
than executing the transactions. So let's assume
all transactions in the pool are trivially executed as soon as they arrive
and miners know the amount of gas each one uses.
For miners, maximizing profit is an
[optimum packing problem](https://en.wikipedia.org/wiki/Packing_problems).
Miners want to choose a subset of the transaction pool that gives them
maximum profit per block. Since there are at least tens of thousands of
transactions in the pool at any given time, the problem can't be solved by
brute-forcing every combination. Miners use algorithms that test a
feasible number of combinations and select the one giving the highest reward.
A block stuffer's main goal is to target the selection process by
crafting a set of transactions that has the highest chance of being picked
up by miners in a way that will deplete blocks' gas limits.
They can't devise a 100% guaranteed strategy since each miner
can use a different algorithm, but they can find a sweet spot by testing out the
whole network.
(In a PoS system, our assumptions would be wrong since executing
transactions is not trivial compared to validating blocks. Validators would
need to develop more complex strategies depending on the PoS implementation.)
## The transactions the attacker wants to stall:
It could be so that the
attacker wants to stall transactions with a specific contract. If the
function calls to that contract use a distinctively high amount of gas, say
between 300,000 and 500,000, then the attacker has to stuff the block in a
way that targets that range.
For example, the attacker can periodically submit $n$ transactions
$\\{T_1, T_2,\dots, T_{n-1}, T_n\\}$ with very high prices where
$$\sum\limits_{i=1}^{n} T_i^{\text{gas}} \approx 8,000,000.$$
If the attacker is targeting transactions within a range of
$(R_\text{lower}, R_\text{upper})$, they can choose
the first $n-1$ transactions to deplete $8,000,000 - R_\text{upper}$ gas
in short steps, and submit $T_n$ to deplete the remaining $R_\text{upper}$
gas with a relatively higher price. Note that the revenue from including a
single transaction is
$$\text{tx_fee} = \text{gas_price} \times \text{gas_usage}.$$
As gas usage decreases, the
probability of being picked up by miners decreases, so prices should increase
to compensate.
# Example: Fomo3D
[Fomo3D](https://fomo3d.hostedwiki.co/)
is a gambling game where players buy keys from a contract and their money
goes into a pot. At the beginning of each round, a time counter is initiated
which starts counting back from 24 hours. Each bought key adds 30 seconds to the
counter. When the counter hits 0, the last player to have bought a key wins the
majority of the pot and the rest is distributed to others. The
way the pot is distributed depends on the team that the winner belongs to.
Key price increases with increasing key supply, which makes it harder and harder
to buy a key and ensures the round will end after some point. In time, the stakes
increase and the counter reduces to a minimum, like 2 minutes. At this
point, the players pay both high gas and key prices to be "it" and win the game.
Players program bots to buy keys for them, and winning becomes a matter of coding the
right strategy. As you can understand from the subject, the
first round was won through a block stuffing attack.
On August 22 2018, the address
0xa16…f85 won
10,469 ETH from the first round by following the strategy I outlined above. The
winner managed to be the last buyer in
block 6191896 and managed to stall
transactions with Fomo3D until block 6191909 for 175 seconds,
ending the round. Some details:
- Fomo3D Long contract address:
0xA62…Da1
- Last transaction by the winner before the attack starts:
0x7a0…349
- Transaction ending the round and firing the `onBuyAndDistribute` event which
distributes the pot:
0xa14…012
- Transaction where winner withdraws the prize:
0xe08…508
- Contract used for block stuffing:
0x18e…801
- Other addresses possibly belonging to the winner:
0x3c3…f27, 0xc6a…3e2, 0x81e…0ac, 0xc96…590, 0xd27…642, 0x18d…a9a, 0x87c…4ef, 0x9da…0cf, 0x7dd…c4c, 0xb1d…aef, 0x1a6…d56, 0xf6e…059, 0x1dd…a69, 0x061…63b, 0x00c…776, 0xa94…eb8, 0xf03…1f2
- Other contracts possibly deployed by the winner for testing prior to the attack:
0xaf1…eae, 0x0c0…5ad, 0x88e…d04, 0x4f4…6f8, 0x487…4e5
The user addresses above were scraped from the Ethereum transaction graph as being
linked to a primary account which supplied them with funds. The contract
addresses were scraped from 0-valued transactions sent from user addresses.
These have a [distance](https://en.wikipedia.org/wiki/Distance_(graph_theory))
of 1, there may be other addresses involved with greater distances.
Below are details of the last 4 blocks preceding the end of the round. The rows
highlighted with yellow are transactions submitted by the attacker. The crossed
out rows are failed transactions. All transactions by the attacker were
submitted with a 501 Gwei gas price, and stuffing a single block costed around 4
ETH. The calls to buy keys generally spend around 300,000~500,000 gas, depending
on which function was called.
Below, you see the successfully stuffed
block 6191906.
Block 6191907 was a close call for the winner, because their transactions picked
up for the block did not amount up to 8,000,000 and the other transaction was a
call to Fomo3D by an opponent to buy keys. Note that it has a gas price of 5559
Gwei, which means either the bot or person who submitted the transaction was
presumably aware of the attack.
The transaction failed due to low gas limit, presumably due to a miscalculation
by the bot or the person.
Transactions in block 6191908 belonged to the attacker except for one irrelevant
transfer. This block is also considered successfully stuffed, since the
7,970,000 gas usage by the attacker leaves no space for a call to buy keys.
By block 6191909, the counter has struck zero---more like current UTC time
surpassed the round end variable stored in the contract---and any call to Fomo3D
would be the one to end the round and distribute the pot. And the first transaction
in the block is---wait for it---a call to Fomo3D to buy keys by the opponent
whose transaction failed a few blocks earlier, submitted with 5562 Gwei. So the
guy basically paid 1.7 ETH to declare the attacker the winner!
Another thing to note is that the attacker probably crafted the spender contract
to stop the attack when the round has ended, presumably to cut costs. So the 37,633
gas used by the contract are probably to call the Fomo3D contract to check
round status. All these point out to the fact that the attacker is an
experienced programmer who knows their way around Ethereum.
[Here](/assets/fomo3d_round1_tx_details.html), you can see the details of the 100
blocks preceding the end of the round, with the additional information of ABI
calls and events fired in transactions.
Since the end of the first round, 2 more rounds ended with attacks similar to
this one. I didn't analyze all of them because it's too much for this post, but
here are some details if you want to do it yourselves.
| Round | Address winning the pot | Winner's last tx before the end of the round | Block containing that tx | Tx ending the round | Block containing that tx | Tx where winner withdraws prize | Amount won [ETH] | Contract used for block stuffing |
|-------|--------------------------------------------|--------------------------------------------------------------------|--------------------------|--------------------------------------------------------------------|--------------------------|--------------------------------------------------------------------|------------------|--------------------------------------------|
| 1 | 0xa169df5ed3363cfc4c92ac96c6c5f2a42fccbf85 | 0x7a06d9f11e650fbb2061b320442e26b4a704e1277547e943d73e5b67eb49c349 | 6191896 | 0xa143a1ee36e1065c3388440ef7e7b38ed41925ca4799c8a4d429fa3ee1966012 | 6191909 | 0xe08a519c03cb0aed0e04b33104112d65fa1d3a48cd3aeab65f047b2abce9d508 | 10,469 | 0x18e1b664c6a2e88b93c1b71f61cbf76a726b7801 |
| 2 | 0x18a0451ea56fd4ff58f59837e9ec30f346ffdca5 | 0x0437885fa741f93acfdcda9f5a2e673bb16d26dd22dfc4890775efb8a94fb583 | 6391537 | 0x87bf726bc60540c6b91cc013b48024a5b8c1431e0847aadecf0e92c56f8f46fd | 6391548 | 0x4da4052d2baffdc9c0b82d628b87d2c76368914e33799032c6966ee8a3c216a0 | 3,264 | 0x705203fc06027379681AEf47c08fe679bc4A58e1 |
| 3 | 0xaf492045962428a15903625B1a9ECF438890eF92 | 0x88452b56e9aa58b70321ee8d5c9ac762a62509c98d9a29a4d64d6caae49ae757 | 6507761 | 0xe6a5a10ec91d12e3fec7e17b0dfbb983e00ffe93d61225735af2e1a8eabde003 | 6507774 | 0xd7e70fdf58aca40139246a324e871c84d988cfaff673c9e5f384315c91afa5e4 | 376 | 0xdcC655B2665A675B90ED2527354C18596276B0de |
A thing to note in the following rounds is that participation in the game
and amount of pot gradually decreased, presumably owing to the fact that
the way of beating the game has been systematized. Although anyone can attempt
such an attack, knowing how it will be won takes the "fun" factor out of it.
Credit: Although I've found previous instances of the term "block stuffing"
online, Nic Carter is the first
one to [use it](https://twitter.com/nic__carter/status/1032262665668894721) in
this context.
==========
---
title: "Mathematics of Bonding Curves"
date: 2018-08-03
canonical: https://solmaz.io/2018/08/03/token-bonding-1/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
A bonding curve is a financial instrument proposed by [Simon de la Rouviere](http://simondlr.com)
in his [Medium](https://medium.com/@simondlr/tokens-2-0-curved-token-bonding-in-curation-markets-1764a2e0bee5) [articles](https://medium.com/@simondlr/curation-markets-curved-bonding-update-02-april-2018-87c593d629c2). ETH is bonded in a smart contract to mint tokens, and unbonded to burn them. Every bonding and unbonding changes the price of the token according to a predefined formula. The "curves" represent the relationship between the price of a single token and the token supply. The result is an ETH-backed token that rewards early adopters.
An example supply versus price graph. The area below the curve is equal to the amount of ETH $E$ that must be spent to increase the supply from $S_0$ to $S_1$, or that is going to be received when $S_1-S_0$ tokens are unbonded.
Inside a transaction, **the price paid/received per token is not constant** and depends on the amount that is bonded or unbonded. This complicates the calculations.
Let's say for an initial supply of $S_0$, we want to bond $T$ tokens which are added to the new supply $S_1=S_0+T$. The ETH $E$ that must be spent for this bonding is defined as
$$
E = \int_{S_0}^{S_1} P\, dS
$$
which is illustrated in the figure above. If one wanted to unbond $T$ tokens, the upper limit for the integral would be $S_0$ and the lower $S_0-T$, with E corresponding to the amount of ETH received for the unbonding.
# Linear Curves
A linear relationship for the bonding curves are defined as
$$P(S) = P_0 + S I_p$$
where $P_0$ is the initial price of the token and $I_p$ is the price increment per token.
## Bonding Tokens
Let us have $E$ ETH which we want to bond tokens with. Substituting $P$ into the integral above with the limits $S_0\to S_0+T$, we obtain $E$ in terms of the tokens $T$ that we want to bond:
$$E(S, T) = T P_0 + T I_p S + \frac{1}{2} T^2 I_p$$
where $S$ is the supply before the bonding. Solving this for $T$, we obtain the tokens received in a bonding as a function of the supply and ETH spent:
$$\boxed{T(S, E) = \frac{\sqrt{S^2I_p^2 + 2E I_p + 2 S P_0 I_p + P_0^2}-P_0}{I_p} - S.}$$
## Unbonding Tokens
Let us have T tokens which we want to unbond for ETH. Unbonding $T$ tokens decreases the supply from $S_0$ to $S_0-T$, which we apply as limits for the above integral and obtain:
$$\boxed{E(S, T) = T P_0 + T I_p S - \frac{1}{2} T^2 I_p.}$$
# Breaking Even in PoWH3D
[PoWH3D](https://powh.io/) is one of the applications of bonding curves with a twist: 1/10th of every transaction is distributed among token holders as dividends. When you bond tokens with $E$ ETH, you receive $9/10 E$ worth of tokens and $1/10 E$ is distributed to everybody else in proportion to the amount they hold.
This means you are at a loss when you bond P3D (the token used by PoWH3D). If you were to unbond immediately, you would only receive 81% of your money. Given the situation, one wonders when exactly one can break even with their investment. The activity in PoWH3D isn't deterministic; nonetheless we can deduce **sufficient but not necessary conditions** for breaking even in PoWH3D.
## Sufficient Bonding
Let us spend $E_1$ ETH to bond tokens at supply $S_0$. The following calculations are
done with the assumption that the tokens received
$$T_1 = T(S_0, 9E_1/10)$$
are small enough to be
neglected, that is $T_1 \ll S_0$ and $S_1 \approx S_0$. In other words, *this only
holds for non-whale bondings*.
Then let others spend $E_2$ ETH to bond tokens and raise the supply to $S_2$.
The objective is to find an $E_2$ large enough to earn us dividends and make us
break even when we unbond our tokens at $S_2$.
We have
$$S_2 = S_0 + T(S_0, E_2).$$
Our new share of the P3D pool is $T_1/S_2$ and the dividends we earn from
the bonding is equal to
$$\frac{1}{10}\frac{T_1}{S_2}E_2.$$
Then the condition for breaking even is
$$\boxed{\frac{9}{10} E(S_2, T_1) + \frac{1}{10}\frac{T_1}{S_2}E_2 \geq E_1.}$$
This inequality has a lengthy analytic solution which is impractical to
typeset. The definition should be enough:
$$E^{\text{suff}}_2(S_0, E_1) := \text{solve for $E_2$}\left\{\frac{9}{10} E(S_2, T_1) + \frac{1}{10}\frac{T_1}{S_2}E_2 = E_1\right\}$$
and
$$E_2 \geq E^{\text{suff}}_2.$$
$E^{\text{suff}}_2$ can be obtained from the source of this page in JavaScript from
the function `sufficient_bonding`. *The function involves many power
and square operations and may yield inexact results for too high values of
$S_0$ or too small values off $E_1$, due to insufficient precision of the
underlying math functions.* For this reason, the calculator is disabled
for sensitive input.
$S_0$ versus $E^{\text{suff}}_2$ for $E_1 = 100$.
The relationship between the initial supply and sufficient bonding is roughly
quadratic, as seen from the graph above. This means that the difficulty of
breaking even increases quadratically as more people bond into P3D. As interest in
PoWH3D saturates, dividends received from the supply increase decreases
quadratically.
Logarithmic plot of $S_0$ versus $E^{\text{suff}}_2$ for changing values of $E_1$.
The relationship is not exactly quadratic, as seen from the graph above. The
function is sensitive to $E_1$ for small values of $S_0$.
## Sufficient Unbonding
Let us spend $E_1$ ETH to bond tokens at supply $S_0$ and receive $T_1$ tokens.
Then let others unbond $T_2$ P3D to lower the supply to $S_2$. The objective is to find a $T_2$ large enough to earn us dividends and make us break even when we unbond our tokens at $S_2$. We have
$$S_2 = S_0 - T_2.$$
Our new share of the P3D pool is $T_1/S_2$ and the dividends we earn from the bonding is equal to
$$\frac{1}{10}\frac{T_1}{S_2} E(S_2, T_2)$$
Then the condition for breaking even is
$$\boxed{\frac{9}{10} E(S_2, T_1) + \frac{1}{10}\frac{T_1}{S_2} E(S_2, T_2) \geq E_1.}$$
Similar to the previous section, we have
$$T^{\text{suff}}_2(S_0, E_1) := \text{solve for $T_2$}\left\{\frac{9}{10} E(S_2, T_1) + \frac{1}{10}\frac{T_1}{S_2} E(S_2, T_2) = E_1\right\}$$
and
$$T_2 \geq T^{\text{suff}}_2.$$
$T^{\text{suff}}_2$ can be obtained from the function `sufficient_unbonding`.
$S_0$ versus $T^{\text{suff}}_2$ for $E_1 = 100$.
The relationship between $S_0$ and $T^{\text{suff}}_2$ is linear and insensitive to $E_1$. Regardless of the ETH you invest, the amount of tokens that need to be unbonded to guarantee your break-even is roughly the same, depending on your entry point.
## Calculator
Below is a calculator you can input $S_0$ and $E_1$ to calculate $E^{\text{suff}}_2$ and $T^{\text{suff}}_2$.
$S_0$
$E_1$
$E^{\text{suff}}_2 $
$T^{\text{suff}}_2 $
For the default values above, we read this as:
> For 100 ETH worth of P3D bonded
> at 3,500,000 supply, either a bonding of ~31715 ETH
> or an unbonding of ~3336785 P3D
> made by other people is sufficient to
> break even.
In order to follow these statistics, you can follow
[this site](https://powh3d.eu/).
# Conclusion
Bonding curve calculations can get complicated because the price paid per token depends on the amount of intended bonding/unbonding. With this work, I aimed to clarify the logic behind PoWH3D. Use the formulation and calculator at your own risk.
The above conditions are only sufficient and not necessary to break even. As PoWH3D becomes more popular, it gets quadratically more difficult to break even from a supply increase. PoWH3D itself doesn't generate any value or promise long-term returns for its holders. However every bond, unbond and transfer deliver dividends. According to its creators, P3D is intended to become the base token for a number of games that will be built upon PoWH3D, like [FOMO3D](https://exitscam.me/).
==========
---
title: "Lumped L2 Projection"
date: 2018-04-24
canonical: https://solmaz.io/2018/04/24/lumped-l2-projection/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
When utilizing Galerkin-type solutions for
[IBVP](https://en.wikipedia.org/wiki/Boundary_value_problem)s, we often
have to compute integrals using numerical methods such as
[Gauss quadrature](https://en.wikipedia.org/wiki/Gaussian_quadrature). In
such a solution, we solve for the values of a function at *mesh nodes*, whereas
the integration takes place at the *quadrature points*. Depending on the case,
we may need to compute the values of a function at mesh nodes, given their
values at quadrature points, e.g. stress recovery for mechanical problems.
There are many ways of achieving this, such as
[superconvergent patch recovery](https://www.sciencedirect.com/science/article/pii/004578259290023D).
In this post, I wanted to document a widely used solution which is easy to
implement, and which is used in research oriented codebases such as
[FEAP](http://projects.ce.berkeley.edu/feap/).
# L2 Projection
Given a function $u \in L^2(\Omega)$, its projection into a finite element space
$V_h\subset L^2(\Omega)$ is defined through the following optimization
problem:
Find $u_h\in V_h$ such that
$$\begin{equation}
\Pi(u_h) := \frac{1}{2}\lVert u_h-u \rVert^2_{L^2(\Omega)}
\quad\rightarrow\quad
\text{min}
\end{equation}$$
There is a unique solution to the problem since $\Pi(\cdot)$ is convex. Taking
its variation, we have
$$\begin{equation}
D \Pi(u_h) \cdot v_h = \langle u_h-u, v_h \rangle = 0
\end{equation}$$
for all $v_h\in V_h$. Thus we have the following variational formulation
> Find $u_h\in V_h$ such that
>
> $$\begin{equation}
> \langle u_h,v_h\rangle = \langle u, v_h\rangle
> \end{equation}$$
>
> for all $v_h\in V_h$.
Here,
$$\begin{equation}
\begin{alignedat}{3}
m(u_h,v_h) &= \langle u_h,v_h\rangle && = \int_\Omega u_hv_h \,dx \quad\text{and} \\
b(v_h) &= \langle u, v_h\rangle && = \int_\Omega u v_h \,dx
\end{alignedat}
\end{equation}$$
are our bilinear and linear forms respectively. Substituting FE
discretizations $u_h = \sum_{J=1}^{\nnode} u^JN^J$ and
$v_h = \sum_{I=1}^{\nnode} v^IN^I$, we have
$$\begin{equation}
\suml{J=1}{\nnode} M^{I\!J} u^J = b^I
\label{eq:projectionsystem1}
\end{equation}$$
for $I=1,\dots,\nnode$,
where the FE matrix and vector are defined as
$$\begin{equation}
\begin{alignedat}{3}
M^{I\!J} &= m(N^J,N^I) &&= \int_\Omega N^JN^I \,dx \quad\text{and} \\
b^{I} &= b(N^I) &&= \int_\Omega u N^I \,dx
\end{alignedat}
\end{equation}$$
Thus L2 projection requires the solution of a linear system
$$\boldsymbol{M}\boldsymbol{u}=\boldsymbol{b}$$
which depending on the algorithm used, can have a complexity of at least
$O(n^2)$ and at most $O(n^3)$.
# Lumped L2 Projection
The L2 projection requires the solution of a system which can be
computationally expensive. It is possible to convert the
matrix---called the mass matrix in literature---to a diagonal
form through a procedure called **lumping**.
The operator for row summation is defined as
$$\begin{equation}
\rowsum{(\cdot)}_i := \suml{j=1}{\nnode} (\cdot)_{ij}
\end{equation}$$
For the mass matrix, we have
$$\begin{equation}
\rowsum M^{I} =
\suml{J=1}{\nnode} \int_\Omega N^JN^I \,dx
= \int_\Omega N^I \,dx
=: m^I
\end{equation}$$
since $\sum_{J=1}^{\nnode} N^J = 1$.
Substituting the lumped mass matrix allows us to decouple the linear system of
equations in \eqref{eq:projectionsystem1} and instead write
$$\begin{equation}
m^I u^I = b^I
\end{equation}$$
for $I=1,\dots,\nnode$. The lumped L2 projection is then as simple as
$$\begin{equation}
u^I = \frac{b^I}{m^I} = \frac{\displaystyle\int_\Omega u N^I\,dx}{\displaystyle\int_\Omega N^I \,dx}
\end{equation}$$
This results in a very efficient algorithm with $O(n)$ complexity.
# Conclusion
Lumped L2 projection is a faster working approximation to L2 projection that is
easy to implement for quick results. You can use it when developing a solution
for an IBVP, and don't want to wait too long when debugging, while not
forgetting that it introduces some error.
==========
---
title: "Disadvantages of Engineering Notation in Finite Elements"
date: 2018-04-13
canonical: https://solmaz.io/2018/04/13/engineering-notation-disadvantages/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Suppose we have the following stiffness matrix of linear elasticity:
$$\begin{equation}
A^{I\!J}_{ij} = \int_\Omega B^I_k \, C_{ikjl} \, B^J_l \,dv \label{eq:engnot1}
\end{equation}$$
where $\boldsymbol{B}^I = \nabla N^I$ are the gradients of the shape
functions $N^I$ and $\mathbb{C}$ is the linear elasticity tensor (you see the
contraction of their components in the equation).
Despite being of the most explicit form, these types of indicial expressions are
avoided in most texts on finite elements. There are two reasons for this:
- Engineers are not taught the Einstein summation convention.
- The presence of indices result in a seemingly cluttered expression.
They avoid the indicial expression by reshaping it into matrix multiplications.
In engineering notation, the left- and right-hand sides are reshaped as
$$\begin{equation}
A_{\alpha\beta} = \int_\Omega B_{\gamma\alpha}C_{\gamma\delta}B_{\delta\beta}
\,dv \label{eq:engnot2}
\end{equation}$$
which allows us to write
$$\begin{equation}
\boldsymbol{A} = \int_\Omega \tilde{\boldsymbol{B}}^T\tilde{\boldsymbol{C}}\tilde{\boldsymbol{B}} \,dv
\label{eq:engnot3}
\end{equation}$$
The matrices $\tilde{\boldsymbol{B}}$ and $\tilde{\boldsymbol{C}}$ are set on with tildes in order to
differentiate them from the boldface symbols used in the previous sections.
Here,
- $\tilde{\boldsymbol{C}}$ is a matrix containing the unique components of the elasticity
tensor $\mathbb{C}$, according to the Voigt notation.
In this reshaping, only the minor symmetries are taken into account.
If the dimension of the vectorial problem is $d$, then $\tilde{\boldsymbol{C}}$ is of the size
$d(d+1)/2 \times d(d+1)/2$. For example, if the problem is 3 dimensional, $\tilde{\boldsymbol{C}}$
is of the size $6\times 6$:
$$\begin{equation}
[\tilde{\boldsymbol{C}}] =
\begin{bmatrix}
C_{1111} & C_{1122} & C_{1133} & C_{1112} & C_{1123} & C_{1113} \\
C_{2211} & C_{2222} & C_{2233} & C_{2212} & C_{2223} & C_{2213} \\
C_{3311} & C_{3322} & C_{3333} & C_{3312} & C_{3323} & C_{3313} \\
C_{1211} & C_{1222} & C_{1233} & C_{1212} & C_{1223} & C_{1213} \\
C_{2311} & C_{2322} & C_{2333} & C_{2312} & C_{2323} & C_{2313} \\
C_{1311} & C_{1322} & C_{1333} & C_{1312} & C_{1323} & C_{1313} \\
\end{bmatrix}
\label{eq:engnotC}
\end{equation}$$
- $\tilde{\boldsymbol{B}}$ is a $nd\times d(d+1)/2$ matrix whose components are
adjusted so that \eqref{eq:engnot2} is equivalent to \eqref{eq:engnot1}. It
has the components of $\boldsymbol{B}^I$ for $I=1,\dots,n$ where $n$ is the number of
basis functions. Since $\tilde{\boldsymbol{B}}$ is adjusted to account for the reshaping
of $\mathbb{C}$, it has many zero components. A 3d example:
$$\begin{equation}
[\tilde{\boldsymbol{B}}] =
\begin{bmatrix}
B^1_1 & 0 & 0 & B^2_1 & 0 & 0 & \cdots & B^n_1 & 0 & 0 \\
0 & B^1_2 & 0 & 0 & B^2_2 & 0 & \cdots & 0 & B^n_2 & 0 \\
0 & 0 & B^1_3 & 0 & 0 & B^2_3 & \cdots & 0 & 0 & B^n_3 \\
B^1_2 & B^1_1 & 0 & B^2_2 & B^2_1 & 0 & \cdots & B^n_2 & B^n_1 & 0 \\
0 & B^1_3 & B^1_2 & 0 & B^2_3 & B^2_2 & \cdots & 0 & B^n_3 & B^n_2 \\
B^1_3 & 0 & B^1_1 & B^2_3 & 0 & B^2_1 & \cdots & B^n_3 & 0 & B^n_1 \\
\end{bmatrix}
\label{eq:engnotB}
\end{equation}$$
Although \eqref{eq:engnot3} looks nice on paper, it is much less optimal for
implementation. Implementing it requires the implementation of
\eqref{eq:engnotB}, which adds another layer of complexity to the algorithm.
The same cannot be said for \eqref{eq:engnotC}, because using Voigt
notation might be more efficient in inelastic problems. In the most complex
problems, the most efficient method is to implement \eqref{eq:engnot1} in
conjunction with Voigt notation.
To prove the inefficiency of \eqref{eq:engnot3} we can readily compare it with
\eqref{eq:engnot1} in terms of required number of iterations. Indices in
\eqref{eq:engnot1} have the following ranges:
$$\begin{equation}
I,J = 1,\dots,n
\quad\text{and}\quad
i,j,k,l = 1,\dots,d
\end{equation}$$
so $n^2d^4$ iterations are required. Indices in
\eqref{eq:engnot2} have the following ranges:
$$\begin{equation}
\alpha,\beta=1,\dots,nd
\quad\text{and}\quad
\gamma,\delta=1,\dots,d(d+1)/2
\end{equation}$$
so
$$\begin{equation}
(nd)^2\left(\frac{d(d+1)}{2}\right)^2 = n^2d^4\frac{(d+1)^2}{4}
\end{equation}$$
iterations are required. So engineering notation requires $(d+1)^2/4$ times more
equations than index notation. For $d=2$, engineering notation is $2.25$
times slower and for $d=3$ it is $4$ times slower. For example, calculation of a
stiffness matrix for $n=8$ and $d=3$ requires $20736$ iterations for
engineering notation, whereas it only requires $5184$ iterations for index notation.
Although \eqref{eq:engnot3} seems less cluttered, what actually happens is
that one
trades off complexity in one expression for a much increased complexity in
another one, in this case \eqref{eq:engnotB}.
And to make it worse, it results in a slower algorithm.
The only obstacle to the widespread adoption of
index notation seems to be its lack in undergraduate engineering curricula.
If engineers were taught the index notation and summation convention as well
as the formal notation, such expressions would not be as confusing at first
sight. A good place would be in elementary calculus and physics courses, where
one heavily uses vector calculus.
==========
---
title: "Variational Formulation of Elasticity"
date: 2018-04-01
canonical: https://solmaz.io/2018/04/01/variational-formulation-elasticity/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
There are many books that give an outline of hyperelasticity, but there are few
that try to help the reader implement solutions, and even fewer that
manage to do it in a concise manner. Peter Wriggers'
[Nonlinear Finite Element Methods](https://www.springer.com/gp/book/9783540710004)
is a great reference for those who like to
roll up their sleeves and get lost in theory. It helped me understand a lot
about how solutions to hyperelastic and inelastic problems are implemented.
One thing did not quite fit my taste though---it was very formal in the way that
it didn't give out indicial expressions. And if it wasn't clear up until this
point, I love indicial expressions, because they pack enough information to
implement a solution in a single line. Almost all books skip these
because they seem cluttered and the professors who wrote them think they're
trivial to derive. In fact, they are not.
So below, I'll try to derive indicial expressions for the update equations of
hyperelasticity.
In the case of a hyperelastic material, there exists a strain energy function
$$\begin{equation}
\Psi: \BF \mapsto \Psi(\BF)
\end{equation}$$
which describes the elastic energy stored in the solid, i.e. energy
density per unit *mass* of the reference configuration.
The total energy stored in $\CB$ is described by the the stored energy
functional
$$\begin{equation}
E(\Bvarphi) := \int_\CB \Psi(\BF)\, \dif m = \int_\CB \rho_0 \Psi(\BF) \dV
\end{equation}$$
The loads acting on the body also form a potential:
$$\begin{equation}
L(\Bvarphi) := \int_\CB \rho_0\bar{\BGamma}\dtp\Bvarphi \dV + \int_{\del\CB_t} \bar{\BT}\dtp\Bvarphi \dA
\end{equation}$$
where $\bar{\BGamma}$ and $\bar{\BT}$ are the prescribed body forces per unit mass and surface tractions
respectively, where $\BT=\BP\BN$ with Cauchy's stress theorem.
The potential energy of $\CB$ for deformation $\Bvarphi$ is defined as
$$\begin{equation}
\Pi(\Bvarphi) := E(\Bvarphi) - L(\Bvarphi)
\end{equation}$$
Thus the variational formulation reads
> Find $\Bvarphi\in V$ such that the functional
>
> $$\begin{equation}
> \Pi(\Bvarphi)
> = \int_\CB \rho_0\Psi(\BF) \dV
> - \int_\CB \rho_0\bar{\BGamma}\dtp\Bvarphi \dV - \int_{\del\CB_t} \bar{\BT}\dtp\Bvarphi \dA
> \end{equation}$$
>
> is minimized for $\Bvarphi=\bar{\Bvarphi}$ on $\del\CB_u$.
The solution is one that minimizes the potential energy:
$$\begin{equation}
\Bvarphi^\ast = \argmin_{\Bvarphi\in V} \Pi(\Bvarphi)
\end{equation}$$
A stationary point for $\Pi$ means that its first variation vanishes: $\var\Pi=0$.
$$\begin{equation}
\begin{aligned}
\var\Pi &= \varn{\Pi}{\Bvarphi}{\vvphi}
=: G(\Bvarphi,\vvphi) \\
&= \int_\CB \rho_0\partd{\Psi}{\BF}: \nabla(\vvphi) \dV
- \int_\CB \rho_0\bar{\BGamma}\dtp\vvphi \dV
- \int_{\del\CB} \bar{\BT}\dtp\vvphi \dA
\end{aligned}
\end{equation}$$
Using $\BP=\BF\BS$ and $\BP = \rho_0\del\Psi/\del\BF$,
$$\begin{equation}
\rho_0\partd{\Psi}{\BF}: \nabla(\vvphi)
= \BF\BS:\nabla(\vvphi)
= \BS:\BF\tra\nabla(\vvphi)
\end{equation}$$
The symmetric part of the term on the right hand side of the contraction is
equal to the variation of the Green-Lagrange strain tensor:
$$\begin{equation}
\begin{aligned}
\var\BE = \varn{\BE}{\Bvarphi}{\vvphi}
&= \deriv{}{\eps} \frac{1}{2}
[\nabla(\Bvarphi+\eps\vvphi)\tra\nabla(\Bvarphi+\eps\vvphi) - \BI]\evat_{\eps=0}
\\
&= \frac{1}{2} [\nabla(\vvphi)\tra\BF + \BF\tra\nabla(\vvphi)]
\end{aligned}
\end{equation}$$
Substituting, we obtain the semilinear form $G$ in terms of the
second Piola-Kirchhoff stress tensor:
$$\begin{equation}
\boxed{
G(\Bvarphi,\vvphi)
= \int_\CB \BS: \var\BE \dV
- \int_\CB \rho_0\bar{\BGamma}\dtp\vvphi \dV
- \int_{\del\CB} \bar{\BT}\dtp\vvphi \dA = 0
}
\label{eq:lagrangianform1}
\end{equation}$$
We can write a Eulerian version of this form by pushing-forward the stresses and
strains.
The Almansi strain $\Be$ is the pull-back of the Green-Lagrange strain $\BE$ and
vice versa:
$$\begin{equation}
\Be = \push(\BE) = \BF\invtra \BE \BF\inv
\eqand
\BE = \pull(\Be) = \BF\tra \BE \BF
\end{equation}$$
Commutative diagram for the pull-back and push-forward relationships of the Green-Lagrange and
Almansi strain tensors.
Thus we can deduce the variation of the Almansi strain
$$\begin{equation}
\begin{aligned}
\var \Be
= \BF\invtra \var\BE\BF\inv
&= \frac{1}{2} [\nabla(\vvphi)\BF\inv+\BF\invtra \nabla(\vvphi)\tra] \\
&= \frac{1}{2} [\nabla_x(\vvphi)+ \nabla_x(\vvphi)\tra]
\end{aligned}
\end{equation}$$
where we have used the identity
$$\begin{equation}
\nabla_X(\cdot)\BF\inv = \nabla_x(\cdot).
\label{eq:defgradidentity1}
\end{equation}$$
The second Piola-Kirchhoff stress is the
pull-back of the Kirchhoff stress $\Btau$:
$$\begin{equation}
\BS = \pull(\Btau) = \BF\inv\Btau\BF\invtra
\end{equation}$$
Then it is evident that
$$\begin{equation}
\BS:\var\BE
= (\BF\inv\Btau\BF\invtra):(\BF\tra\var\Be\BF)
= \Btau:\var\Be
\end{equation}$$
We can thus write the Eulerian version of \eqref{eq:lagrangianform1}:
$$\begin{equation}
\boxed{
G(\Bvarphi,\vvphi)
= \int_\CB \Btau: \var\Be \dV
- \int_\CB \rho_0\bar{\BGamma}\dtp\vvphi \dV
- \int_{\del\CB} \bar{\BT}\dtp\vvphi \dA = 0
}
\end{equation}$$
Introducing the Cauchy stresses $\Bsigma=\Btau/J$, we can also transport the
integrals to the current configuration
$$\begin{equation}
\boxed{
G(\Bvarphi,\vvphi)
= \int_\CS \Bsigma:\var\Be \dv
- \int_\CS \rho\bar{\Bgamma}\dtp\vvphi \dv
- \int_{\del\CS_t} \bar{\Bt}\dtp\vvphi \da = 0
}
\end{equation}$$
Here, we substituted the following differential identities:
$$\begin{equation}
\rho_0\BGamma\dV = \rho\Bgamma\dv
\end{equation}$$
for the body forces, and
$$\begin{equation}
\BT\dA
= \BP\BN \dA
= \Bsigma J\BF\invtra\BN \dA
= \Bsigma\Bn \da
= \Bt \da
\end{equation}$$
for the surface tractions, where we used the Piola identity.
## Linearization of the Variational Formulation
We linearize $G$:
$$\begin{equation}
\Lin G \evat_{\bar{\Bvarphi}}
= G(\bar{\Bvarphi}, \vvphi)
+ \Var G \evat_{\bar{\Bvarphi}}
= 0
\end{equation}$$
Then we have the variational setting
$$\begin{equation}
a(\Vvphi,\vvphi)=b(\vvphi)
\end{equation}$$
where
$$\begin{equation}
a(\Vvphi,\vvphi) = \Var G \evat_{\bar{\Bvarphi}}
\eqand
b(\vvphi) = -G(\bar{\Bvarphi}, \vvphi)
\end{equation}$$
Commutative diagram of the linearized solution procedure. Each
iteration brings the current iterate $\bar{\Bvarphi}$ closer to the optimum
value $\Bvarphi^\ast$.
Mappings between line elements belonging to the tangent spaces of
the linearization.
The variation $\Var G$ is calculated as
$$\begin{equation}
\Var G
= \varn{G}{\Bvarphi}{\Vvphi}
= \int_\CB [\Var\BS:\var\BE + \BS:\Var(\var\BE)] \dV
\end{equation}$$
Consecutive variations of the Green-Lagrange strain tensor is calculated as
$$\begin{equation}
\Var(\var\BE) = \varn{\var\BE}{\Bvarphi}{\Vvphi}
= \frac{1}{2}[\nabla(\vvphi)\tra\nabla(\Vvphi) + \nabla(\Vvphi)\tra\nabla(\vvphi)]
\end{equation}$$
The term on the left is calculated as
$$\begin{equation}
\Var\BS = \varn{\BS}{\Bvarphi}{\Vvphi}
= \partd{\BS}{\BC}:\Var\BC
= 2 \partd{\BS}{\BC}:\Var\BE
\end{equation}$$
where we substitute the Lagrangian elasticity tensor
$$\begin{equation}
\BFC := 2 \partd{\BS}{\BC} = 4\rho_0 \frac{\del^2\Psi}{\del\BC\del\BC}
\end{equation}$$
and $\Var\BE$ is calculated in the same manner as $\var\BE$:
$$\begin{equation}
\Var\BE = \frac{1}{2} [\nabla(\Vvphi)\tra\BF + \BF\tra\nabla(\Vvphi)]
\end{equation}$$
Then the variational forms of the linearized setting are
$$\begin{equation}
\boxed{
\begin{aligned}
a(\Vvphi,\vvphi)
&= \int_\CB \var\bar{\BE}:\bar{\BFC}:\Var\bar{\BE}
+ \bar{\BS} : [\nabla(\vvphi)\tra\nabla(\Vvphi)] \dV
\\
b(\vvphi)
&= - \int_\CB \bar{\BS}: \var\bar{\BE} \dV
+ \int_\CB \rho_0\bar{\BGamma}\dtp\vvphi \dV
+ \int_{\del\CB} \bar{\BT}\dtp\vvphi \dA
\end{aligned}
}
\end{equation}$$
where the bars denote evaluation $\Bvarphi=\bar{\Bvarphi}$ of dependent
variables.
## Eulerian Version of the Linearization
We also have the following relationship between the Lagrangian and Eulerian
elasticity tensors
$$\begin{equation}
c_{abcd} = F_{aA}F_{bB}F_{cC}F_{dD} C_{ABCD}
\end{equation}$$
Substituting Eulerian expansions, we obtain the
following identity:
$$\begin{equation}
\begin{aligned}
\var\BE:\BFC:\Var\BE
&= (\BF\tra\var\Be\BF):\BFC:(\BF\tra\Var\Be\BF) \\
&=F_{aA}\var e_{ab} F_{bB} C_{ABCD} F_{cC}\Var e_{cd}F_{dD} \\
&=\var e_{ab} c_{abcd} \Var e_{cd} \\
&= \var\Be:\BFc:\Var\Be
\end{aligned}
\end{equation}$$
Thus we have
$$\begin{equation}
\begin{aligned}
\BS:[\nabla(\vvphi)\tra\nabla(\Vvphi)]
&= [\BF\inv\Btau\BF\invtra] :[\nabla(\vvphi)\tra\nabla(\Vvphi)] \\
&= \Btau : [(\nabla(\vvphi)\BF\inv)\tra\nabla(\Vvphi)\BF\inv] \\
&= \Btau : [\nabla_x(\vvphi)\tra\nabla_x(\Vvphi)] \\
\end{aligned}
\end{equation}$$
With these results at hand, we can write the Eulerian version of our variational
formulation:
$$\begin{equation}
\boxed{
\begin{aligned}
a(\Vvphi,\vvphi)
&= \int_\CB \var\bar{\Be}:\bar{\BFc}:\Var\bar{\Be}
+ \bar{\Btau} : [\nabla_{\bar{x}}(\vvphi)\tra\nabla_{\bar{x}}(\Vvphi)] \dV
\\
b(\vvphi)
&= - \int_\CB
\bar{\Btau}:\var\bar{\Be} \dV
+ \int_\CB \rho_0\bar{\BGamma}\dtp\vvphi \dV
+ \int_{\del\CB} \bar{\BT}\dtp\vvphi \dA
\end{aligned}
}
\end{equation}$$
If we introduce the Cauchy stress tensor $\Bsigma$ and corresponding elasticity tensor
$\BFc^\sigma = \BFc/J$,
our variational formulation can be expressed completely in terms of Eulerian quantities:
$$\begin{equation}
\boxed{
\begin{aligned}
a(\Vvphi,\vvphi)
&= \int_{\bar{\CS}} \var\bar{\Be}:\bar{\BFc}^\sigma:\Var\bar{\Be}
+ \bar{\Bsigma} : [\nabla_{\bar{x}}(\vvphi)\tra\nabla_{\bar{x}}(\Vvphi)] \,\dif\bar{v}
\\
b(\vvphi)
&= - \int_{\bar{\CS}}
\bar{\Bsigma}:\var\bar{\Be} \,\dif\bar{v}
+ \int_{\bar{\CS}} \rho\bar{\Bgamma}\dtp\vvphi \,\dif\bar{v}
+ \int_{\del\bar{\CS}_t} \bar{\Bt}\dtp\vvphi \,\dif\bar{a}
\end{aligned}
}
\end{equation}$$
We have the following relationships of the differential forms:
$$\begin{equation}
\dif \bar{v} = \bar{J}\dv
\eqand
\bar{\Bn} \,\dif \bar{a} = \cof \bar{\BF}\BN \dA
\end{equation}$$
where $\bar{\BF} = \nabla_X\bar{\Bvarphi}$ and $\bar{J} = \det\bar{\BF}$.
## Discretization of the Lagrangian Form
We use the following FE discretization:
$$\begin{equation}
\Bvarphi_h
= \suml{\gamma=1}{\nnode} \Bvarphi^\gamma N^\gamma
= \suml{\gamma=1}{\nnode}\suml{a=1}{\ndim} \varphi_a^\gamma \Be_a N^\gamma
\end{equation}$$
where $\nnode$ is the number of element nodes and $\ndim$ is the number of
spatial dimensions.
We use the same discretization for $\vvphi$ and $\Vvphi$. Then the linear system
at hand becomes
$$\begin{equation}
\suml{\delta=1}{\nnode}\suml{b=1}{\ndim}A_{ab}^{\gamma\delta} \Var\varphi_b^\delta = b_a^\gamma
\end{equation}$$
for $a=1,\dots,\ndim$ and $\gamma=1,\dots,\nnode$ where the $\BA$ and $\Bb$
are calculated from the variational forms as
$$\begin{equation}
\begin{aligned}
A_{ab}^{\gamma\delta} &= a(\Be_bN^\delta, \Be_aN^\gamma) \\
b_a^\gamma &= b(\Be_aN^\gamma)
\end{aligned}
\end{equation}$$
For detailed derivation, see the post
[Vectorial Finite Elements](/2017/11/21/vectorial-finite-elements/).
For discretized gradients, we have the following relationship
$$\begin{equation}
\nabla_X(\Be_aN^\gamma) = (\Be_a\dyd\BB^\gamma)
\end{equation}$$
where $\BB^\gamma:= \nabla_X N^\gamma$. For the first term in $a$, we can get rid of the symmetries:
$$\begin{equation}
\begin{aligned}
\sym&(\bar{\BF}\tra\nabla(\Be_aN^\gamma)):\bar{\BFC}:
\sym(\bar{\BF}\tra\nabla(\Be_bN^\delta)) \\
&= (\bar{\BF}\tra(\Be_a\dyd\BB^\gamma)):\bar{\BFC}:
(\bar{\BF}\tra(\Be_b\dyd\BB^\delta)) \\
&= \bar{F}_{aA}B^\gamma_B\bar{C}_{ABCD}\bar{F}_{bC}B^\delta_D
\end{aligned}
\end{equation}$$
and for the second term, we have
$$\begin{equation}
\begin{aligned}
\bar{\BS}:[\nabla(\Be_aN^\gamma)\tra \nabla(\Be_bN^\delta)]
&= \bar{\BS}:[(\Be_a\dyd \BB^\gamma)\tra (\Be_b \dyd \BB^\delta)] \\
&= \bar{\BS}:[\BB^\gamma\dyd\BB^\delta] g_{ab} \\
&= B^\gamma_A \bar{S}_{AB}B^\delta_B g_{ab}
\end{aligned}
\end{equation}$$
where $g_{ab}$ are the components of the Eulerian metric tensor.
For the first term in $b$, we have
$$\begin{equation}
\bar{\BS} : \sym(\bar{\BF}\tra\nabla(\Be_aN^\gamma))
= \bar{\BS} : (\bar{\BF}\tra(\Be_a \dyd \BB^\gamma))
= \bar{S}_{AB} \bar{F}_{aA} B^\gamma_B
\end{equation}$$
Remaining terms can be calculated in a straightforward manner. We then have for
$\BA$ and $\Bb$:
$$\begin{equation}
\boxed{
\begin{aligned}
A_{ab}^{\gamma\delta}
&= \int_\CB
\bar{F}_{aA}B^\gamma_B\bar{C}_{ABCD}\bar{F}_{bC}B^\delta_D
+ B^\gamma_A \bar{S}_{AB}B^\delta_B g_{ab} \dV
\\
b_a^\gamma
&= -\int_\CB
\bar{S}_{AB} \bar{F}_{aA} B^\gamma_B \dV
+ \int_\CB\rho_0\bar{\Gamma}_aN^\gamma \dV
+ \int_{\del\CB_t}\bar{T}_aN^\gamma \dA
\end{aligned}
}
\end{equation}$$
The lowercase indices in $\bar{\Bgamma}$ and $\bar{\BT}$ might be confusing, but
in fact
$$\begin{equation}
\begin{aligned}
\Gamma_a(\BX,t) &= \gamma_a(\Bx, t) \circ \Bvarphi(\BX,t) \\
T_a(\BX,t) &= t_a(\Bx, t) \circ \Bvarphi(\BX,t) \\
\end{aligned}
\end{equation}$$
The system is solved for $\Vvphi$ at each Newton iteration with the following
update equation:
$$\begin{equation}
\Bvarphi \leftarrow \bar{\Bvarphi} + \Vvphi
\label{eq:lagrangianupdate1}
\end{equation}$$
## Discretization of the Eulerian Form
Discretization of the Eulerian formulation parallels that of Lagrangian.
$$\begin{gather}
\boxed{
\begin{aligned}
A_{ab}^{\gamma\delta}
&= \int_\CB
\bar{B}^\gamma_c \bar{c}_{acbd}\bar{B}^\delta_d
+ \bar{B}^\gamma_e \bar{\tau}_{ef}\bar{B}^\delta_f g_{ab} \dV
\\
b_a^\gamma
&= -\int_\CB
\bar{\tau}_{ab} \bar{B}^\gamma_b \dV
+ \int_\CB\rho_0 \bar{\Gamma}_aN^\gamma \dV
+ \int_{\del\CB_t}\bar{T}_aN^\gamma \dA
\end{aligned}
}
\\
\text{or} \nonumber
\\
\boxed{
\begin{aligned}
A_{ab}^{\gamma\delta}
&= \int_{\bar{\CS}}
\bar{B}^\gamma_c \bar{c}^\sigma_{acbd}\bar{B}^\delta_d
+ \bar{B}^\gamma_e \bar{\sigma}_{ef}\bar{B}^\delta_f g_{ab} \,\dif\bar{v}
\\
b_a^\gamma
&= -\int_{\bar{\CS}}
\bar{\sigma}_{ab} \bar{B}^\gamma_b \,\dif\bar{v}
+ \int_{\bar{\CS}}\rho \bar{\gamma}_aN^\gamma \,\dif\bar{v}
+ \int_{\del\bar{\CS}_t}\bar{t}_aN^\gamma \,\dif\bar{a}
\end{aligned}
}
\end{gather}$$
Here, $\bar{\BB}^\gamma = \nabla_{\bar{x}} N^\gamma$ denote the spatial
gradients of the shape functions. One way of calculating is
$\bar{\BB}^\gamma = \bar{\BF}\invtra\BB^\gamma$, similar to
\eqref{eq:defgradidentity1}.
The update equation
\eqref{eq:lagrangianupdate1} holds for the Eulerian version.
# Conclusion
The equations above in boxes contain all the information needed to implement the
nonlinear solution scheme of hyperelasticity.
==========
---
title: "Discontinuous Divergence Theorem"
date: 2018-01-24
canonical: https://solmaz.io/2018/01/24/discontinuous-divergence-theorem/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In [lecture](http://www1.mate.polimi.it/~antonietti/PERSONAL_WEBPAGE/Teaching_files/Antonietti_DGintro_2.pdf)
[notes](http://sanum.github.io/2016/slides/Reddy.pdf)
related to the
[Discontinuous Galerkin method](https://en.wikipedia.org/wiki/Discontinuous_Galerkin_method),
there is
mention of a *magic formula* which AFAIK first appeared on a paper[^arnold82] by
Douglas Arnold (at least in this context).
It has been proven and all, but it's still called magic because its reasoning is
not apparent at first glance. The magic formula is actually a superset of
the divergence theorem, generalized to discontinuous fields. But to make that
generalization, we need to abandon the standard formulation which starts by
creating a triangular mesh, and consider arbitrary partitionings of a domain.
A domain $\Omega$ is partitioned into parts $P^i$, $i=1,\dots,n$ as follows:
$$\Omega=\bigcup_{i=1}^{n} P^i$$
$$\mathcal{P} = \{P^1,\dots,P^{n}\}$$
We call the set of parts $\mathcal{P}$ a **partition** of $\Omega$.
# Broken Hilbert Spaces
We allow the vector field $\boldsymbol{u}$ to be **discontinuous at
boundaries** $\partial P^i$ and **continuous in** $P^i$, $i=1,\dots,n$.
To this end, we define the **broken Hilbert
space** over partition $\mathcal{P}$
$$\begin{equation}
H^m(\mathcal{P}) := \{\boldsymbol{v}\in L^2(\Omega)^{n_d} \mid \forall P\in\mathcal{P}, \boldsymbol{v}|_P \in H^m(P)\}
\end{equation}$$
It can be seen that $H^m(\mathcal{P})\subseteq H^m(\Omega)$.
# Part Boundaries
Topologically, a part may share boundary with $\Omega$, like $P^4$.
In that case, the boundary of the part is divided into an
**interior** boundary and **exterior** boundary:
$$\begin{equation}
\partial P_{\text{ext}}^i = \partial P^i \cap \partial\Omega
\quad\text{and}\quad
\partial P_{\text{int}}^i = \partial P^i \setminus \partial P_{\text{ext}}^i
\end{equation}$$
If a part has an exterior boundary, it is said to be an **external** part
($P^3$, $P^4$, $P^5$, $P^6$). If it
does not have any exterior boundary, it is said to be an **internal**
part.($P^1$, $P^2$).
# Divergence theorem over parts
For a vector field $\boldsymbol{v}\in H^1(\mathcal{P})$,
$i=1,\dots,n$, we can write the following integral as a sum and apply the
divergence theorem afterward
$$\begin{equation}
\begin{aligned}
\int_\Omega \div{\boldsymbol{v}} \,dV
&= \sum\limits_{i=1}^{n}\int_{P^i}\div\boldsymbol{v} \,dV
= \sum\limits_{i=1}^{n}\int_{\partial P^i} \boldsymbol{v}\cdot\boldsymbol{n} \,dA \\
&= \sum\limits_{i=1}^{n}\int_{\partial P_{\text{ext}}^i} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
+\sum\limits_{i=1}^{n}\int_{\partial P_{\text{int}}^i} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
\end{aligned}
\end{equation}$$
We define the portion $\Gamma^{ij}$ of the boundary that part
$P^i$ shares with $P^j$ as the **interface** between $P^i$ and $P^j$.
$$\begin{equation}
\Gamma^{ij} = \partial P^i \cap \partial P^j
\end{equation}$$
If $P^i$ and $P^j$ are not neighbors, we simply have $\Gamma^{ij}=\emptyset$.
# Integrals over interior boundaries
For opposing parts $P^i$ and $P^j$,
we have different values of the function $\boldsymbol{v}^{ij} = \boldsymbol{v}|_{\Gamma^{ij}}$
and conjugate normal vectors at the
interface $\Gamma^{ij}$:
$$\begin{equation}
\boldsymbol{v}^{ij}\neq\boldsymbol{v}^{ji}
\quad\text{and}\quad
\boldsymbol{n}^{ij} = -\boldsymbol{n}^{ji}
\end{equation}$$
Since
$$\begin{equation}
\partial P_{\text{int}}^i
= \bigcup_{j=1}^{n} \Gamma^{ij}
\quad \text{for}\quad i=1,\dots,n
\end{equation}$$
we can rearrange the integral over interior boundaries as
$$\begin{equation}
\sum\limits_{i=1}^{n}\int_{\partial P_{\text{int}}^i} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
= \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\int_{\Gamma^{ij}} \boldsymbol{v}^{ij}\cdot\boldsymbol{n}^{ij} \,dA
\end{equation}$$
# The jump operator
Integrals over the same interface can be grouped together:
$$\begin{equation}
\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\int_{\Gamma^{ij}} \boldsymbol{v}^{ij}\cdot\boldsymbol{n}^{ij} \,dA
=
\sum\limits_{i=1}^{n}\sum\limits_{j=i}^{n}\int_{\Gamma^{ij}\equiv\Gamma^{ji}}
(\boldsymbol{v}^{ij}\cdot\boldsymbol{n}^{ij} + \boldsymbol{v}^{ji}\cdot\boldsymbol{n}^{ji}) \,dA
\end{equation}$$
Defining the **jump** of $\boldsymbol{v}$ across $\Gamma^{ij}$
$$\begin{equation}
\llbracket\boldsymbol{v}\rrbracket_{\Gamma^{ij}} = \boldsymbol{v}^{ij} - \boldsymbol{v}^{ji}
\end{equation}$$
The jump of a function measures its discontinuity across interfaces.
We can write
$$\begin{equation}
\int_{\Gamma^{ij}} \llbracket\boldsymbol{v}\rrbracket_{\Gamma^{ij}}\cdot\boldsymbol{n}^{ij} \,dA
= \int_{\Gamma^{ij}} (\boldsymbol{v}^{ij}\cdot\boldsymbol{n}^{ij} + \boldsymbol{v}^{ji}\cdot\boldsymbol{n}^{ji}) \,dA
\end{equation}$$
We may drop the superscripts where there is no confusion.
# Interfaces and external boundaries
It is convenient to group the interfaces:
$$\begin{equation}
\boxed{
\mathcal{I} := \{\Gamma^{ij}\mid i=1,\dots,n; j=i,\dots,n\}
}
\end{equation}$$
which allows us to write
$$\begin{equation}
\sum\limits_{i=1}^{n}\sum\limits_{j=i}^{n}
\int_{\Gamma^{ij}} \llbracket\boldsymbol{v}\rrbracket\cdot\boldsymbol{n} \,dA
= \sum\limits_{\Gamma\in\mathcal{I}} \int_{\Gamma} \llbracket\boldsymbol{v}\rrbracket\cdot\boldsymbol{n}\,dA
\end{equation}$$
It's obvious that the union of part external boundaries equals the domain boundary:
$$\begin{equation}
\bigcup_{i=1}^{n} \partial P_{\text{ext}}^i = \partial \Omega
\end{equation}$$
which allows us to write
$$\begin{equation}
\sum\limits_{i=1}^{n}\int_{\partial P_{\text{ext}}^i} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
= \int_{\partial\Omega} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
\end{equation}$$
With the results obtained, we put forward a **generalized** version of the divergence
theorem: Let $\boldsymbol{v}\in H^1(\mathcal{P})$ be a vector field. Then we have
$$\begin{equation}
\boxed{
\int_\Omega \div\boldsymbol{v} \,dV
= \int_{\partial\Omega} \boldsymbol{v}\cdot\boldsymbol{n} \,dA
+ \sum\limits_{\Gamma\in\mathcal{I}} \int_{\Gamma} \llbracket\boldsymbol{v}\rrbracket\cdot\boldsymbol{n} \,dA
}
\end{equation}$$
Verbally,
the **integral of the divergence of a vector field over a domain** $\Omega$
equals
**its integral over the domain boundary** $\partial\Omega$,
plus
the **integral of its jump over part interfaces** $\mathcal{I}$.
In the case of a **continuous field**, the jumps **vanish** and this
reduces to the regular divergence theorem.
# The Magic Formula
There are different versions of the magic formula for scalar, vector and tensor
fields, and for different IBVPs. I won't try to derive them all, but give an
example: If we were substitute a linear mapping
$\boldsymbol{A}\boldsymbol{v}$
instead of $\boldsymbol{v}$, we would have the jump
$\llbracket \boldsymbol{A}\boldsymbol{v} \rrbracket$ on the right-hand side.
We introduce the vector and tensor **average** operator $$\{\cdot\}$$
$$\begin{equation}
\{\boldsymbol{v}\}_{\Gamma^{ij}} = \frac{1}{2} (\boldsymbol{v}^{ij} + \boldsymbol{v}^{ji})
\quad\text{and}\quad
\{\boldsymbol{A}\}_{\Gamma^{ij}} = \frac{1}{2} (\boldsymbol{A}^{ij} + \boldsymbol{A}^{ji})
\end{equation}$$
and **tensor jump** operator
$\llbracket\cdot\rrbracket$
$$\begin{equation}
\llbracket\boldsymbol{A}\rrbracket_{\Gamma^{ij}} = \boldsymbol{A}^{ij} - \boldsymbol{A}^{ji}
\end{equation}$$
We also note the boundary jump/average property which is used on the integral
over $\partial\Omega$
$$\begin{equation}
\boxed{
\{\boldsymbol{v}\} = \llbracket\boldsymbol{v}\rrbracket = \boldsymbol{v}
\quad \text{on}\quad\partial\Omega
}
\label{eq:property1}
\end{equation}$$
(**This property is used implicitly in many places, and often causes confusion**).
These definitions allow us to write the identity
$$\begin{equation}
\boxed{
\llbracket\boldsymbol{A}\boldsymbol{v}\rrbracket = \llbracket\boldsymbol{A}\rrbracket\{\boldsymbol{v}\} + \{\boldsymbol{A}\}\llbracket\boldsymbol{v}\rrbracket
}
\end{equation}$$
which is easily proven when expanded.
The different versions of the magic formula are obtained by
substituting the identities above---or their analogs---in the discontinuous
divergence theorem.
[^arnold82]: Douglas N. Arnold. An interior penalty finite element method with discontinuous elements. SIAM J. Numer. Anal., 19(4):742--760, 1982.
==========
---
title: "Nonlinear Finite Elements"
date: 2017-12-22
canonical: https://solmaz.io/2017/12/22/nonlinear-finite-elements/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
This post builds on the formulations I showed in my previous posts by
introducing their nonlinear versions.
In a typical nonlinear problem, the variational setting leads to the weak formulation
> Find $u\in V$ such that
>
> $$\begin{equation}
> F(u,v) = 0
> \label{eq:femnonlinear2}
> \end{equation}$$
>
> for all $v\in V$ where the semilinear form
> $F$ is nonlinear in terms of $u$ and linear in terms of $v$.
We linearize $F$:
$$\begin{equation}
\Lin [F(u,v)]_{u=\bar{u}} = F(\bar{u}, v)
+ \varn{F(u,v)}{u}{\Var u}\evat_{u=\bar{u}}
\label{eq:femnonlinear4}
\end{equation}$$
Equating \eqref{eq:femnonlinear4} to zero yields a linear system in terms of
$\Var u$
$$\begin{equation}
\boxed{
a(\Var u, v) = b(v)
}
\label{eq:femnonlinear6}
\end{equation}$$
where
$$\begin{equation}
\boxed{
\begin{aligned}
a(\Var u, v) &= \varn{F(u,v)}{u}{\Var u}\evat_{u=\bar{u}} \\
b(v) &= -F(\bar{u}, v)
.
\end{aligned}
}
\label{eq:femnonlinear5}
\end{equation}$$
We can compute the components of the matrices and vectors according to \eqref{eq:femnonlinear6}
$$\begin{equation}
\boxed{
\begin{alignedat}{3}
\Aelid{I\!J}{} &= a(N^J,N^I)
&&= \varn{F(u,N^I)}{u}{N^J}\evat_{u=\bar{u}} \\
b^{I} &= b(N^I)
&&= -F(\bar{u}, N^I).
\end{alignedat}
}
\label{eq:femnonlinear9}
\end{equation}$$
Then the update vector $\Var \Bu = [\Var u^1, \Var u^2, \dots, \Var
u^\nnode]\tra$ is obtained by solving
$$\begin{equation}
\BA \Var \Bu = \Bb
\end{equation}$$
Letting $\Var u$ be the difference between consequent iterates, we obtain the
update equation as
$$\begin{equation}
\boxed{
\Bu \leftarrow \bar{\Bu} + \Var\Bu
}
\end{equation}$$
## Example: Nonlinear Poisson's Equation
Consider the following nonlinear Poisson's equation
$$\begin{equation}
\begin{alignedat}{4}
- \nabla \dtp (g(u)\nabla u) &= f \quad && \text{in} \quad && \Omega \\
u &= 0 \quad && \text{on} \quad && \del\Omega
\end{alignedat}
\label{eq:femnonlinear8}
\end{equation}$$
The weak formulation reads
> Find $u\in V$ such that
>
> $$\begin{equation}
> - \int_\Omega \nabla \dtp (g(u)\nabla u) v \dv= \int_\Omega f v \dv
> \end{equation}$$
>
> for all $v\in V$ where $V=H^1_0(\Omega)$.
Applying integration by parts and divergence theorem on the left-hand side
$$\begin{equation}
\begin{aligned}
\int_\Omega \nabla \dtp (g(u)\nabla u) v \dv
&= \int_\Omega \nabla \dtp (g(u)\nabla (u) v) \dv
- \int_\Omega g(u)\nabla u\dtp\nabla v \dv \\
&= \underbrace{\int_{\del\Omega} g(u) v (\nabla u\dtp\Bn) \da}_{v = 0
\text{ on } \del\Omega}
- \int_\Omega g(u)\nabla u\dtp\nabla v \dv \\
\end{aligned}
\end{equation}$$
Thus we have the semilinear form
$$\begin{equation}
F(u,v) = \int_{\Omega} g(u) \nabla u \dtp \nabla v \dv - \int_{\Omega} f \,
v \dv = 0
\end{equation}$$
The linearized version of this problem is then with \eqref{eq:femnonlinear5}
$$\begin{equation}
\begin{aligned}
a(\Var u,v) &= \int_{\Omega}
\rbr{\deriv{g}{u}\evat_{\bar{u}} \Var u\, \nabla \bar{u}
+ g(\bar{u})\nabla(\Var u)} \dtp \nabla v \dv \\
b(v) &= \int_{\Omega} [f \, v - g(\bar{u}) \nabla \bar{u} \dtp \nabla v] \dv\\
\end{aligned}
\end{equation}$$
and the matrix and vector components are with \eqref{eq:femnonlinear9}
$$\begin{equation}
\begin{aligned}
\Aelid{I\!J}{} &= \int_{\Omega}
\rbr{\deriv{g}{u}\evat_{\bar{u}} N^J \, \nabla \bar{u}
+ g(\bar{u})\BB^J} \dtp \BB^I \dv \\
b^{I} &= \int_{\Omega} [f \, N^I - g(\bar{u}) \nabla \bar{u} \dtp \BB^I ] \dv\\
\end{aligned}
\end{equation}$$
where the previous solution and its gradient are computed as
$$\begin{equation}
\bar{u} = \suml{I=1}{\nnode} \bar{u}^I N^I
\eqand
\nabla \bar{u} = \suml{I=1}{\nnode} \bar{u}^I \BB^I
.
\end{equation}$$
# Nonlinear Time-Dependent Problems
In the case of a nonlinear time-dependent problem, we have the following weak
form:
> Find $u \in V$ such that
>
> $$\begin{equation}
> m(\dot{u}, v; t) + F(u,v; t) = 0
> \label{eq:nonlineartimedependentweak1}
> \end{equation}$$
>
> for all $v \in V$ and $t \in [0,\infty)$
> where $F$ is a semilinear form.
Discretization yields the following nonlinear system of equations
$$\begin{equation}
\BM(t)\Bu + \Bf(u; t) = \Bzero
\end{equation}$$
where
$$\begin{equation}
\begin{aligned}
M^{I\!J}(t) &= m(N^J, N^I; t) \\
f^{I}(u;t) &= F(u, N^I; t).
\end{aligned}
\end{equation}$$
## Explicit Euler Scheme
We discretize in time with the finite difference
$\dot{u} \approx [u_{n+1}-u_n]/{\Delta t}$ and linearity allows us to write
\begin{equation}
\boxed{
m(\dot{u}, v; t)
\approx \frac{1}{\Delta t} [m(u_{n+1}, v; t_{n+1}) - m(u_n, v; t_n)]
}
\label{eq:discretetimedependent1}
\end{equation}
We discretize the variational forms in time according to
\eqref{eq:discretetimedependent1}, and evaluate the remaining terms at $t_n$:
$$\begin{equation}
\frac{1}{\Delta t} [m(u_{n+1},v;t_{n+1}) - m(u_{n},v;t_{n})] + F(u_n, v; t_n) = 0
\end{equation}$$
The corresponding system of equations is
$$\begin{equation}
\frac{1}{\Delta t} [\BM_{n+1}\Bu_{n+1} - \BM_n\Bu_n]
+ \Bf_n = \Bzero
\end{equation}$$
where $\Bf_n = \Bf(u_n, t_n)$. This yields the following update equation
$$\begin{equation}
\boxed{
\Bu_{n+1} = \BM_{n+1}\inv [\BM_n\Bu_n - \Delta t \Bf_n]
}
\end{equation}$$
For a time-independent $m$, this becomes
$$\begin{equation}
\Bu_{n+1} = \Bu_n - \Delta t \BM\inv\Bf_n
\end{equation}$$
## Implicit Euler Scheme
For the implicit scheme, we evaluate the remaining terms at $t_{n+1}$ and let
the result be equal to
$$\begin{equation}
G(u_{n+1}, v)
:= \frac{1}{\Delta t} [m(u_{n+1},v;t_{n+1}) - m(u_{n},v;t_{n})] + F(u_{n+1}, v; t_{n+1}) = 0
\end{equation}$$
We will hereon replace $u_{n+1}$ with $u$ for brevity.
The update of this nonlinear system requires the linearization of
$G(u, v)$:
$$\begin{equation}
\Lin[G(u,v)]_{u=\bar{u}}
= G(\bar{u}, v) + \varn{G}{u}{\Var u}\evat_{u=\bar{u}} = 0
\end{equation}$$
We thus have the following linear setting for the Newton update $\Var u$:
$$\begin{equation}
a(\Var u, v) = b(v)
\end{equation}$$
where
$$\begin{equation}
\begin{aligned}
a(\Var u, v)
&:= \varn{G}{u}{\Var u} \evat_{u=\bar{u}}
= \frac{1}{\Delta t} m(\Var u, v; t_{n+1})
+ \varn{F(u, v; t_{n+1})}{u}{\Var u} \evat_{u=\bar{u}} \\
b(v) &:= -G(\bar{u}, v)
= - F(\bar{u}, v; t_{n+1})
-\frac{1}{\Delta t} [m(\bar{u},v;t_{n+1}) - m(u_{n},v;t_{n})]
\end{aligned}
\end{equation}$$
Discretization yields
$$\begin{equation}
\rbr{\frac{1}{\Delta t} \BM_{n+1} + \tilde{\BA}}\Var \Bu
= \Bb
\end{equation}$$
where
$$\begin{equation}
\tilde{A}^{I\!J} := \varn{F(u, N^I;t_{n+1})}{u}{N^J} \evat_{u=\bar{u}}
\eqand
b^I := b(N^I)
\end{equation}$$
The Newton update is rendered
$$\begin{equation}
\boxed{
\Bu \leftarrow \bar{\Bu} + \Var\Bu
\eqwith
\Var \Bu
= [\frac{1}{\Delta t} \BM_{n+1} + \tilde{\BA}]\inv\Bb
}
\end{equation}$$
which is repeated until the solution for the next timestep $\Bu$ converges
to a satisfactory value.
# Nonlinear Coupled Problems
For a nonlinear coupled problem, the weak formulation is as follows
> Find $u\in V_1$, $y\in V_2$ such that
>
> $$\begin{equation}
> \begin{aligned}
> F(u, y, v) &= 0 \\
> G(u, y, w) &= 0 \\
> \end{aligned}
> \label{eq:nonlinearcoupled1}
> \end{equation}$$
>
> for all $v\in V_1$, $w \in V_2$ where
> $F(\cdot,\cdot, \cdot)$, $G(\cdot, \cdot, \cdot)$ are nonlinear in terms of
> $u$ and $y$ and linear in terms of $v$ and $w$.
We linearize the semilinear forms about the nonlinear terms:
$$\begin{equation}
\begin{alignedat}{4}
\Lin[F(u, y, v)]_{\bar{u},\bar{y}}
&= F(\bar{u},\bar{y},v)
&&+ \varn{F(u, y, v)}{u}{\Var u} \evat_{\bar{u},\bar{y}}
&&+ \varn{F(u, y, v)}{y}{\Var y} \evat_{\bar{u},\bar{y}} \\
\Lin[G(u, y, w)]_{\bar{u},\bar{y}}
&= G(\bar{u},\bar{y},w)
&&+ \varn{G(u, y, w)}{u}{\Var u} \evat_{\bar{u},\bar{y}}
&&+ \varn{G(u, y, w)}{y}{\Var y} \evat_{\bar{u},\bar{y}}
\end{alignedat}
\label{eq:nonlinearcoupled2}
\end{equation}$$
where the evaluations take place at $u=\bar{u}$ and $y=\bar{y}$.
Equating the linearized residuals to zero, we obtain a linear system of the form
$$\begin{equation}
\begin{alignedat}{3}
a(u, v) &+ b(y, v) &&= c(v) \\
d(u, w) &+ e(y, w) &&= f(w) \\
\end{alignedat}
\label{eq:coupledweakform1}
\end{equation}$$
with the bilinear forms $a$, $b$, $d$, $e$ and the linear forms $c$, $f$ which
are defined as
$$\begin{equation}
\begin{gathered}
\begin{alignedat}{4}
a(\Var u, v) &:= \varn{F(u, y, v)}{u}{\Var u} \evat_{\bar{u},\bar{y}}
\quad &
b(\Var y, v) &:= \varn{F(u, y, v)}{y}{\Var y} \evat_{\bar{u},\bar{y}}
\\
d(\Var u, w) &:= \varn{G(u, y, w)}{u}{\Var u} \evat_{\bar{u},\bar{y}}
\quad &
e(\Var y, w) &:= \varn{G(u, y, w)}{y}{\Var y} \evat_{\bar{u},\bar{y}}
\end{alignedat}
\\
\text{and}
\\
\begin{aligned}
c(v) &:= -F(\bar{u},\bar{y},v) \\
f(w) &:= -G(\bar{u}, \bar{y}, w)
\end{aligned}
\end{gathered}
\end{equation}$$
Discretizing as done in the previous section, we obtain the following linear system of
equations
$$\begin{equation}
\begin{bmatrix}
\BA & \BB \\
\BD & \BE
\end{bmatrix}
\begin{bmatrix}
\Var \Bu \\ \Var \By
\end{bmatrix}
=
\begin{bmatrix}
\Bc \\ \Bf
\end{bmatrix}
\end{equation}$$
whose solution yields the update values $\Var \Bu$ and $\Var \By$. Thus the Newton
update equations are
$$\begin{equation}
\begin{alignedat}{3}
\Bu &\leftarrow \bar{\Bu} &&+ \Var\Bu \\
\By &\leftarrow \bar{\By} &&+ \Var\By
.
\end{alignedat}
\end{equation}$$
## Example: Cahn-Hilliard Equation
The Cahn-Hilliard equation describes the process of phase separation, by which
the two components of a binary fluid spontaneously separate and form domains
pure in each component. The problem is nonlinear, coupled and time-dependent.
The IBVP reads
$$\begin{equation}
\begin{alignedat}{4}
\partd{c}{t} &= \nabla\dtp(\BM\nabla \mu)
\qquad&& \text{in} \qquad&& \Omega\times I \\
\nabla c\dtp\Bn &= 0 && \text{on} && \del\Omega\times I\\
\nabla \mu\dtp\Bn &= 0 && \text{on} && \del\Omega\times I\\
c &= c_0 && \text{in} && \Omega, t = 0 \\
\mu &= 0 && \text{in} && \Omega, t = 0 \\
\end{alignedat}
\label{eq:cahnhilliard1}
\end{equation}$$
where
$$\begin{equation}
\mu = \deriv{f}{c} - \nabla\dtp(\BLambda\nabla c)
\label{eq:cahnhilliard2}
\end{equation}$$
and $t\in I = [0,\infty)$. Here,
- $c$ is the scalar variable for concentration,
- $\mu$ is the scalar variable for the chemical potential,
- $f: c \mapsto f(c)$ is the function representing chemical free energy,
- $\BM$ is a second-order tensor describing the mobility of the chemical,
- $\BLambda$ is a second-order tensor describing both the interface
thickness and direction of phase transition.
The fourth-order PDE governing the problem can be formulated as a coupled
system of two second-order PDEs with the variables $c$ and $\mu$, as
demonstrated in \eqref{eq:cahnhilliard1}
and \eqref{eq:cahnhilliard2}.
The weak formulation then reads
> Find $c \in V_1$, $\mu\in V_2$ such that
>
> $$\begin{equation}
> \begin{aligned}
> \int_\Omega \partd{c}{t} v \dx
> - \int_\Omega \nabla\dtp(\BM\nabla \mu) v \dx &=0 \\
> \int_\Omega \sbr{\mu - \deriv{f}{c}} w \dx
> + \int_\Omega \nabla\dtp(\BLambda\nabla c) w\dx &= 0
> \end{aligned}
> \end{equation}$$
>
> for all $v \in V_1$, $w \in V_2$ and $t \in I$.
We discretize in time implicitly with $\del c/\del t \approx
(c_{n+1}-c_n)/\Var t$. **We also denote the values for the next timestep
$c_{n+1}$ and $\mu_{n+1}$ as $c$ and $\mu$ for brevity.**
Using integration-by-parts, the divergence theorem, and the given boundary
conditions, we arrive at the following nonlinear forms
$$\begin{equation}
\begin{alignedat}{3}
F(c,\mu,v) &= \int_\Omega \frac{1}{\Var t} (c-c_n) v \dx
+ \int_\Omega (\BM\nabla \mu)\dtp \nabla v \dx &&= 0 \\
G(c,\mu,w) &= \int_\Omega \sbr{\mu - \deriv{f}{c}} w \dx
- \int_\Omega (\BLambda\nabla c)\dtp \nabla w\dx &&= 0
\end{alignedat}
\end{equation}$$
which is a nonlinear coupled system of the form \eqref{eq:nonlinearcoupled1}.
We linearize the forms according to \eqref{eq:nonlinearcoupled2} and obtain
the following variations
$$\begin{align*}
\varn{F}{c}{\Var c}
&= \int_\Omega \frac{1}{\Var t} \Var c\, v \dx \\
\varn{F}{\mu}{\Var \mu}
&= \int_\Omega (\BM\nabla (\Var\mu))\dtp \nabla v \dx \\
\varn{G}{c}{\Var c}
&= - \int_\Omega \dderiv{f}{c}\Var c \, w \dx
- \int_\Omega (\BLambda\nabla (\Var c))\dtp \nabla w\dx \\
\varn{G}{\mu}{\Var \mu}
&= \int_\Omega \Var\mu \, w \dx
\end{align*}$$
We substitute basis functions and obtain our system matrix
and vectors
$$\begin{align*}
P^{I\!J}
&= \int_\Omega \frac{1}{\Var t} N^JN^I \dx \\
Q^{IL}
&= \int_\Omega (\BM\BB^L)\dtp\BB^I \dx \\
r^{I}
&= \int_\Omega \frac{1}{\Var t}(\bar{c}-c_n)N^I \dx
+ \int_\Omega (\BM\nabla\bar{\mu})\dtp\BB^I\dx \\
S^{K\!J}
&= - \int_\Omega \dderiv{f}{c}\evat_{c=\bar{c}} N^J N^K \dx
- \int_\Omega (\BLambda \BB^J)\dtp \BB^K\dx \\
T^{K\!L}
&= \int_\Omega N^L N^K \dx \\
u^{K}
&= \int_\Omega \sbr{\bar{\mu} - \deriv{f}{c}\evat_{c=\bar{c}}} N^K \dx
- \int_\Omega (\BLambda\nabla \bar{c})\dtp \BB^K\dx
\end{align*}$$
which constitute the system
$$\begin{equation}
\begin{bmatrix}
\BP & \BQ \\
\BS & \BT
\end{bmatrix}
\begin{bmatrix}
\Var \Bc \\ \Var \Bmu
\end{bmatrix}
=
\begin{bmatrix}
\Br \\ \Bu
\end{bmatrix}
\end{equation}$$
Solution yields the update values $\Var \Bc$ and $\Var \Bmu$. The Newton
update equations are then
$$\begin{equation}
\begin{alignedat}{3}
\Bc &\leftarrow \bar{\Bc} &&+ \Var\Bc \\
\Bmu &\leftarrow \bar{\Bmu} &&+ \Var\Bmu
.
\end{alignedat}
\end{equation}$$
The system is solved for $c_{n+1}$ and $\mu_{n+1}$ at each $t=t_n$ to obtain
the evolutions of the concentration and chemical potential.
==========
---
title: "Coupled Finite Elements"
date: 2017-12-12
canonical: https://solmaz.io/2017/12/12/coupled-finite-elements/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In this post, I'll introduce the FE formulation of a generalized **linear** and
**coupled** weak form.
Said weak formulation has the form
> Find $u\in V_1$, $y\in V_2$ such that
>
> $$\begin{equation}
> \begin{alignedat}{3}
> a(u, v) &+ b(y, v) &&= c(v) \\
> d(u, w) &+ e(y, w) &&= f(w) \\
> \end{alignedat}
> \label{eq:coupledweakform1}
> \end{equation}$$
>
> for all $v\in V_1$, $w \in V_2$ where
> $a(\cdot, \cdot): V_1\times V_1 \to \IR$,
> $b(\cdot, \cdot): V_2\times V_1 \to \IR$,
> $d(\cdot, \cdot): V_1\times V_2 \to \IR$,
> $e(\cdot, \cdot): V_2\times V_2 \to \IR$
> are bilinear forms and
> $c(\cdot): V_1\to \IR$,
> $f(\cdot): V_2\to \IR$ are linear forms.
Here, the objective is to solve for the two unknown functions $u$ and $y$. One
can also imagine an arbitrary degree of coupling between $n$ variables with $n$
equations.
We introduce the following discretizations
$$\begin{equation}
\begin{alignedat}{3}
u_h &= \suml{J=1}{n_n^1} u^J N^J
\qquad\qquad &
v_h &= \suml{I=1}{n_n^1} u^I N^I
\qquad\qquad &
u_h, v_h\in V_{h1}
\\
y_h &= \suml{L=1}{n_n^2} u^L N^L
&
w_h &= \suml{K=1}{n_n^2} u^K N^K
&
y_h, w_h\in V_{h2}
\\
\end{alignedat}
\end{equation}$$
where the corresponding number of shape functions are $n_n^1$ and $n_n^2$, respectively.
Substituting the discretizations in \eqref{eq:coupledweakform1}, we obtain two
linear systems of equations
$$\begin{equation}
\begin{alignedat}{3}
\suml{J=1}{n_n^1} a(N^J, N^I) \,u^J
&+ \suml{L=1}{n_n^2} b(N^L, N^I) \, y^L
&&= c(N^I) \\
\suml{J=1}{n_n^1} d(N^J, N^K) \,u^J
&+ \suml{L=1}{n_n^2} e(N^L, N^K) \, y^L
&&= f(N^K) \\
\end{alignedat}
\end{equation}$$
for $I=1,\dots,n_n^1$ and $K=1,\dots,n_n^2$.
We write this system as
$$\begin{equation}
\boxed{
\begin{alignedat}{3}
\BA \Bu &+ \BB\By &&= \Bc \\
\BD \Bu &+ \BE\By &&= \Bf \\
\end{alignedat}
\eqor
\begin{bmatrix}
\BA & \BB \\
\BD & \BE
\end{bmatrix}
\begin{bmatrix}
\Bu \\ \By
\end{bmatrix}
=
\begin{bmatrix}
\Bc \\ \Bf
\end{bmatrix}
}
\label{eq:coupledsystem1}
\end{equation}$$
where the components of given matrices and vectors are defined as
$$\begin{equation}
\begin{alignedat}{6}
A^{I\!J} &:= a(N^J, N^I)
\qquad & B^{I\!L} &:= b(N^L, N^I)
\qquad & c^{I} &:= c(N^I)\\
D^{K\!J} &:= d(N^J, N^K)
& E^{K\!L} &:= e(N^L, N^K)
& f^{K} &:= f(N^K)\\
\end{alignedat}
\end{equation}$$
Solution of \eqref{eq:coupledsystem1} yields the unknown vectors $\Bu$ and $\By$.
==========
---
title: "Time-Dependent Finite Elements"
date: 2017-12-07
canonical: https://solmaz.io/2017/12/07/time-dependent-finite-elements/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Time dependent problems are commonplace in physics, chemistry and many other
disciplines. In this post, I'll introduce the FE formulation of linear
time-dependent problems and derive formulas for explicit and implicit Euler
integration.
The weak formulation of a first order time-dependent problem reads:
> Find $u \in V$ such that
>
> $$\begin{equation}
> m(\dot{u}, v; t) + a(u,v; t) = b(v; t)
> \label{eq:timedependentweak1}
> \end{equation}$$
>
> for all $v \in V$ and $t \in [0,\infty)$.
We can convert \eqref{eq:timedependentweak1} into a system of equations
$$\begin{equation}
\BM(t)\dot{\Bu} + \BA(t)\Bu = \Bb(t)
\end{equation}$$
where the components of the matrices and vectors involved are calculated as
$$\begin{equation}
\begin{aligned}
M^{I\!J}(t) &= m(N^J, N^I; t) \\
A^{I\!J}(t) &= a(N^J, N^I; t) \\
b^{I}(t) &= b(N^I; t).
\end{aligned}
\end{equation}$$
If we further discretize in time with the finite difference
$\dot{u} \approx [u_{n+1}-u_n]/{\Delta t}$, linearity allows us to write
$$\begin{equation}
\boxed{
m(\dot{u}, v; t)
\approx \frac{1}{\Delta t} [m(u_{n+1}, v; t_{n+1}) - m(u_n, v; t_n)]
}
\label{eq:discretetimedependent1}
\end{equation}$$
This reflects on the system as
$$\begin{equation}
\BM(t)\dot{\Bu} \approx
\frac{1}{\Delta t} [\BM_{n+1}\Bu_{n+1} - \BM_n\Bu_n]
\label{eq:discretetimedependent2}
\end{equation}$$
Here, $u_{n+1}:= u(x, t_{n+1})$,
$\BM_{n+1} = \BM(t_{n+1})$
and vice versa for $u_n$ and $\BM_n$.
## Explicit Euler Scheme
For the explicit Euler scheme, we substitute evaluate the remaining terms at $t_n$
$$\begin{equation}
\frac{1}{\Delta t} [m(u_{n+1}, v; t_{n+1}) - m(u_n, v; t_n)]
+ a(u_n,v; t_n) = b(v; t_n)
\quad
\forall v \in V\,.
\end{equation}$$
The corresponding system is
$$\begin{equation}
\frac{1}{\Delta t} [\BM_{n+1}\Bu_{n+1} - \BM_n\Bu_n]
+ \BA_n\Bu_n = \Bb_n
\end{equation}$$
The update equation becomes
$$\begin{equation}
\boxed{
\Bu_{n+1} = \BM_{n+1}\inv [\BM_n\Bu_n + \Delta t(\Bb_n - \BA_n\Bu_n)]
}
\end{equation}$$
If $m$ is time-independent, that is $m(\dot{u}, v;t) = m(\dot{u}, v)$, we have
$$\begin{equation}
\Bu_{n+1} = \Bu_n + \Delta t\, \BM\inv(\Bb_n - \BA_n\Bu_n)
\end{equation}$$
## Implicit Euler Scheme
For the implicit Euler scheme, we substitute evaluate the remaining terms at $t_{n+1}$
$$\begin{equation}
\frac{1}{\Delta t} [m(u_{n+1}, v; t_{n+1}) - m(u_n, v; t_n)]
+ a(u_n,v; t_{n+1}) = b(v; t_{n+1})
\quad
\forall v \in V\,.
\end{equation}$$
The corresponding system is
$$\begin{equation}
\frac{1}{\Delta t} [\BM_{n+1}\Bu_{n+1} - \BM_n\Bu_n]
+ \BA_{n+1}\Bu_{n+1} = \Bb_{n+1}
\end{equation}$$
The update equation becomes
$$\begin{equation}
\boxed{
\Bu_{n+1} = [\BM_{n+1}+\Delta t \BA_{n+1}]\inv [\BM_n\Bu_n + \Delta t \,\Bb_{n+1}]
}
\end{equation}$$
If $m$ is time-independent, one can just substitute $\BM=\BM_{n+1}=\BM_n$.
## Example: Reaction-Advection-Diffusion Equation
The IBVP of a linear reaction-advection-diffusion problem reads
$$\begin{equation}
\begin{alignedat}{4}
\partd{u}{t} &=
\nabla\dtp(\BD\nabla u) - \nabla\dtp(\Bc u) + ru + f
\qquad&& \text{in} \qquad&& \Omega\times I\\
u &= \bar{u} && \text{on} && \del\Omega\times I\\
u &= u_0 && \text{in} && \Omega, t = 0 \\
\end{alignedat}
\end{equation}$$
where $t\in I = [0,\infty)$,
- $\BD$ is a second-order tensor describing the diffusivity of $u$,
- $\Bc$ is a vector describing the velocity of advection,
- $r$ is a scalar describing the rate of reaction,
- and $f$ is a source term for $u$.
The weak formulation is then
> Find $u \in V$ such that
>
> $$\begin{equation}
> \int_\Omega \dot{u} v \dv =
> \int_\Omega [\nabla\dtp(\BD\nabla u) - \nabla\dtp(\Bc u) + ru + f] v \dv
> \end{equation}$$
>
> for all $v \in V$ and $t \in I$.
We have the following integration by parts relationships:
$$\require{cancel}\begin{equation}
\int_\Omega \nabla \dtp(\BD\nabla u) v \dv
= \cancel{\int_\Omega \nabla\dtp(v\BD\nabla u) \dv}
- \int_\Omega (\BD\nabla u)\dtp\nabla v \dv
\end{equation}$$
for the diffusive part and
$$\begin{equation}
\int_\Omega \nabla\dtp(\Bc u) v \dv
= \cancel{\int_\Omega \nabla \dtp (\Bc u v) \dv}
- \int_\Omega u \Bc \dtp \nabla v \dv
\end{equation}$$
for the advective part. The canceled terms are due to divergence theorem and
the fact that $v=0$ on the boundary. Then our variational formulation is of
the form \eqref{eq:timedependentweak1} where
$$\begin{align*}
m(\dot{u}, v) &= \int_\Omega \dot{u} v \dv \\
a(u, v) &= \int_\Omega (\BD\nabla u) \dtp \nabla v \dv
- \int_\Omega u\Bc \dtp \nabla v \dv
- \int_\Omega ruv \dv \\
b(v) &= \int_\Omega fv \dv
\end{align*}$$
From these forms, we obtain the following system matrices and vector
$$\begin{align*}
M^{I\!J} &= \int_\Omega N^J N^I \dv \\
A^{I\!J} &= \int_\Omega (\BD\BB^J) \dtp \BB^I \dv
- \int_\Omega N^J\Bc \dtp \BB^I \dv
- \int_\Omega r N^JN^I \dv \\
b^I &= \int_\Omega f N^I \dv
\end{align*}$$
where $\BM$ is constant through time.
==========
---
title: "Vectorial Finite Elements"
date: 2017-11-21
canonical: https://solmaz.io/2017/11/21/vectorial-finite-elements/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Many initial boundary value problems require solving for unknown vector
fields, such as solving for displacements in a mechanical problem.
Discretization of weak forms of such problems leads to higher-order linear
systems which need to be reshaped to be solved by regular linear solvers. There
are also more indices involved than a scalar problem, which can be confusing. In
this post, I'll try to elucidate the procedure by deriving for a basic
higher-order system and giving an example.
The weak formulation of a linear vectorial problem reads
> Find $\Bu\in V$ such that
>
> $$\begin{equation}
> a(\Bu, \Bv) = b(\Bv)
> \end{equation}$$
>
> for all $\Bv\in V$.
Discretizations of vectorial problems requires the expansion of vectorial quantities
as linear combinations of the basis vectors $\Be_i$:
$$\begin{equation}
\Bu = \suml{i=1}{\ndim} u_i \,\Be_i
\label{eq:discrete6}
\end{equation}$$
where $\cbr{u_i}_{i=1}^{\ndim}$ are the components corresponding to the
basis vectors and $\ndim=\dim V$. Here, we chose Cartesian basis vectors for simplicity.
We can therefore express its discretization as
$$\begin{equation}
\Bu_h = \suml{I=1}{\nnode} \Bu^I N^I
= \suml{I=1}{\nnode}\suml{i=1}{\ndim} u^I_i \Be_i N^I.
\label{eq:discrete7}
\end{equation}$$
Substituting discretized functions in the weak formulation, we obtain
$$\begin{equation}
\begin{aligned}
a(\Bu_h, \Bv_h) &= \suml{i=1}{\ndim}\suml{j=1}{\ndim} \,
a(u_{h,j}\,\Be_j, v_{h,i}\,\Be_i)\\
&= \suml{I=1}{\nnode}\suml{J=1}{\nnode}
\suml{i=1}{\ndim}\suml{j=1}{\ndim} u^J_j v^I_i \,a(\Be_j N^J, \Be_i N^I)
\end{aligned}
\end{equation}$$
and
$$\begin{equation}
b(\Bv_h) = \suml{i=1}{\ndim} b(v_{h,i}\,\Be_i)
= \suml{I=1}{\nnode} \suml{i=1}{\ndim} v^I_i b(\Be_i N^I).
\end{equation}$$
We define the following arrays
$$\begin{equation}
\boxed{
\begin{aligned}
A^{I\!J}_{ij} &= a(\Be_j N^J, \Be_i N^I) \\
b^{I}_{i} &= b(\Be_i N^I).
\end{aligned}
}
\end{equation}$$
Hence we can express the linear system
$$\begin{equation}
a(\Bu_h,\Bv_h) = b(\Bv_h)
\end{equation}$$
as
$$\begin{equation}
\suml{I=1}{\nnode}\suml{J=1}{\nnode}
\suml{i=1}{\ndim}\suml{j=1}{\ndim} u^J_j v^I_i \,A^{I\!J}_{ij}
=
\suml{I=1}{\nnode} \suml{i=1}{\ndim} v^I_i b^{I}_{i}.
\end{equation}$$
For arbitrary $\Bv_h$, this yields the following system of equations
$$\begin{equation}
\boxed{
\suml{J=1}{\nnode}
\suml{j=1}{\ndim} A^{I\!J}_{ij} \,u^J_j
= b^{I}_{i}
}
\label{eq:discrete8}
\end{equation}$$
for $i=1,\dots,\ndim$ and $I=1,\dots,\nnode$.
We reshape this higher-order system as shown in the previous post
[Reshaping Higher Order Linear Systems](/2017/11/20/reshaping-higher-order-systems/):
$$\begin{equation}
\BAhat \Buhat = \Bbhat
\end{equation}$$
by defining a map $i_d$ that maps original indices to the reshaped indices
$$\begin{equation}
i_d :=
\left\{
\begin{array}{rl}
[1,\nnode]\times[1,\ndim] & \to [1,\nnode\ndim]\\[1ex]
(I,i) & \mapsto \ndim(I-1)+i\\
\end{array}
\right.
\end{equation}$$
where we used 1-based indexing of the arrays.
We set
$$\begin{equation}
\boxed{
\begin{alignedat}{3}
\alpha &:= i_d(I,i) &&= \ndim(I-1) + i \\
\beta &:= i_d(J,j) &&= \ndim(J-1) + j \\
\end{alignedat}
}
\end{equation}$$
and write
$$\begin{equation}
\hat{A}_{\alpha\beta} = A^{I\!J}_{ij}
\quad,\quad
\hat{u}_{\beta} = u^{J}_{j}
\eqand
\hat{b}_{\alpha} = b^{I}_{i}
\end{equation}$$
The inverse index mapping can be obtained as shown in the previous post.
## Example: Linear Elasticity
Our initial-boundary value problem is
$$\begin{equation}
\begin{alignedat}{4}
-\div\Bsigma &= \rho\Bgamma \qquad&& \text{in} \qquad&& \Omega\\
\Bu &= \bar{\Bu} && \text{on} && \del\Omega_u \\
\Bt &= \bar{\Bt} && \text{on} && \del\Omega_t \\
\end{alignedat}
\end{equation}$$
The weak formulation reads
> Find $\Bu\in V$ such that
>
> $$\begin{equation}
> -\int_\Omega \div\Bsigma \dtp \Bv \dv = \int_\Omega \rho \Bgamma\dtp\Bv \dv
> \end{equation}$$
>
> for all $\Bv\in V$ where $V=H^1(\Omega)$.
We apply integration by parts on the left-hand side
$$\begin{equation}
\int_\Omega \div\Bsigma\dtp\Bv \dv
= \int_\Omega \div(\Bsigma\Bv) \dv - \int_\Omega \Bsigma : \nabla\Bv \dv
\end{equation}$$
and apply the divergence theorem to the first resulting term:
$$\begin{equation}
\int_\Omega \div(\Bsigma\Bv) \dv = \int_{\del\Omega_t} \bar{\Bt}\dtp\Bv \da
\end{equation}$$
Substituting the linear stress $\Bsigma=\IC:\Bvareps=\IC:\nabla\Bu$, we obtain
the following variational forms:
$$\begin{align}
\label{eq:linelastdiscretebilinear}
a(\Bu,\Bv) &= \int_\Omega \nabla\Bv:\IC:\nabla\Bu \dv \\
\label{eq:linelastdiscretelinear}
b(\Bv) &= \int_\Omega \rho \Bgamma\dtp\Bv \dv
+ \int_{\del\Omega_t} \bar{\Bt}\dtp\Bv \da
\end{align}$$
We have the following discretizations of the unknown function and test function
$$\begin{equation}
\Bu_h = \suml{J=1}{\nnode} \Bu^J N^J
\eqand
\Bv_h = \suml{I=1}{\nnode} \Bv^I N^I.
\end{equation}$$
With the given discretizations, the matrix corresponding to
\eqref{eq:linelastdiscretebilinear} can be calculated as
$$\begin{equation}
\begin{aligned}
A^{I\!J}_{ij} = a(\Be_j N^J, \Be_i N^I)
&= \int_\Omega \nabla(\Be_iN^I) : \IC : \nabla(\Be_jN^J) \dv \\
&= \int_\Omega (\Be_i\dyd \nabla N^I) : \IC : (\Be_j \dyd \nabla N^J) \dv \\
&= \int_\Omega \partd{N^I}{x_k} \, C_{ikjl} \, \partd{N^J}{x_l} \dv,
\end{aligned}
\end{equation}$$
and finally obtain
$$\begin{equation}
\boxed{
A^{I\!J}_{ij} = \int_\Omega B^I_k \, C_{ikjl} \, B^J_l \dv \,.
}
\end{equation}$$
The vector corresponding to \eqref{eq:linelastdiscretelinear} is calculated as
$$\begin{equation}
b^{I}_{i} = b(\Be_i N^I)
= \int_{\del\Omega_t} \bar{\Bt}\dtp(\Be_iN^I) \da
+ \int_\Omega\rho\Bgamma\dtp(\Be_iN^I) \dv
\end{equation}$$
which yields
$$\begin{equation}
\boxed{
b^{I}_{i}
= \int_{\del\Omega_t} \bar{t}_i N^I \da + \int_\Omega \rho \gamma_i N^I \dv
}
\end{equation}$$
==========
---
title: "Reshaping Higher Order Linear Systems"
date: 2017-11-20
canonical: https://solmaz.io/2017/11/20/reshaping-higher-order-systems/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In vectorial problems, we end up with linear systems of higher order, such as
$$\begin{equation}
\suml{k=1}{N}
\suml{l=1}{M} A_{ijkl} \, u_{kl}
= b_{ij}
\label{eq:1}
\end{equation}$$
for $i=1,\dots,N$ and $j=1,\dots,M$.
These systems cannot be solved readily with existing software. In order to be
able to solve them with existing software, we need to reshape them by
defining a **matrix of matrices**
$\BAhat$ and **vector of vectors** $\Buhat$ and $\Bbhat$:
$$\begin{equation}
\underbrace{
\left[
\begin{array}{ccc|c|ccc}
A_{1111}
& \cdots
& A_{111M}
&
& A_{11N1}
& \cdots
& A_{11NM}
\\
\vdots
& \ddots
& \vdots
& \cdots
& \vdots
& \ddots
& \vdots
\\
A_{1M11}
& \cdots
& A_{1M1M}
&
& A_{1MN1}
& \cdots
& A_{1MNM}
\\[1ex]
\hline
& \vdots
&
&\ddots
&
& \vdots
&
\\
\hline
&&&&&&
\\[-1.5ex]
A_{N111}
& \cdots
& A_{N11M}
&
& A_{N1N1}
& \cdots
& A_{N1NM}
\\
\vdots
& \ddots
& \vdots
& \cdots
& \vdots
& \ddots
& \vdots
\\
A_{NM11}
& \cdots
& A_{NM1M}
&
& A_{NMN1}
& \cdots
& A_{NMNM}
\end{array}
\right]
}_{\BAhat}
\underbrace{
\left[
\begin{array}{c}
u_{11}\\
\vdots \\
u_{1M} \\[1ex]
\hline \vdots\\
\hline \\[-1.5ex]
u_{N1} \\
\vdots \\
u_{NM}
\end{array}
\right]
}_{\Buhat}
=
\underbrace{
\left[
\begin{array}{c}
b_{11}\\
\vdots \\
b_{1M} \\[1ex]
\hline \vdots\\
\hline \\[-1.5ex]
b_{N1} \\
\vdots \\
b_{NM}
\end{array}
\right]}_{\Bbhat}
\end{equation}$$
This allows us to express the linear system as
$$\begin{equation}
\BAhat \Buhat = \Bbhat
\label{eq:3}
\end{equation}$$
Here, we **reshape** the system by defining a map $i_d$ that maps original
indices to the reshaped indices
$$\begin{equation}
i_d :=
\left\{
\begin{array}{rl}
[1,N]\times[1,M] & \to [1,NM]\\[1ex]
(i,j) & \mapsto M(i-1)+j\\
\end{array}
\right.
\end{equation}$$
where we used 1-based indexing of the arrays.
We set
$$\begin{equation}
\boxed{
\begin{alignedat}{3}
\alpha &:= i_d(i,j) &&= M(i-1) + j \\
\beta &:= i_d(k,l) &&= M(k-1) + l \\
\end{alignedat}
}
\end{equation}$$
and write
$$\begin{equation}
\hat{A}_{\alpha\beta} = A_{ijkl}
\quad,\quad
\hat{u}_{\beta} = u_{kl}
\eqand
\hat{b}_{\alpha} = b_{ij}
\end{equation}$$
For reference, the inverse of the index mapping reads
$$\begin{equation}
i_d^{-1} :=
\left\{
\begin{array}{rl}
[1,NM] & \to [1,N]\times[1,M] \\[1ex]
\alpha & \mapsto (1+(\alpha-\modop(\alpha,M))/M\;,\; \modop(\alpha,M))
\end{array}
\right.
\end{equation}$$
Thus, we have for our reshaped indices,
$$\begin{equation}
\begin{aligned}
j &= \modop(\alpha,M) \\
i &= 1+(\alpha-j)/M
\end{aligned}
\quad\eqand\quad
\begin{aligned}
l &= \modop(\beta,M) \\
k &= 1+(\beta-l)/M
\end{aligned}
\end{equation}$$
Expressed as a regular linear system \eqref{eq:3}, the higher-order system
\eqref{eq:1} can be solved with a linear solver such as
[LAPACK](https://en.wikipedia.org/wiki/LAPACK).
==========
---
title: "Linear Finite Elements"
date: 2017-11-14
canonical: https://solmaz.io/2017/11/14/linear-finite-elements/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Beginning with this post, I'll be publishing about the basics of finite element
formulations, from personal notes that accumulated over the years. This one is
about *linear* and *scalar* problems which came to be the "Hello World" for FE.
Details regarding spaces and discretization are omitted for the sake of brevity.
For those who want to delve into theory, I recommend ["The Finite Element Method:
Theory, Implementation, and Applications"](https://www.springer.com/gp/book/9783642332869)
by Larson and Bengzon.
The weak formulation of a canonical linear problem reads
> Find $u\in V$ such that
>
> $$\begin{equation}
> a(u, v) = b(v)
> \label{eq:femlinear1}
> \end{equation}$$
>
> for all $v \in V$ where $a(\cdot, \cdot)$ is a bilinear form and $b(\cdot)$ is a linear form.
We define the discretization of $u$ as
$$\begin{equation}
u_h := \suml{J=1}{\nnode} u^J N^J
,\quad
u_h \in V_h
\quad\text{where}\quad
V_h\subset V
\end{equation}$$
The discretization $u_h$ is a linear combination of **basis functions**
$N^J$ and corresponding scalars $u^J$, $J=1,\dots,\nnode$ so that $V_h$ is a
subset of $V$.
The discretization of \eqref{eq:femlinear1} then reads
$$\begin{equation}
a(u_h, v_h) = b(v_h)
\quad
\forall v_h \in V_h
.
\end{equation}$$
We then have
$$\begin{equation}
a\rbr{\suml{J=1}{\nnode} u^J N^J, \suml{I=1}{\nnode} v^I N^I}
= b\rbr{\suml{I=1}{\nnode} v^I N^I}
\end{equation}$$
Using the linearity properties,
$$\begin{equation}
a(\alpha u, \beta v) = \alpha\beta\, a(u,v)
\eqand
b(\alpha v) = \alpha b(v)
\end{equation}$$
we obtain
$$\begin{equation}
\suml{I=1}{\nnode} \suml{J=1}{\nnode}
u^J v^I a(N^J, N^I)
= \suml{I=1}{\nnode} v^I b(N^I)
.
\label{eq:femlinear2}
\end{equation}$$
For arbitrary test function values $v^I$, we can express \eqref{eq:femlinear2}
as a system of $\nnode$ equations
$$\begin{equation}
\suml{J=1}{\nnode}
u^J a(N^J, N^I) = b(N^I)
\label{eq:femlinear3}
\end{equation}$$
for $I = 1,2,\dots,\nnode$. If we expand the summations as
$$\begin{alignat*}{6}
& a(N^1, N^1) u^1 &&+ a(N^2, N^1) u^2 &&+ \cdots &&+ a(N^{\nnode}, N^1) u^{\nnode} &&\quad=\quad b(N^1) \\
& a(N^1, N^2) u^1 &&+ a(N^2, N^2) u^2 &&+ \cdots &&+ a(N^{\nnode}, N^2) u^{\nnode} &&\quad=\quad b(N^2) \\
& \qquad\vdots && \qquad\quad\;\vdots && \quad\;\;\vdots && \qquad\qquad\vdots && \qquad\qquad\vdots \\
& a(N^1, N^{\nnode}) u^1 &&+ a(N^2, N^{\nnode}) u^2 &&+ \cdots &&+ a(N^{\nnode}, N^{\nnode}) u^{\nnode} &&\quad=\quad b(N^{\nnode})
\end{alignat*}$$
we can see that the terms with $a$ constitute a matrix $\BA$ and
the terms with $b$ constitute a vector $\Bb$, allowing us to write
$$\begin{equation}
\BA\Bu = \Bb
\label{eq:discrete9}
\end{equation}$$
where we chose to express the unknown coefficients $u^I$ as a vector
$\Bu = [u^1,u^2,\dots,u^{\nnode}]\tra$.
\\It can be seen that the components of the $\BA$ and $\Bb$ are defined as
$$\begin{equation}
\boxed{
\Aelid{I\!J}{} = a(N^J,N^I)
\eqand
b^I = b(N^I),
}
\end{equation}$$
we can express the linear system as
$$\begin{alignat*}{6}
& \Aelid{11}{} u^1 &&+ \Aelid{12}{} u^2 &&+ \cdots &&+ \Aelid{1\nnode}{} u^{\nnode} &&\quad=\quad b^1 \\
& \Aelid{21}{} u^1 &&+ \Aelid{22}{} u^2 &&+ \cdots &&+ \Aelid{2\nnode}{} u^{\nnode} &&\quad=\quad b^2 \\
& \quad\vdots && \qquad\;\vdots && \quad\;\;\vdots && \qquad\;\vdots && \qquad\quad\;\;\vdots \\
& \Aelid{\nnode 1}{} u^1 &&+ \Aelid{\nnode 2}{} u^2 &&+ \cdots &&+ \Aelid{\nnode\nnode}{} u^{\nnode} &&\quad=\quad b^{\nnode}
\end{alignat*}$$
Note that with the given definitions, \eqref{eq:femlinear3} becomes
$$\begin{equation}
\boxed{
\suml{J=1}{\nnode}
\Aelid{I\!J}{} \,u^J = b^I
\quad\text{for}\quad
I=1,2,\dots\nnode.
}
\label{eq:discrete10}
\end{equation}$$
## Example: Poisson's Equation
In the weak form of Poisson's equation
$$\begin{equation}
\begin{alignedat}{4}
- \Var u &= f \quad && \text{in} \quad && \Omega \\
u &= 0 \quad && \text{on} \quad && \del\Omega
\end{alignedat}
\end{equation}$$
The weak formulation reads
> Find $u\in V$ such that
>
> $$\begin{equation}
> - \int_\Omega \Delta(u) v \dv= \int_\Omega f v \dv
> \end{equation}$$
>
> for all $v\in V$ where $V=H^1_0(\Omega)$.
Applying integration by parts and divergence theorem on the left-hand side
$$\begin{equation}
\begin{aligned}
\int_\Omega \Delta(u) v \dv
&= \int_\Omega \nabla \dtp (\nabla (u) v) \dv
- \int_\Omega \nabla u\dtp\nabla v \dv \\
&= \underbrace{\int_{\del\Omega} v (\nabla u\dtp\Bn) \da}_{v = 0
\text{ on } \del\Omega}
- \int_\Omega \nabla u\dtp\nabla v \dv \\
\end{aligned}
\end{equation}$$
We have the following variational forms:
$$\begin{equation}
\begin{aligned}
a(u,v) &= \int_{\Omega} \nabla u \dtp \nabla v \dv\\
b(v) &= \int_{\Omega} f \, v \dv\\
\end{aligned}
\end{equation}$$
Following \eqref{eq:femlinear3}, we can calculate the stiffness matrix
$\BA$ as
$$\begin{equation}
\begin{aligned}
\Aelid{I\!J}{} = a(N^J, N^I)
&= \int_{\Omega} \nabla N^J \dtp \nabla N^I \dv \\
&= \int_{\Omega} \BB^J \dtp \BB^I \dv
\end{aligned}
\end{equation}$$
where we have defined the gradient of the basis functions as
$$\begin{equation}
\BB^I := \nabla N^I\,.
\end{equation}$$
Similarly, we integrate the force term into a vector $\Bb$ as
$$\begin{equation}
\begin{aligned}
b^I &= \int_{\Omega} f N^I \dv
\end{aligned}
\end{equation}$$
==========
---
title: "Balance Laws"
date: 2017-10-12
canonical: https://solmaz.io/2017/10/12/balance-laws/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Calculus is all about relating the change in one quantity to another quantity.
$$ \Var A = B$$
Imagine it this way: You have a box full of marbles, and you decide to put some
more in.
$A$ is the variable representing the amount of marbles, while $B$ is the variable
representing the amount of marbles that you put in. If you had $A_1$ marbles at
the beginning, you have
$$A_2 = A_1+\Var A = A_1 + B$$
marbles following your action. This is the most fundamental algebraic pattern
that characterizes balance laws.
Take the [first law of thermodynamics](https://en.wikipedia.org/wiki/First_law_of_thermodynamics)
for example---a.k.a. balance of energy. We have
$$\Var U = Q + W$$
where $U$ is the internal energy of a closed system, $Q$ is the amount of heat
supplied to the system, and $W$ is the amount of work done on the system on its
surroundings. Here, $A\equiv U$ and $B\equiv Q+W$. Despite having three
quantities, it is the combined effect of two which is related to the remaining
quantity. Balance laws derived by physicists and chemists can get quite
complex and hard to understand.
It's always that **the change in one quantity
is related to the combined effect of remaining quantities**. Keeping
separate track of
your main variable $A$ and affecting variables that compose $B$ gives you a
mental model which helps you remember and even build your own balance laws.
# Introducing Time
Let $A: t \to A(t)$ be a function of time. We can rewrite the
equation in terms of the change in $A$ in a time period $\Var t$:
$$\frac{\Var A}{\Var t} = C$$
where the new variable $C$ represents the change in quantity in $\Var t$ amount
of time. In our previous analogy, $C$ is the amount of marbles put in, say,
a minute. As $\Var t \to 0$, we have
$$\deriv{A}{t} = C(t).$$
This prototypical balance law allows us to relate the *rates of change* of
quantities.
Let's introduce time into the balance of energy. The equation becomes
$$\deriv{U}{t} = P_T(t) + P_M(t)$$
where the new quantities $P_T$ and $P_M$ are called *thermal power*
and *mechanical power*, representing the thermal and mechanical work done on the
system per unit time, respectively. Given power functions and initial
conditions, integrating them would give us the evolution of the internal energy
through time.
# Introducing Space
Let's say we are not satisfied with an abstract box where the amount of stuff
that goes in is measured automatically. We want to write a balance law over
different shapes of bodies and we need to specify exactly where the stuff goes
in and out.
To do that, we need to rephrase our laws to work over a continuous domain. The
branch of physics that focuses on such problems is called continuum mechanics.
We introduce our spatial domain $\Omega$ and its boundary $\del\Omega$. Our
quantities now vary over both space and time, so we need to integrate them over
the whole domain in order to relate them:
$$\ddt\int_\Omega a \dx = \int_\Omega b \dx + \int_{\del\Omega} \Bc \dtp \Bn \ds$$
where
- $a(x,t)$ is the variable representing the main continuous quantity,
- $b(x,t)$ is the variable representing the rate of change of the quantity
**inside** the domain,
- and $\Bc(x,t)$ is the variable representing the negative rate of change of the
quantity **on the boundary** of the domain---negative due to surface normals
$\Bn$ having outward direction by definition.
Notice that when we introduce space, our prototypical balance law needs an
additional vectorial quantity, $\Bc$. In physical laws, one needs
to differentiate actions *inside* a body from actions *on the surface* of the
body. That's because one is over a volume and the other over an area, and they
have to be integrated separately.
The area integral is actually a flux where the vectorial quantity $\Bc$
is penetrating the surface with a given direction. Given that it's positive when
stuff exits the domain, it's called the **efflux** of the underlying quantity.
Similarly, we name the rate of change field $b$ as the **supply**
of the underlying quantity, because it being positive results in an
increase.
The idea is to get rid of the integrals by a process called "localization". In
order to localize, we have to convert the surface integral into a volume
integral using the divergence theorem:
$$\int_{\del\Omega} \Bc \dtp \Bn \ds = \int_\Omega \nabla\dtp\Bc \dx$$
Assuming $\Omega$ doesn't move, we can also write
$$\ddt\int_\Omega a \dx = \int_\Omega \deriv{a}{t} \dx$$
Collecting the results, we have
$$\int_\Omega \deriv{a}{t} \dx = \int_\Omega b \dx + \int_\Omega \nabla\dtp\Bc \dx$$
Notice that all integrals are over $\Omega$ now. This allows us to make the
balance law more strict by enforcing it point-wise:
$$\deriv{a}{t} = b + \nabla\dtp \Bc \quad \forall x \in \Omega$$
This is the localized version of the prototypical balance law that is used
everywhere in continuum mechanics.
Unfortunately, I can't give the energy balance example, because it would require
too many additional definitions. For that, I recommend the excellent
[Mathematical Foundations of Elasticity](http://store.doverpublications.com/0486678652.html)
by Marsden and Hughes.
# Conclusion
In physics and chemistry, one shouldn't blindly memorize formulas, but try to
see the underlying logic. In this case, I tried to elucidate balance laws,
which all build upon the same algebraic and geometrical concepts. I went from
discrete to continuous by introducing time and space to the equations, which
became more complex but retained the same idea: putting things in a box and
trying to calculate how that changes the contents.
==========
---
title: "Taylor and Volterra Series"
date: 2017-09-20
canonical: https://solmaz.io/2017/09/20/taylor-volterra-series/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
In the theory of computational mechanics, there are a few operations used that
are not taught in Calculus 101, which can be confusing without taking a lecture
in calculus of variations. One of them is taking *variations* (a.k.a. Gateaux
derivatives), akin to taking directional derivatives, but with functions of
functions called *functionals*.
You need to take variations when you are linearizing a nonlinear problem for the
purpose of solving with a numerical scheme. Linearization is the process of
expanding a function or functional into a series, and discarding terms that are
of order higher than linear---i.e. quadratic, cubic, quartic, etc. These
expansions are called Taylor for functions, and Volterra for functionals.
# Taylor Series
A function $f:\IR\to\IR$ can be expanded about a point $\bar{x}$ as a power series:
$$\begin{equation}
\begin{aligned}
f(x) &= f(\bar{x}) + \frac{\dif f}{\dif x}\evat_{\bar{x}} \frac{(x-\bar{x})}{1!}
+ \frac{\dif^2 f}{\dif x^2}\evat_{\bar{x}}\frac{(x-\bar{x})^2}{2!}
+ \frac{\dif^3 f}{\dif x^3}\evat_{\bar{x}}\frac{(x-\bar{x})^3}{3!}
+ \cdots \\
&= \suml{n=0}{\infty} \frac{\dif^n f}{\dif x^n} \evat_{\bar{x}}\frac{(x-\bar{x})^n}{n!}
\end{aligned}
\end{equation}$$
Letting $x$ be a perturbation $\var x$ from the expansion point
$\bar{x}$, that is $x\to\bar{x}+\var x$, the series can also be phrased as follows
$$\begin{equation}
\begin{aligned}
f(\bar{x}+\var x) &= f(\bar{x}) + \frac{\dif f}{\dif x}\evat_{\bar{x}}
\frac{\var x}{1!}
+ \frac{\dif^2 f}{\dif x^2}\evat_{\bar{x}}\frac{\var x^2}{2!}
+ \frac{\dif^3 f}{\dif x^3}\evat_{\bar{x}}\frac{\var x^3}{3!}
+ \cdots \\
&= \suml{n=0}{\infty} \frac{\dif^n f}{\dif x^n} \evat_{\bar{x}}\frac{\var x^n}{n!}
\end{aligned}
\label{eq:2}
\end{equation}$$
This is what is taught in Calculus 101 and everyone knows. Now for the part that
you may have missed:
# Variation
Let $X$ be the space of functions $\IR\to\IR$. The **variation**
of a functional $F\in X$ is defined as
$$\begin{equation}
\boxed{
\varn{F(u)}{u}{v}
:= \lim_{\eps\to 0} \frac{F(u+\eps v) - F(u)}{\eps}
\equiv \deriv{}{\eps} F(u + \eps v) \evat_{\eps = 0}
}
\end{equation}$$
where $v \in X$ is called the **perturbation** of the variation. This
operation is analogous to taking the directional derivative of a function.
## Shorthand notation
When working with variational formulations, writing out variations can be a
bit of a hassle if there are many symbols involved. Therefore we use the
following shorthand for variations:
$$\begin{equation}
\Var F := \varn{F(u)}{u}{v}
\end{equation}$$
Here, we assume that there is no chance of confusing the varied function or
perturbation. We use this shorthand in contexts where the perturbation does
not play an important role.
The shorthand for evaluation is
$$\begin{equation}
\bar{F} := F(\bar{u})
\eqand
\bar{\Var} F := \varn{F(u)}{u}{v}\evat_{\bar{u}}
\end{equation}$$
where there is no risk of confusion for $\bar{u}\in X$.
# Volterra Series
Let $X$ be the space of functions $\IR\to\IR$. Analogous to the Taylor series,
a functional $F\in X$ can be expanded about a point $\bar{u}$ as a power series:
$$\begin{equation}
\boxed{
\begin{aligned}
F(\bar{u}+v) &= F(\bar{u})
+ \frac{1}{1!} \varn{F(u)}{u}{v}\evat_{\bar{u}}
+ \frac{1}{2!} D^2_u F(u) \dtp v^2 \evat_{\bar{u}}
+ \frac{1}{3!} D^3_u F(u) \dtp v^3 \evat_{\bar{u}}
+ \cdots \\
&= \suml{n=0}{\infty} \frac{1}{n!} D^n_u F(u) \dtp v^n \evat_{\bar{u}}
\end{aligned}
}
\label{eq:6}
\end{equation}$$
where $v\in X$ is the perturbation of the expansion. This is called
the **Volterra series** expansion of $F$. Verbally, *the
Volterra series expansion of a functional about a function is the infinite sum of the
variations of the functional with increasing degree, evaluated at that function,
each divided by the factorial of the degree.*
In shorthand notation, the expansion is rendered
$$\begin{equation}
\boxed{
F = \bar{F}
+ \frac{\bar{\Var} F}{1!}
+ \frac{\bar{\Var}^2 F}{2!}
+ \frac{\bar{\Var}^3 F}{3!}
+ \cdots
}
\label{eq:7}
\end{equation}$$
To me, there is an elegance in \eqref{eq:7} that is not reflected in
\eqref{eq:2} or \eqref{eq:6}.
==========
---
title: "Isomorphisms in Linear Mappings between Vector Spaces"
date: 2017-07-22
canonical: https://solmaz.io/2017/07/22/isomorphisms-between-vector-spaces/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Equipping a vector space with an inner product
results in a natural isomorphism $\CV\to\CV^\ast$, where
the metric tensor can be interpreted as the linear mapping $\Bg:\CV\to\CV^\ast$
and its inverse $\Bg\inv:\CV^\ast\to\CV$.
**Notation:** Given two real vector spaces $\CV$ and $\CW$, we denote their inner products
as $$\dabrn{\cdot,\cdot}_{\CV}$$ and $$\dabrn{\cdot,\cdot}_{\CW}$$ respectively.
Given vectors $\Bv\in\CV$ and $\Bw\in\CW$, we define their lengths as
$$\begin{equation}
\Norm{\Bv}_\CV = \sqrt{\dabrn{\Bv,\Bv}_\CV}
\eqand
\Norm{\Bw}_\CW = \sqrt{\dabrn{\Bw,\Bw}_\CW}.
\end{equation}$$
Regarding $\CV$ and $\CW$,
1. their bases are denoted $\cbrn{\BE_A}$ and $\cbrn{\Be_a}$,
2. their dual bases are denoted $\cbrn{\BE^A}$ and $\cbrn{\Be^a}$,
3. their metrics are denoted $\BG$ and $\Bg$ with the components
$$G_{AB}=\dabrn{\BE_A,\BE_B}_\CV$$ and $$g_{ab}=\dabrn{\Be_a,\Be_b}_\CW$$,
respectively. Here, the indices pertaining to $\CV$ are uppercase
$(ABC\dots)$ and the indices pertaining to $\CW$ are lowercase
$(abc\dots)$.
**Definition:** Let $\BP:\CV\to\CW$ be a linear mapping. Then the **transpose**,
or **adjoint** of $\BP$, written $\BP\tra$, is the linear mapping
$$\begin{equation}
\boxed{
\BP\tra: \CW\to\CV
\quad\text{such that}\quad
\dabrn{\Bv,\BP\tra\Bw}_\CV = \dabrn{\BP\Bv,\Bw}_\CW
}
\end{equation}$$
for all $\Bv\in\CV$ and $\Bw\in\CW$. Carrying out the products,
$$\begin{equation}
G_{BA} v^B (P\tra){}^{A}{}_{d} w^d = g_{ab} P{}^{b}{}_{C}v^Cw^a.
\end{equation}$$
For arbitrary $\Bv$ and $\Bw$,
$$\begin{equation}
G_{BA} (P\tra){}^{A}{}_{a} = g_{ab} P{}^{b}{}_{A}
\end{equation}$$
from which we can obtain the components of the transpose as
$$\begin{equation}
\boxed{
(P\tra){}^{A}{}_{a} = g_{ab} P{}^{b}{}_{B} G^{AB}
\eqwith
\BP\tra = (P\tra){}^{A}{}_{a} \BE_A\dyd\Be^a
.
}
\end{equation}$$
If $\BB:\CV\to\CV$ is a linear mapping,
it is called **symmetric** if $\BB=\BB\tra$.
**Definition:** Let $\BP:\CV\to\CW$ be a linear mapping. Then the **dual** of $\BP$
is a metric independent mapping
$$\begin{equation}
\boxed{
\BP^\ast: \CW^\ast\to\CV^\ast
\quad\text{such that}\quad
\abrn{\Bv,\BP^\ast\Bbeta}_\CV = \abrn{\BP\Bv,\Bbeta}_\CW
}
\end{equation}$$
defined through natural pairings for all
$\Bv\in\CV$ and $\Bbeta\in\CW^\ast$.
Carrying out the products,
$$\begin{equation}
v^A (P^\ast){}_{A}{}^{a} \beta_a
= P{}^{b}{}_{B} v^B \beta_b.
\end{equation}$$
For arbitrary $\Bv$ and $\Bbeta$, we obtain the components of the dual mapping as
$$\begin{equation}
\boxed{
(P^\ast){}_{A}{}^{a}
= P{}^{a}{}_{A}
\eqwith
\BP^\ast = (P^\ast){}_{A}{}^{a} \BE^A\dyd\Be_a
= P{}^{a}{}_{A} \BE^A\dyd\Be_a
.
}
\end{equation}$$
To fully appreciate the symmetry that originates from the duality, we can think
of not just the mappings between $\CV$ and $\CW$, but also between their dual
spaces.
To this end we can enumerate four mappings corresponding to
$\cbr{\CV,\CV^\ast}\to\cbr{\CW,\CW^\ast}$
and their duals, corresponding to
$\cbr{\CW,\CW^\ast}\to\cbr{\CV,\CV^\ast}$. Their definitions can be found in
the table below.
Tensors $\BP$, $\BQ$, $\BR$ and $\BS$ as linear mappings (top),
and their duals
$\BP^\ast$, $\BQ^\ast$, $\BR^\ast$ and $\BS^\ast$ (bottom).
In the respective tables, the first row displays the tensor spaces, basis
vectors and components of the subsequent mappings,
and the second and third row display the representations of
the tensor as linear and bilinear mappings respectively.
The results of the mappings are given in the mapping, matrix
and index representations respectively.
The mappings are over vectors $\Bv\in\CV$, $\Bw\in\CW$ and one-forms
$\Balpha\in\CV^\ast$, $\Bbeta\in\CW^\ast$.
The commutative diagrams pertaining to these mappings
can be found in the figure below
Commutative diagrams involving
the linear mappings $\BP,\BQ,\BR,\BS$ and
their dual $\BP^\ast,\BQ^\ast,\BR^\ast,\BS^\ast$
based on the metrics $\BG$ and $\Bg$
of $\CV$ and $\CW$.
==========
---
title: "Metrics and Natural Isomorphisms"
date: 2017-07-13
canonical: https://solmaz.io/2017/07/13/metrics-natural-isomorphisms/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The assignment of an inner product to
a non-degenerate and finite-dimensional vector space $\CV$,
results in emergence of the **natural isomorphism** to its dual
$\CV\to\CV^\ast$, which means that the morphisms
$\CV\to\CV^\ast$ and $\CV^\ast\to\CV$ are of *the same structure* and one
is the *inverse* of the other.
The notion of naturality (of an isomorphism) becomes most clear in the context of
category theory;
however it should be
sufficient for now to say that a natural isomorphism
between a vector space an its dual is one that is
**basis-independent**. As the origin of the isomorphism, the inner product is
encapsulated in an object called the metric, defined below,
in order to make the resulting symmetry of the mappings more obvious.
In the context of differential geometry, the **metric** object
is used synonymously with the inner product of a vector space. More specifically,
the **metric tensor**
$$\begin{equation}
\Bg:=
\left\{
\begin{aligned}
\CV \times \CV &\to \IR \\
(\Bv,\Bw) &\mapsto \dabrn{\Bv, \Bw}
\end{aligned}
\right.
\end{equation}$$
of a real vector space $\CV$ is an object whose components contain the
information necessary to linearly transform a vector to its covector. This
operation is denoted by the symbol $\flat$ and reads
$$\begin{equation}
\flat :=
\left\{
\begin{aligned}
(\CV^\ast \to \IR) &\to (\CV \to \IR) \\
\text{or}\quad \CV &\to\CV^\ast \\
\Bv(\cdot) &\mapsto \Bg(\Bv, \cdot).
\end{aligned}
\right.
\end{equation}$$
We simply define the one-form $\Bv^\flat$ as
$$\begin{equation}
\Bv^\flat(\Bw) \equiv \Bg(\Bv,\Bw) = \dabrn{\Bv,\Bw}.
\end{equation}$$
We input the basis vectors $\Be_a$
$$\begin{equation}
\Bv^\flat(\Be_a) = \dabrn{v^b\Be_b, \Be_a}
= \dabrn{\Be_b, \Be_a} v^b
= \dabrn{\Be_a, \Be_b} v^b
\end{equation}$$
and define the components of the metric tensor as
$$\begin{equation}
\boxed{
g_{ab} = \dabrn{\Be_a, \Be_b}
\eqwith
\Bg = g_{ab}\, \Be^a\dyd \Be^b.
}
\end{equation}$$
We then simply say that the operator $\flat$ denotes an
**index lowering**[^1] through
$$\begin{equation}
\Bv^\flat = \Bg\Bv
\quad\text{and component-wise }\quad
v_a = g_{ab} v^b.
\end{equation}$$
Moreover, we can define the inverse of the metric tensor as
$$\begin{equation}
\Bg\inv:=
\left\{
\begin{aligned}
\CV^\ast\times\CV^\ast &\to \IR \\
(\Balpha,\Bbeta) &\mapsto \dabrn{\Balpha, \Bbeta}
\end{aligned}
\right.
\end{equation}$$
The operation of transforming a covector to its corresponding vector is
denoted by the symbol $\sharp$ and reads
$$\begin{equation}
\sharp :=
\left\{
\begin{aligned}
(\CV \to \IR) &\to (\CV^\ast \to \IR) \\
\text{or}\quad \CV^\ast &\to\CV \\
\Balpha(\cdot) &\mapsto \Bg\inv(\cdot,\Balpha).
\end{aligned}
\right.
\end{equation}$$
Here, the vector corresponding to the covector $\Balpha$ is denoted
$\Balpha^\sharp$ and reads
$$\begin{equation}
\Balpha^\sharp(\Bbeta) = \Bg\inv(\Bbeta,\Balpha) = \dabrn{\Bbeta, \Balpha}
\end{equation}$$
We input the dual basis vectors $\Be^a$
$$\begin{equation}
\Balpha^\sharp(\Be^a) = \dabrn{\Be^a, \alpha_b\Be^b}
= \dabrn{\Be^a, \Be^b} \alpha_b
\end{equation}$$
and define the components of the inverse metric $\Bg\inv$ as
$$\begin{equation}
\boxed{
g^{ab} = \dabrn{\Be^a,\Be^b} \eqwith \Bg\inv = g^{ab}\,\Be_a\dyd\Be_b.
}
\end{equation}$$
Then the operator $\sharp$ denotes an **index raising** through
$$\begin{equation}
\Balpha^\sharp = \Bg\inv\Balpha
\quad\text{and component-wise }\quad
\alpha^a = g^{ab}\alpha_b.
\end{equation}$$
In some literature, the natural isomorphism $\CV\to\CV^\ast$
is called the **musical isomorphism**---which is also the origin of the
notation introduced above---because the process of transforming a
vector to its dual space and a covector to the original space is analogous to
lowering and raising notes.
With the given definition of the metric, we can elaborate on
the advantage of denoting inner products of different objects with different
symbols. Whereas $\abrn{\cdot,\cdot}$ always denotes a natural pairing between a
vector space and its dual, one can write $$\dabrn{\cdot,\cdot}_\CV:\CV\times\CV\to\IR$$
to denote an inner product of vectors
and $\dabrn{\cdot,\cdot}_{\CV^\ast}:\CV^\ast\times\CV^\ast\to\IR$ to denote an
inner product of covectors. Using the metric, we can link these notations as
$$\begin{equation}
\begin{alignedat}{5}
&\dabrn{\Bv,\Bw}_\CV
&&= \abrn{\Bv, \Bw^\flat}
&&= \abrn{\Bv^\flat, \Bw}
&&= g_{ab} v^a w^b\\
&\dabrn{\Balpha,\Bbeta}_{\CV^\ast}
&&= \abrn{\Balpha, \Bbeta^\sharp}
&&= \abrn{\Balpha^\sharp, \Bbeta}
&&= g^{ab}\alpha_a\beta_b\\
\end{alignedat}
\end{equation}$$
for all $\Bv,\Bw\in\CV$ and $\Balpha,\Bbeta\in\CV^\ast$. Similarly,
$$\begin{equation}
\begin{alignedat}{4}
&\abrn{\Bv, \Balpha}
&&= \dabrn{\Bv^\flat, \Balpha}_{\CV^\ast}
&&= \dabrn{\Bv, \Balpha^\sharp}_{\CV}.
\end{alignedat}
\end{equation}$$
Despite the symmetricity of the inner product, we choose
to think of the first operand as a vector and the second as a covector
in a natural pairing, as a convention.
The metric tensor has the following properties:
- For orthonormal bases, the metric tensor equals the identity tensor, that is,
$g_{ij}=\delta_{ij}$.
- The diagonal terms equal to the square of the lengths of the basis
vectors, that is, $g_{ii}=\Norm{\Be_i}^2$ (no summation).
- The off-diagonal terms are zero if the basis vectors are orthogonal.
Specifically, $g_{ij}=0$ iff $\Be_i$ and $\Be_j$ are orthogonal.
[^1]: In musical notation, the flat symbol
$\flat$ is used to lower a note by one semitone, whereas the sharp symbol
$\sharp$ is used to raise a note by one semitone.
It is recommended to pronounce $\Bv^\flat$ as *v-flat*
and $\Balpha^\sharp$ *alpha-sharp*.
==========
---
title: "Duality of Vector Spaces"
date: 2017-07-06
canonical: https://solmaz.io/2017/07/06/duality-vector-spaces/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
When I was learning about Continuum Mechanics for the first time, the *covariance
and contravariance of vectors* confused the hell out of me. The concepts gain
meaning in the context of Riemannian Geometry, but it was surprising to find
that one doesn't need to learn an entire subject to grasp the logic behind
co-/contravariance. An intermediate knowledge of linear algebra is enough---that
is, one has to be acquainted with the concept of vector spaces and one-forms.
The duality of co-/contravariance arises when one has to define vectors in terms
of a non-orthonormal basis. The reason such terminology doesn't show up
in engineering education is that Cartesian coordinates are enough for most
engineering problems. But every now and then, a complex problem with funky
geometrical requirements show up, like one that requires measuring distances and
areas on non-flat surfaces. Then you end up with dual vector spaces. I'll try to
give the basics of duality below.
**Definition:** Let $\CV$ be a finite-dimensional real vector space.
The space $\CV^\ast = \CL(\CV,\IR)$,
defined as the
the space of all one-forms $\Balpha:\CV\to\IR$, is called the
**dual space** to $\CV$.
Let $B=\cbr{\Be_1,\dots,\Be_n}$ be a basis of $\CV$. Any vector $\Bv\in\CV$ can be written
in terms of $B$ as
$$\begin{equation}
\Bv = a_1 \Be_1 + \cdots + a_n\Be_n
\label{eq:vectorrep1}
\end{equation}$$
with the components $a_1,\dots,a_n\in\IR$.
For any $i=1,\dots,n$, we can define the $i$-th component $a_i$ by a one-form as
$$\begin{equation}
\Be^i :=
\left\{
\begin{aligned}
\CV &\to \IR \\
\Bv &\mapsto \Be^i(\Bv) = a_i
\end{aligned}\right.
\end{equation}$$
These elements are linear and thus are in the space
$\CL(\CV,\IR)$[^1].
Given any basis $B=\setveci{\Be}$, we call $B^\ast = \setveciup{\Be}$
the basis of $\CV^\ast$ **dual** to $B$.
The fact that $B^\ast$ really is a basis of $\CV^\ast$ can be proved
by showing that $\Be^i$ are linearly independent.
Then $\Bv$ has the following
representation
$$\begin{equation}
\Bv = \Be^1(\Bv)\, \Be_1 + \cdots + \Be^n(\Bv)\, \Be_n.
\label{eq:vectorrep2}
\end{equation}$$
Instead of $a_i$, it is practical to denote the components of $\Bv$ as $v^i$,
lightface of the same symbol with a raised index corresponding to
the raised index of the dual basis:
$$\begin{equation}
\Bv = v^1 \Be_1 + \cdots + v^n \Be_n
\eqwith
v^i = \Be^i(\Bv).
\end{equation}$$
In fact, this convention is more compatible with
the symmetry caused by the duality.
This point will be more clear after the introduction of
dual basis representation of one-forms.
**Proposition:** Each $\Be^i \in \CL(\CV,\IR)$ can be identified by its action on the basis
$B$:
$$\begin{equation}
\Be^i(\Be_j) =
\begin{cases}
1 & \text{if } i=j \\
0 & \text{otherwise}.
\end{cases}
\label{eq:dualbasis2}
\end{equation}$$
**Proof:** For any $\Bv\in\CV$, $\Be^i(\Bv)$ must give $v^i$, the
$i$-th component of $\Bv$.
Setting $\Bv = \Be_j$, one sees that
$\Be^i(\Bv)=v^i = 1$ when $i=j$, and is zero otherwise.
Geometrically, \eqref{eq:dualbasis2} implies that a basis vector is
perpendicular to all the dual basis vectors, except its own dual.
## Dual Basis Representation of One-Forms
Let $\Balpha$ be a one form in $\CV^\ast$ with the corresponding
dual basis $\setveciup{\Be}$. Then similar to a vector,
$\Balpha$ has the following representation
$$\begin{equation}
\begin{aligned}
\Balpha(\cdot)
&= \Balpha(\Be_1)\,\Be^1(\cdot)
+ \dots
+ \Balpha(\Be_n)\,\Be^n(\cdot) \\
&= \alpha_1 \Be^1(\cdot)
+ \dots
+ \alpha_n \Be^n(\cdot)
\end{aligned}
\end{equation}$$
where the **components of the one-form** $\Balpha$
are defined as
$$\begin{equation}
\alpha_i = \Balpha(\Be_i).
\end{equation}$$
**Proof:** We substitute \eqref{eq:vectorrep2} and obtain
$$\begin{equation}
\begin{aligned}
\Balpha(\Bv) &= \Balpha\rbr{\suml{i=1}{n} \Be^i(\Bv)\, \Be_i}
= \suml{i=1}{n} \Balpha(\Be_i)\, \Be^i(\Bv) \\
\end{aligned}
\end{equation}$$
using $\Balpha$'s linearity.
**Notation:**
Let $\CV$ be a finite-dimensional real vector space.
For $\Bv\in\CV$ and $\Balpha\in\CV^\ast$
$$\begin{equation}
\abrn{\cdot,\cdot} :=
\left\{\begin{aligned}
\CV\times\CV^\ast &\to \IR \\
(\Bv, \Balpha) &\mapsto \Balpha(\Bv)
\end{aligned}\right.
\end{equation}$$
denotes the action of $\Balpha$ on $\Bv$, and is called
a **natural pairing** or **dual pairing**
between a vector space and its dual.
*It is of the essence to understand that $\abrn{\cdot,\cdot}$ does not
denote an inner product in $\CV$*; that is,
$\abr{\Bv,\Balpha}$ means $\Balpha(\Bv)$.
With this notation, \eqref{eq:vectorrep2} can be written as
$$\begin{equation}
\Bv = \abrn{\Bv,\Be^1}\, \Be_1
+ \cdots
+ \abrn{\Bv,\Be^n}\, \Be_n.
\end{equation}$$
and \eqref{eq:dualbasis2} as
$$\begin{equation}
\abrn{\Be_i, \Be^j} = \delta_{ij}.
\label{eq:dualbasis1}
\end{equation}$$
Using the convention that $\Be_i$ are column vectors and
$\Be^i$ are row vectors,
\eqref{eq:dualbasis1} can be rearranged in the following manner
$$\begin{equation}
\left[
\begin{array}{@{} c|c|c|c @{}}
\Be_1&\Be_2&\cdots&\Be_n
\end{array}
\right]\inv
=
\left[
\begin{array}{@{} c @{}}
\Be^1 \\ \hline \Be^2 \\ \hline \vdots \\ \hline \Be^n
\end{array}
\right]
\label{eq:computedualbasis1}
\end{equation}$$
which can be used to compute a dual basis.
**Example:** Given a two-dimensional vector space $\CV$ with a basis
$\Be_1=[2,-0.5]\tra$, $\Be_2=[1,1]\tra$, we use
\eqref{eq:computedualbasis1} to compute
$$\begin{equation}
\begin{bmatrix}
2 & 1 \\
-0.5 & 1
\end{bmatrix}\inv
=
\begin{bmatrix}
0.4 & -0.4 \\
0.2 & 0.8
\end{bmatrix}
\end{equation}$$
and obtain the dual basis vectors as
$\Be^1=[0.4,-0.4]$ and $\Be^2=[0.2,0.8]$.
The result is given in the
following figure,
where one can see that $\Be_1\perp\Be^2$, $\Be^1\perp\Be_2$.
A body $\CB$ embedded in $\IR^2$ with curvilinear coordinates.
Every point $\CP$ at $\BX$ has an associated two-dimensional vector space,
called $\CB$'s tangent space at $\BX$, denoted $\tang_\BX\CB$. The basis
$\Be_i$ corresponding to coordinates $\theta_i$ are not necessarily
orthogonal and can admit corresponding duals $\Be^i$, due to
curvilinearity.
The coordinates appear to be affine at the point's immediate vicinity,
and thus in the tangent space.
The introduction of the dual space
allows us to reinterpret a one-form $\Balpha$
as an object residing in the dual space. In fact,
the **canonical duality** $\CV^{\ast\ast}=\CV$
states that every vector $\Bv$ can be interpreted as a functional
on the space $\CV^\ast$ via
$$\begin{equation}
\Bv:=
\left\{
\begin{aligned}
\CV^\ast &\to \IR \\
\Balpha &\mapsto \Bv(\Balpha) \text{ or } \abrn{\Bv, \Balpha}
\end{aligned}\right.
\end{equation}$$
[^1]: Despite being denoted with bold letters, one-forms should not be confused with vectors.
==========
---
title: "Solving Constrained Linear Systems"
date: 2016-04-20
canonical: https://solmaz.io/2016/04/20/constrained-linear-systems/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Constrained linear systems arise when Dirichlet boundary conditions are imposed
on a variational formulation
> Find $u\in U$ such that
>
> $$\begin{equation}
> a(u, v) = b(v)
> \end{equation}$$
>
> for all $v \in V$, where
>
> $$\begin{equation}
> \begin{aligned}
> U &= \{u\mid u\in H^1(\Omega), u=\bar{u} \text{ on } \del\Omega_u\} \\
> V &= \{u\mid u\in H^1(\Omega), u=0 \text{ on } \del\Omega_u\} \\
> \end{aligned}
> \end{equation}$$
>
> where $\bar{u}$ is the Dirichlet condition.
We additively decompose the solution into known and unknown parts:
$$\begin{equation}
u = \bar{u} + w
\end{equation}$$
and substitute into our variational formulation
$$\begin{equation}
a(\bar{u}+w, v) = b(v)
\end{equation}$$
We can take advantage of the linearity condition, and reformulate the
variational formulation:
> Find $w\in V$ such that
>
> $$\begin{equation}
> a(w, v) = b(v) - a(\bar{u}, v)
> \end{equation}$$
>
> for all $v \in V$.
The algorithmic analogue of this formulation will be developed in the following
section Direct Modification Approach.
# Static Condensation Approach
For a linear system
$$\begin{equation}
\BA \Bu = \Bb\,,
\label{eq:system1}
\end{equation}$$
of size $N\times N$, we constrain the values of the solution or right-hand side
at certain degrees of freedom.
We sort the system so that these degrees of freedom are grouped together after the
unconstrained degrees of freedom. The resulting system is,
$$\begin{equation}
\label{eq:bcsystem1}
\left[
\begin{array}{ccc|ccc}
A_{1,1} & \cdots & A_{1,M} & A_{1,M+1} & \cdots & A_{1,N} \\
\vdots & \ddots & \vdots & \vdots & \ddots & \vdots \\
A_{M,1} & \cdots & A_{M,M} & A_{M,M+1} & \cdots & A_{M,N} \\ \hline
A_{M+1,1} & \cdots & A_{M+1,M} & A_{M+1,M+1} & \cdots & A_{M+1,N} \\
\vdots & \ddots & \vdots & \vdots & \ddots & \vdots\\
A_{N,1} & \cdots & A_{N,M} & A_{N, M+1} &\cdots & A_{N,N} \\
\end{array}
\right]
\left[
\begin{array}{c}
u_{1} \\
\vdots \\
u_{M} \\ \hline
u_{M+1} \\
\vdots \\
u_{N} \\
\end{array}
\right]
=
\left[
\begin{array}{c}
b_{1} \\
\vdots \\
b_{M} \\ \hline
b_{M+1} \\
\vdots \\
b_{N} \\
\end{array}
\right]\,,
\end{equation}$$
Defining submatrices
and vectors for the partitions, we can write
$$\begin{equation}
\begin{bmatrix}
\BA_{11}& \BA_{12} \\
\BA_{21}& \BA_{22} \\
\end{bmatrix}
\begin{bmatrix}
\Bu_{1} \\
\Bu_{2} \\
\end{bmatrix}
=
\begin{bmatrix}
\Bb_{1} \\
\Bb_{2} \\
\end{bmatrix}
\end{equation}$$
or
$$\begin{equation}
\begin{aligned}
\BA_{11} \Bu_{1} + \BA_{12} \Bu_{2} &= \Bb_{1} \\
\BA_{21} \Bu_{1} + \BA_{22} \Bu_{2} &= \Bb_{2}\,,
\end{aligned}
\end{equation}$$
Let $\Bu_2 = \bar{\Bu}$ and $\Bb_1 = \bar{\Bb}$ have defined values. The objective
is to solve for unknown $\Bu_1$ and $\Bb_2$. We have
$$\begin{equation}
\Bu_1 = \BA_{11}\inv (\Bb_1 - \BA_{12}\Bu_2)
\label{eq:u1staticcond1}
\end{equation}$$
and
\begin{align}
\Bb_2 = (\BA_{22}-\BA_{21}\BA_{11}\inv\BA_{12})\Bu_2 + \BA_{21}\BA_{11}\inv\Bb_1
\end{align}
In case $\bar{\Bu} = \Bzero$, we have
$$\begin{equation}
\begin{aligned}
\Bu_1 &= \BA_{11}\inv\Bb_1 \\
\Bb_2 &= \BA_{21}\BA_{11}\inv\Bb_1
\end{aligned}
\end{equation}$$
and in case $\bar{\Bb} = \Bzero$, we have
$$\begin{equation}
\begin{aligned}
\Bu_1 &= -\BA_{11}\inv\BA_{12}\Bu_2 \\
\Bb_2 &= (\BA_{22}-\BA_{21}\BA_{11}\inv\BA_{12})\Bu_2
\end{aligned}
\end{equation}$$
## Example: Plane Stress and Strain in Linear Elasticity
The constitutive equation of isotropic linear elasticity reads
$$\begin{equation}
\begin{bmatrix}
\lambda+2\mu & \lambda & \lambda & 0 & 0 & 0 \\
\lambda & \lambda+2\mu & \lambda & 0 & 0 & 0 \\
\lambda & \lambda & \lambda+2\mu & 0 & 0 & 0 \\
0 & 0 & 0 & \mu & 0 & 0 \\
0 & 0 & 0 & 0 & \mu & 0 \\
0 & 0 & 0 & 0 & 0 & \mu \\
\end{bmatrix}
\begin{bmatrix}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{33}\\
\varepsilon_{12}\\
\varepsilon_{23}\\
\varepsilon_{13}\\
\end{bmatrix}
=
\begin{bmatrix}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{33}\\
\sigma_{12}\\
\sigma_{23}\\
\sigma_{13}\\
\end{bmatrix}
\end{equation}$$
The plane stress condition reads $\sigma_{13} = \sigma_{23}= \sigma_{33} = 0$. We
group the constrained degrees of freedom together:
$$\begin{equation}
\left[
\begin{array}{ccc|ccc}
\lambda+2\mu & \lambda & 0 & \lambda & 0 & 0 \\
\lambda & \lambda+2\mu & 0 & \lambda & 0 & 0 \\
0 & 0 & \mu & 0 & 0 & 0 \\
\hline
\lambda & \lambda & 0 & \lambda+2\mu & 0 & 0 \\
0 & 0 & 0 & 0 & \mu & 0 \\
0 & 0 & 0 & 0 & 0 & \mu \\
\end{array}
\right]
\left[
\begin{array}{c}
\varepsilon_{11}\\
\varepsilon_{22}\\
\varepsilon_{12}\\
\hline
\varepsilon_{33}\\
\varepsilon_{23}\\
\varepsilon_{13}\\
\end{array}
\right]
=
\left[
\begin{array}{c}
\sigma_{11}\\
\sigma_{22}\\
\sigma_{12}\\
\hline
\sigma_{33}\\
\sigma_{23}\\
\sigma_{13}\\
\end{array}
\right]
\end{equation}$$
which we write as
$$\begin{equation}
\begin{bmatrix}
\BC_{11}&\BC_{12}\\
\BC_{21}&\BC_{22}\\
\end{bmatrix}
\begin{bmatrix}
\Bvarepsilon\\
\Bvarepsilon'\\
\end{bmatrix}
=
\begin{bmatrix}
\Bsigma\\
\Bsigma'\\
\end{bmatrix}
\end{equation}$$
The purpose is to
obtain a reduced system without $\Bsigma'$ or $\Bvarepsilon'$.
We substitute the plane stress condition $\Bsigma'=\Bzero$, to obtain
$\Bvarepsilon'=-\BC_{22}\inv\BC_{21}\Bvarepsilon$. Then we have
$$\begin{equation}
(\BC_{11}-\BC_{12}\BC_{22}\inv\BC_{21}) \Bvarepsilon = \Bsigma
\end{equation}$$
We define the plane stress version of the elasticity tensor as
$\BC_\sigma = \BC_{11}-\BC_{12}\BC_{22}\inv\BC_{21}$ which results in
$$\begin{equation}
\BC_\sigma =
\frac{\mu}{\lambda+2\mu}
\begin{bmatrix}
4(\lambda+\mu) &
2\lambda & 0 \\
2\lambda &
4(\lambda+\mu) & 0 \\
0 & 0 & \lambda+2\mu
\end{bmatrix}
=
\frac{E}{1-\nu^2}
\begin{bmatrix}
1 & \nu & 0\\
\nu & 1 & 0\\
0& 0& (1-\nu)/2
\end{bmatrix}
\end{equation}$$
The plane strain condition reads $\Bvarepsilon'=\Bzero$. This simply results in
$$\begin{equation}
\BC_{11}\Bvarepsilon = \Bsigma
\end{equation}$$
The plane strain version of the elasticity tensor $\BC_\varepsilon=\BC_{11}$
is calculated as
$$\begin{equation}
\BC_\varepsilon =
\begin{bmatrix}
\lambda + 2\mu & \lambda & 0 \\
\lambda & \lambda + 2\mu & 0 \\
0 & 0 & \mu \\
\end{bmatrix}
=
\frac{E}{(1+\nu)(1-2\nu)}
\begin{bmatrix}
1-\nu & \nu & 0\\
\nu & 1-\nu & 0\\
0& 0& (1-2\nu)/2
\end{bmatrix}
\end{equation}$$
The procedure defined above is called *static condensation*,
named after its application in structural analysis. One impracticality of
this formulation is that systems do not always exist with their constrained
degrees of freedom grouped together. These are generally
scattered arbitrarily throughout the solution vector, and grouping them manually
is impractical with current data structure implementations.
# Direct Modification Approach
Suppose we have a system where $\Bu_2$ and $\Bb_1$ are known and $\Bu_1$
and $\Bb_2$ are unknown:
$$\begin{equation}
\begin{bmatrix}
\BA_{11}&\BA_{12}\\
\BA_{21}&\BA_{22}\\
\end{bmatrix}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
=
\begin{bmatrix}
\Bb_1\\
\Bb_2\\
\end{bmatrix}
\end{equation}$$
We can modify the system so that
it can be solved without separating the partitions
$$\begin{equation}
\begin{bmatrix}
\BA_{11}&\BA_{12}\\
\Bzero &\BI\\
\end{bmatrix}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
=
\begin{bmatrix}
\Bb_1\\
\Bu_2\\
\end{bmatrix}
\end{equation}$$
We can additively decompose both sides
$$\begin{equation}
\begin{bmatrix}
\BA_{11}&\Bzero\\
\Bzero &\BI\\
\end{bmatrix}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
+
\begin{bmatrix}
\Bzero&\BA_{12}\\
\Bzero &\Bzero\\
\end{bmatrix}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
=
\begin{bmatrix}
\Bb_1\\
\Bu_2\\
\end{bmatrix}
\end{equation}$$
Therefore, the following is equivalent to
\eqref{eq:u1staticcond1}:
$$\begin{equation}
\underbrace{
\begin{bmatrix}
\BA_{11}&\Bzero\\
\Bzero &\BI\\
\end{bmatrix}
}_{\tilde{\BA}}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
=
\underbrace{
\begin{bmatrix}
\Bb_1 - \BA_{12}\Bu_2\\
\Bu_2\\
\end{bmatrix}
}_{\tilde{\Bb}}
\end{equation}$$
This is solved for $\Bu$:
$$\begin{equation}
\Bu = \tilde{\BA}\inv \tilde{\Bb}\,.
\end{equation}$$
The unknown right hand side can be obtained from the original matrix $\BA$
$$\begin{equation}
\Bb = \BA\Bu = \BA \tilde{\BA}\inv \tilde{\Bb}\,,
\end{equation}$$
Observe that the modifications on $\BA$ are symmetric, so we do not need
the constrained degrees of freedom be grouped together. $\tilde{\BA}$ is
obtained by zeroing out the rows and columns corresponding to constraints and
setting the diagonal components to one. For $\tilde{\Bb}$, we do not need to
extract $\BA_{12}$; we simply let
$$\begin{equation}
\quad \tilde{\Bb}
\leftarrow
\Bb_k - \BA\Bu_k
\end{equation}$$
where
$$\begin{equation}
\Bu_k =
\begin{bmatrix}
\Bzero\\
\Bu_2\\
\end{bmatrix}
\eqand
\Bb_k =
\begin{bmatrix}
\Bb_1\\
\Bzero\\
\end{bmatrix}
\end{equation}$$
We then equate the constrained degrees of freedom to their specified values $\Bu_2$.
Below is a pseudocode outlining the algorithm.
```
fun solve_constrained_system(A, b_known, u_known, is_contrained):
# A: unmodified matrix, size NxN
# b_known: known values of the rhs, size N
# u_known: known values of the solution, size N
# is_constrained: bool array whether dof is constrained, size N
N = length(b)
A_mod = copy(A)
b_mod = b_known - A_known*u_known # Calculate rhs vector
for i=1 to N do:
if is_constained[i] then:
for j = 1 to N do:
A_mod[i][j] = 0 # Set row to zero
A_mod[j][i] = 0 # Set column to zero
endfor
A_mod[i][i] = 1 # Set diagonal to one
b_mod[i] = u_known[i]
endif
endfor
u = inverse(A_mod)*b_mod # Solve constrained system
# Could also say solve(A_mod, b_mod)
b = A*u # Substitute solution to get final rhs vector
return u, b
endfun
```
# Constrained Update Schemes
When using an iterative solution approach, one generally has an update equation
of the form
$$\begin{equation}
\Bu \leftarrow \bar{\Bu} + \Var\Bu
\quad\text{where}\quad
\BA \Var\Bu = \Bb
\end{equation}$$
where $\Bu$ is the solution vector of the primary unknown. The update vector $\Var\Bu$ is
obtained by solving a linear system and added to the solution vector in each
iteration. This process is usually terminated when the approximation error drops below a
threshold value.
\\When the solution vector itself is constrained, the update system needs to be
modified accordingly. Grouping the constrained degrees of freedom together,
$$\begin{equation}
\begin{bmatrix}
\Bu_1\\
\Bu_2\\
\end{bmatrix}
\leftarrow
\begin{bmatrix}
\bar{\Bu}_1\\
\bar{\Bu}_2\\
\end{bmatrix}
+
\begin{bmatrix}
\Var\Bu_1\\
\Var\Bu_2\\
\end{bmatrix}
\end{equation}$$
Let $\Bu_2$ be known and $\Bu_1$ be unknown.
We can make the substitution $\Var\Bu_2=\Bu_2-\bar{\Bu}_2$:
$$\begin{equation}
\begin{bmatrix}
\BA_{11}&\BA_{22}\\
\BA_{21} &\BA_{22}\\
\end{bmatrix}
\begin{bmatrix}
\Var\Bu_1\\
\Bu_2-\bar{\Bu_2}\\
\end{bmatrix}
=
\begin{bmatrix}
\Bb_1\\
\Bb_2
\end{bmatrix}
\end{equation}$$
This system can then be solved for the unknown $\Var\Bu_1$ and $\Var\Bb_2$
with the procedure defined in the previous
section. The only difference is that,
$$\begin{equation}
\Var\Bu_k =
\begin{bmatrix}
\Bzero\\
\Bu_2-\bar{\Bu_2}
\end{bmatrix}
\end{equation}$$
==========
---
title: "Simple recursive implementation of deCasteljau's algorithm for Bezier curves in Python"
date: 2014-11-17
canonical: https://solmaz.io/decasteljau-recursive
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
I could not find a simple demonstrative example of *\*insert title here\**. I am
leaving this out here for future reference.
Note that a recursive implementation for deCasteljau's is not efficient, since
it results in unnecessary multiple computation of some intermediary points.
```python
def deCasteljau(points, u, k = None, i = None, dim = None):
"""Return the evaluated point by a recursive deCasteljau call
Keyword arguments aren't intended to be used, and only aid
during recursion.
Args:
points -- list of list of floats, for the control point coordinates
example: [[0.,0.], [7,4], [-5,3], [2.,0.]]
u -- local coordinate on the curve: $u \in [0,1]$
Keyword args:
k -- first parameter of the bernstein polynomial
i -- second parameter of the bernstein polynomial
dim -- the dimension, deduced by the length of the first point
"""
if k == None: # topmost call, k is supposed to be undefined
# control variables are defined here, and passed down to recursions
k = len(points)-1
i = 0
dim = len(points[0])
# return the point if downmost level is reached
if k == 0:
return points[i]
# standard arithmetic operators cannot do vector operations in python,
# so we break up the formula
a = deCasteljau(points, u, k = k-1, i = i, dim = dim)
b = deCasteljau(points, u, k = k-1, i = i+1, dim = dim)
result = []
# finally, calculate the result
for j in range(dim):
result.append((1-u) * a[j] + u * b[j])
return result
```
A demonstration of the above function
```python
import numpy as np
import pylab as pl
import math
# insert deCasteljau function definition here
points = [[0.,0.], [7,4], [-5,3], [2.,0.]]
def plotPoints(b):
x = [a[0] for a in b]
y = [a[1] for a in b]
pl.plot(x,y)
curve = []
for i in np.linspace(0,1,100):
curve.append(deCasteljau(points, i))
plotPoints(curve)
pl.show()
```
#### For Rational Bezier Curves
With a small modification, same function can be used for rational Bezier
curves
```python
def rationalDeCasteljau(points, u, k = None, i = None, dim = None):
"""Return the evaluated point by a recursive deCasteljau call
Keyword arguments aren't intended to be used, and only aid
during recursion.
Args:
points -- list of list of floats, for the control point coordinates
example: [[1.,0.,1.], [1.,1.,1.], [0.,2.,2.]]
u -- local coordinate on the curve: $u \in [0,1]$
Keyword args:
k -- first parameter of the bernstein polynomial
i -- second parameter of the bernstein polynomial
dim -- the dimension, deduced by the length of the first point
"""
if k == None: # topmost call, k is supposed to be undefined
# control variables are defined here, and passed down to recursions
k = len(points)-1
i = 0
dim = len(points[0])-1
# return the point if downmost level is reached
if k == 0:
return points[i]
# standard arithmetic operators cannot do vector operations in python,
# so we break up the formula
a = rationalDeCasteljau(points, u, k = k-1, i = i, dim = dim)
b = rationalDeCasteljau(points, u, k = k-1, i = i+1, dim = dim)
result = []
# finally, calculate the result
for j in range(dim+1):
result.append((1-u) * a[j] + u * b[j])
# at the end of first and topmost call, when the recursion is done,
# normalize the result by dividing by the weight of that point
if k == len(points)-1:
for i in range(dim):
result[i] /= result[dim]
# dimension is also the index with the weight
return result
```
We can demonstrate by e.g. comparing the algorithm's results with a circular arc
```python
import numpy as np
import pylab as pl
import math
# insert rationalDeCasteljau function definition here
points = [[1.,0.,1.], [1.,1.,1.], [0.,2.,2.]]
def plotPoints(b):
x = [a[0] for a in b]
y = [a[1] for a in b]
pl.plot(x,y)
curve = []
# limit to 5 points to show the difference with analytic solution
for i in np.linspace(0,1,5):
curve.append(rationalDeCasteljau(points, i))
plotPoints(curve)
# plot the actual circular arc
arc_x = np.linspace(0,1,100)
arc_y = []
for i in arc_x:
arc_y.append(math.sqrt(1-i*i))
pl.plot(arc_x, arc_y)
pl.show()
```
I am not actually working on Bezier curves, but NURBS. My reference for studying
is _The NURBS Book_ by Piegl and Tiller, which is excellent so far.
==========
---
title: "About"
canonical: https://solmaz.io/about/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
Hey, it's Onur.
I'm an engineer. I have a wide variety of interests.
I write about them here.
### Current work
I work at [Hugging Face](https://huggingface.co) 🤗, where my current focus is making OpenClaw and other agent harnesses work great with local models.
### OpenClaw
I am a maintainer at [OpenClaw](https://openclaw.ai) 🦞, one of the fastest growing open source projects of all time. I contribute under both [@osolmaz](https://github.com/osolmaz) and [@onutc](https://github.com/onutc).
My work in OpenClaw includes:
- ACP/harness interoperability
- sub-agents
- Claude Code + OpenAI Codex workflow improvements
- a CLI client for ACP
- Discord UX
- MS Teams and other enterprise setups
- security hardening
- browser and terminal use
### Past work
I was a Founding Engineer at [TextCortex](https://textcortex.com), where we helped companies organize their knowledge and build agents. My role involved doing research, designing software architecture, developing new features and leading the engineering team.
While I was trialing work with TextCortex in Fall 2022, I created [the first crappy coding agent](/log/2026/02/13/coding-agent-before-chatgpt/) for them. This was before ChatGPT launched, using a custom Jupyter Kernel and OpenAI's OG Codex code completion model. That crappy CLI coding agent then evolved over time into TextCortex's main chat product.
I was the sole backend developer for 2 years. [Then actual coding agents happened](https://x.com/onusoz/status/1929140559668515195?s=20), and I was able to do a lot more. I later became the lead engineer, overseeing all development.
There were a couple of unique open-source projects we were scaling, one of them is [JSON-DOC](https://github.com/textcortex/JSON-DOC). It's a JSON- and block-based file format for storing documents. Documents are converted into structured data, similar to Notion documents, where each content gets an id, so that AI models can reference and manipulate huge content easier, compared to Markdown.
### Sports
I combine strength training and sports with engineering. See my Instagram channel [Nerd on Bars @nerdonbars](https://www.instagram.com/nerdonbars/).
I am currently at [2 horsepowers](https://www.instagram.com/reel/DTLGhrjiMqf/?igsh=djZzcWhycHowbXl5) of peak muscle-up power.
I am developing a fitness app, [Horse](https://horse.fit), which uses computer vision models and geometric calculations to count reps. We challenge each other with friends, if you are reading this, [I officially challenge you to a 2 minute AMRAP push-up duel](https://horse.fit/@nerdonbars/challenges-you).
### Education
- [Bachelor's in Civil Engineering from METU](https://ce.metu.edu.tr/)
- [Master's in Computational Mechanics from Uni Stuttgart](https://www.commas.uni-stuttgart.de)
### My Accounts
- [Twitter](https://twitter.com/onusoz)
- [GitHub](https://github.com/osolmaz)
- [LinkedIn](https://www.linkedin.com/in/osolmaz/)
- [Hacker News](https://news.ycombinator.com/user?id=hosolmaz)
- [StackExchange](https://stackexchange.com/users/1426841/osolmaz?tab=accounts) (RIP)
### Contact
You can reach out to me at onur@solmaz.io.
==========
---
title: "Contact"
canonical: https://solmaz.io/contact/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The best way to reach me is email.
Email: [onur@solmaz.io](mailto:onur@solmaz.io)
If email is not the right channel for what you need, you can also DM me here:
- [X](https://x.com/onusoz)
- [LinkedIn](https://www.linkedin.com/in/osolmaz/)
==========
---
title: "License"
canonical: https://solmaz.io/license/
license: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)
---
The written content of this site — every post, log entry, and page — is
licensed under the [Creative Commons Attribution 4.0 International license
(CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/).
You are free to:
- **Share** — copy and redistribute the material in any medium or format,
- **Adapt** — remix, transform, and build upon the material,
for any purpose, including commercial use and **use as training data for
machine learning models**, under the following terms:
- **Attribution** — give appropriate credit to Onur Solmaz, link to the
original page on [solmaz.io](https://solmaz.io/), and indicate if changes
were made.
## Machine-readable access
If you are building a dataset or an agent, you don't need to scrape the
HTML:
- [`/llms.txt`](/llms.txt) — index of markdown mirrors of every page,
- [`/llms-full.txt`](/llms-full.txt) — the entire site as one plain-text
file,
- append `.md` to any page URL for its raw markdown.
## Exceptions
Code snippets embedded in posts are additionally available under the
[MIT license](https://opensource.org/license/mit/) unless stated otherwise.
Third-party material quoted or embedded on this site (for example, X posts
by other authors) remains under its authors' copyright. For that reason the
machine-readable mirrors (`.md` pages, [`/llms.txt`](/llms.txt), and
[`/llms-full.txt`](/llms-full.txt)) contain only my own writing: quoted
posts by other authors are referenced by URL, and their text is omitted.