&lt;?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Max Clinton</title><link>https://mtclinton.com/</link><description>Recent essays from Max Clinton</description><generator>Hugo</generator><language>en-us</language><managingEditor>Max Clinton</managingEditor><webMaster>Max Clinton</webMaster><copyright>2026 Max Clinton</copyright><lastBuildDate>Sat, 30 May 2026 01:30:12 +0000</lastBuildDate><atom:link href="https://mtclinton.com/index.xml" rel="self" type="application/rss+xml"/><item><title>The Visitor's Book</title><link>https://mtclinton.com/posts/the-visitors-book/</link><pubDate>Tue, 26 May 2026 12:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-visitors-book/</guid><category>writing</category><description>A man inherits a guest book that signs itself in the next visitor's hand, and slowly learns what it counts as a visit.</description><content:encoded>&lt;![CDATA[<p>I have known Hollis Berridge since we were schoolboys, and I will say at the outset that there has never in all that time been a man more thoroughly suited to his own life. He kept a small house in a quiet street, a small income out of a family trust that had been quiet for three generations, and a small circle of friends who came to him at regular intervals and were treated, when they came, with the unobtrusive and entirely sincere hospitality of a man who has decided he does not very much wish to go anywhere himself but has no objection to being called upon. He read in the mornings, walked in the afternoons, and dined alone four nights in seven and in company the other three; and he had so arranged this life that the proportions of it required no further adjustment of any kind, and he proposed to live the rest of it on the same plan. That he did not is the subject of what follows, and I set it down as he gave it to me, in the order in which he gave it, because Berridge asked me to, and because a thing of this kind ought not to vanish merely because it would be inconvenient to the world to credit it.</p><p>The book came to him by the same path most of his furniture had come — by way of an aunt, a Miss Henrietta Berridge, who had occupied a narrow house on the south side of the town for the better part of fifty years and had died there at last in the manner she had lived: without bother to anyone and without consultation with the doctor she had outlasted. The estate was small and the relations few, and Berridge, being both the nearest and the most willing to come down for the inventory, had been left to dispose of the contents as he saw fit. Most of it he sent to the auction rooms. A few things he kept — a clock he had liked as a boy, a set of plates not worth the carriage but pleasant to remember her by, and, among a parcel of stationery oddments turned out of her desk, a guest book bound in dark green calf, much rubbed at the corners, with the word<em>Visitors</em> stamped in faded gilt across the front and a brass clasp that had long since ceased to clasp anything.</p><p>It is the sort of book that used, in such houses, to lie open on the hall table beside a small dish for cards. The earliest signatures in his aunt&rsquo;s were from the eighteen-eighties; the last was perhaps a dozen years old, a curate she had once given tea to. Between these two dates were perhaps four hundred entries, in every variety of hand, each one a person who had crossed his aunt&rsquo;s threshold and been thought sufficient to her hospitality to be invited to record the fact. Berridge took the book home, less out of any feeling for it than because he had reached the bottom of the parcel and saw no reason to throw it away, and he laid it on the side-table in his own small hall. He thought, with a passing pleasure in the thought, that he would begin a fresh page; that his own visitors might sign below where his aunt&rsquo;s had signed, the line continuing through him as the line of clocks and plates and quiet trust incomes had continued through him; and that this was the modest sort of small ceremony a man in his circumstances might reasonably maintain. He turned to the first blank page after the curate, and he wrote in his own neat hand at the top of it the date, and his own name, and the words<em>In residence</em>, by way of opening the page. And he did no more with the book that evening, and went to his supper.</p><p>He came down the next morning, he told me, and his eye caught on the book before it caught on anything else, because there was a second entry on the page where last night there had been only his own.</p><p>It was below his, in the proper place; it was dated for that morning&rsquo;s date; and it was in a confident sloping hand he had never seen in his life. The name written was<em>Edwin Mark Pelham</em>. He did not know any Edwin Mark Pelham. There was no card on the hall table, no caller&rsquo;s hat upon the peg, no possible explanation a careful man could put forward for finding a stranger&rsquo;s signature in a book that had stood overnight in a locked house. Berridge — and he was at pains, in the telling, that I should understand this — Berridge was not a man given to fanciful constructions. He took the book up and examined the ink and found it dry; he checked the front door and found it bolted as he had left it; he asked his housekeeper, when she came, whether anyone had called, and she said no one had, and he believed her, because she was a woman who would have mentioned a moth.</p><p>He set the book down again and resolved to think no more of it, which is the resolution men in his case always make and always immediately break. He thought a great deal of it. He thought of it through breakfast and through the morning&rsquo;s reading, and at a little after eleven the bell rang, and the housekeeper went to the door, and there came into Berridge&rsquo;s hall — apologising for the want of notice, with a letter of introduction from a man Berridge knew slightly in the country — a gentleman who gave his name, on being asked, as Edwin Mark Pelham.</p><p>Berridge held the visitor&rsquo;s coat, he said, with hands that performed the office quite competently while the mind behind them stood at some considerable distance and watched. He showed Mr Pelham into the morning-room. He gave him sherry. He listened, with every appearance of attention, to the matter Mr Pelham had come about — a question of some old shares of his aunt&rsquo;s that touched a charity Pelham administered — and concluded the business in a quarter of an hour, and then, in the calmest voice he could lay his tongue to, he asked Mr Pelham if he would be so good as to sign the visitor&rsquo;s book in the hall on his way out.</p><p>Mr Pelham was, naturally, willing. He stood at the side-table; he took up the pen; and he wrote, in a confident sloping hand that Berridge already knew, exactly the entry that had been there since the morning. The same date. The same name. The same loop on the final<em>m</em>. He put down the pen and went away, and Berridge stood in the hall with the book in front of him and looked, on the open page, at the single signature — a single signature now, because the morning&rsquo;s entry and the noon&rsquo;s were not two entries but one, written once.</p><h2 id="a-most-convenient-article">A Most Convenient Article</h2><p>I will not pretend, and Berridge did not pretend, that the period that followed was anything but a pleasant one. A thing of this kind, when it is new, has a way of being its own sufficient justification, and the early weeks of the book&rsquo;s working were perhaps the happiest of his middle life.</p><p>For it worked, very plainly, by a single rule. The book wrote, in advance, the entry of the next person who would cross his threshold. Sometimes it wrote in the early hours, before he came down; sometimes — he discovered, by going out to the hall at odd intervals — it wrote in the moments after some hidden mechanism in the world had settled who the next caller was to be, which might be a quarter of an hour or several days before the call itself. The hand was always the visitor&rsquo;s own. The date was always correct. He had only to come down each morning, glance at the book, and know whether to expect anyone; and if anyone was expected, who; and, by the date set against the name, when.</p><p>The conveniences of this were considerable, and he availed himself of them. He had cake in the house when his cousin came up unannounced, because the book had told him she was coming; he had the small private collection of architectural prints already laid out on the morning-room table when Crowther, who cared for such things, called by on a whim; he had decanted the better claret an hour before the bishop, who was no friend of his but the friend of a friend, found himself unexpectedly in the neighbourhood. The bishop went away saying that Berridge was a man of remarkable readiness, and the saying of it travelled. Berridge began, in a small way, to be sought out. The note in people&rsquo;s voices, when they spoke of him, acquired the particular warmth a host&rsquo;s name acquires when a man can say of him that he has never once been caught wanting. He was, in short, found hospitable; and he had not had to alter, for the sake of being found hospitable, a single one of his comfortable habits, since he had now to alter nothing in haste and could alter everything in good time.</p><p>He took, also, an interest in the simpler pleasure of foreknowledge for its own sake — standing by the table of a morning before any caller had arrived and spending an idle quarter-hour wondering what the bearer of an unknown name would look like, whether his business would be brisk or long. The book never told him<em>what</em> the call would be about; only that it would happen, and who. The rest was left to the hour itself, and he found, perhaps to his own faint surprise, that it was left genuinely. The man who came to the door at three was not less interesting because Berridge had known since seven that he was coming. He brought his own news. He brought his own face. The book had not, as Berridge put it to me with some satisfaction in that first telling,<em>taken the day</em>. It had only prepared him for it.</p><p>This went on, by his reckoning, a little over four months. He recorded, in those four months, perhaps thirty signatures in advance of their visits, and not one of them had failed.</p><h2 id="the-name-that-did-not-come">The Name That Did Not Come</h2><p>The first thing that troubled him, he told me, was not a signature that failed but a signature that he could not place.</p><p>It appeared on a Wednesday in the autumn. He came down, glanced at the book, and saw written in the morning&rsquo;s place, in a careful schoolmasterish hand, the name<em>Thomas Carrick</em>. He did not know any Thomas Carrick. This in itself was not alarming — he had not known Pelham either, and a number of the names since had been new to him — and he went about his morning expecting, as before, that the door would open in due course upon a stranger.</p><p>The door did not open. No one came that day. No one came the next, either, nor the next. Berridge watched the book in some perplexity. The entry remained where it was, dated for the Wednesday, the ink quite ordinary; nothing else appeared above or below it; and at the end of a week he was obliged to set it down, with whatever feelings, as the first instance in which the book had been wrong.</p><p>He thought of it as the first instance, that is, for the better part of a fortnight. Then, on a Tuesday evening, he came into his hall by the back stair to take down a book of his aunt&rsquo;s letters, and as he passed the side-table he saw — without at first understanding what he was seeing — that on the cover of an envelope lying there, addressed to him in a hand he had been about to open, was the name of the sender printed in small black type above the seal. The sender was a firm of country solicitors. The signing partner was a Mr Thomas Carrick. The envelope had been delivered by the second post on the very Wednesday the visitor&rsquo;s book had written his name; Berridge had carried it through to the morning-room, had read its contents and answered them, and had laid the envelope back on the side-table, where it had stayed, because he was not a man who threw papers away promptly. He had answered Mr Carrick&rsquo;s enquiry in writing, and Mr Carrick had never set foot in the house.</p><p>Berridge stood with the envelope in one hand and the visitor&rsquo;s book open in the other, he told me, and he understood for the first time that he had been mistaken about what the book did.</p><p>It did not record the people who would walk into his hall. It recorded — and he saw this with a slow and disagreeable clarity — the people who would, on that day, cross his threshold<em>in some sense.</em> A letter, lying on his hall table from breakfast to bedtime, had counted. A man whose name had passed under his eye and whose words had occupied his attention for an hour together, though that man had been forty miles off and would never come within forty of him, had counted. The book&rsquo;s threshold was not the door. The book&rsquo;s threshold was something a great deal harder to draw a line round; and Berridge had been keeping, with a comfortable inattention, only the most outward and bodily account of his own borders, while the book had been keeping a longer and less merciful one.</p><p>He sat down in the hall, he said, and turned slowly back through the four months&rsquo; pages, and found that he had been quietly wrong about a number of them. There was a name he had read as a caller&rsquo;s, and which was now on examination the unmistakable hand of a clergyman whose long telegram of condolence had arrived that afternoon and been read in the hall before he carried it through to the fire. There was an entry he had taken pride in answering with claret: the bishop had crossed his threshold, indeed, but he had crossed it twice by the book&rsquo;s reckoning — once on the day of the wine, and once, more quietly, a week earlier, when his pastoral letter had been read aloud at Berridge&rsquo;s breakfast. He had crossed several of these names off, in his own hand, as failures of the book; he saw now that none of them had been failures of any kind. The book had been faithful. He had been reading it by the wrong measure.</p><p>A man, Berridge said to me, accumulates an immense number of small visitors in the course of a quiet life, and does not, for the most part, notice them; and a book that counts every one of them is a book that knows him a great deal more intimately than he knows himself.</p><h2 id="what-the-threshold-was">What the Threshold Was</h2><p>It was after this, he told me, that he stopped sleeping well.</p><p>He continued, for some time, to come down each morning and look at the book; he could not bring himself not to look. But what he was looking for had altered. He was no longer reading the page to see who would knock at the door. He was reading it to see what the day intended to be allowed to reach him. The book had revealed itself as a kind of register of admissions, and the keeping of the register was not in his hands; and a man who has come to understand that someone, or something, somewhere is keeping a register of every person and every voice that he permits across the inner boundary of his attention does not easily resume his old comfortable opinion of the privacy of his own house.</p><p>He began to notice, as he had not noticed before, how many names a quiet life in fact admits. He read a great deal — most reclusive men do — and every author he opened was, by the book&rsquo;s reckoning, a visitor; he took newspapers and telegrams and letters, and the writers of leaders and the senders of bills came in with them; he thought, late in the evening, of friends not heard from in years, and the thought itself, he came at last to suspect, was a small door opened upon them through which the book counted them as having passed. He took, for the better part of a fortnight, a private inventory of his admissions; and the count, even on his most retired days, ran into the dozens. He saw then that his solitude, which he had always considered a settled and well-defended thing, had been throughout his life a very crowded room indeed; and that the only difference the book had introduced was that someone was, at last, keeping the list.</p><p>There was no consolation in the discovery. The book, he came to see, did not merely record; it chose. It chose, by some rule he could not work out,<em>which</em> of his day&rsquo;s many admissions to set down and which to let go unrecorded; and the choosing was a judgement, and the judgement was not his. There were names it wrote in a fine round hand and gave precedence on the page; there were names it set down small, and at the foot, as though apologising for them; there were people he had thought himself close to whose names appeared only after long absence, and others he had hardly given thought to whose names recurred and recurred. He saw himself, gradually, through the book&rsquo;s eye — not as the host of a few particular friendships, conducted on the front step, but as the keeper of a long and uneven account in which he was creditor and debtor by turns to a hundred presences he had never properly examined. And he was ashamed of the account.</p><p>I think this is the part he found hardest to give me. The book&rsquo;s register was not a list of merely external doings; it was a list of where his attention had really gone. The friends to whom he was hospitable in the matter of cake and claret appeared in a small careful hand, as though the book agreed with him in counting them; but it also recorded, in larger and freer letters, the people he had not invited and would not have admitted at his door and yet had let in by some softer entrance — strangers whose books he had argued with at midnight, dead men he kept up quarrels with, women he had never spoken to who lived in his afternoons. The book did not judge these admissions; it merely<em>noticed</em> them, and the noticing was unanswerable, because the hand each one was set down in was the person&rsquo;s own.</p><h2 id="the-last-entry">The Last Entry</h2><p>He did not, he told me, ever consider destroying the book. He had thought of it, naturally; one entertains the thought, in such a case, as a man entertains the thought of the doctor he will not see. But he found that he could not. The book was, by then, the only honest history he possessed of his own days, and a man does not burn the only honest history he possesses, however poorly it flatters him. He thought, at one period, of locking it away, but he understood that the locking away would alter nothing — the book would write whether he watched it or not, and not to watch was merely to be the last of his own visitors to know who had been admitted.</p><p>He left it on the side-table.</p><p>I saw him in the spring. He had grown thinner, in the way men of his temperament grow thinner — without any loss of order, with the same neat collar and the same neat conversation, but with the bones of the face become a little nearer to the surface, as though the man inside were standing a step closer to the window. We spoke of his aunt, and the prints, and a small matter about my own affairs in which he was kind enough to take an interest. As I was leaving he asked me, with a particular gentleness, to come and sit with him in the hall for a moment, and I went, and he opened the book.</p><p>He had not turned to the morning&rsquo;s page. He had turned to a page some way forward — three weeks forward, by the date written at its head, in his own hand — and on that page, beneath the date, there was a single entry. It had been written, plainly and without flourish, in a hand I knew at once, because I had seen it on the flyleaf of every book Berridge had ever lent me. The name was his own. The date was a Tuesday morning some weeks ahead. There was no other entry on the page, and the rest of the book, when he leafed through it for me, was blank from the present day to that one and blank thereafter.</p><p>He shut the book carefully and put it back on the table, and he asked me, in a level and quite unrhetorical voice, what I thought it meant. I tried to give him the comfortable interpretations — that it was the date of some long journey, some final shutting of his own door behind him, some particular and ordinary admission of himself into his own house after an absence. He let me give them. He did not contradict any of them. He thanked me, with the same particular gentleness, for having tried.</p><p>I went home, and I did not write to him for some days, because I did not know what to write that would not be insulting either to him or to the book. On the Wednesday after the date he had shown me, his housekeeper sent me a note. He had been found in the morning-room, in his chair, with the book open on the table beside him at the page on which his name had stood three weeks; and the page, the housekeeper said, in the particular flat steady tone in which her short letter was set down throughout, was now empty. The entry was gone. There was no mark where the writing had been. The hand, having at last crossed the threshold it had been waiting to cross, had taken its signature with it; and the page was as clean and as unwritten as the rest of the book that lay ahead of it, and would lie ahead of it, and would no longer be opened by anyone.</p><p>I have set this down as he asked me to, and as exactly as I am able. The book is in my keeping now. He left it me by a clause in his will, with a small note in his own hand asking me not to open it on any blank page and not to attempt to begin a fresh one of my own; and I have honoured both requests, and propose to go on honouring them, because I have spent a part of every week since trying not to think about the visitors my own quiet life admits, and I am not yet ready to know which of them a book in my hall would think it worth its while to write down.</p>
]]></content:encoded></item><item><title>Git's Wire Protocol</title><link>https://mtclinton.com/posts/gits-wire-protocol/</link><pubDate>Tue, 26 May 2026 11:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/gits-wire-protocol/</guid><category>code</category><description>An account of what actually crosses the wire when one types git fetch — pkt-lines, packfiles, the ref negotiation, and the engineering judgment behind it all.</description><content:encoded>&lt;![CDATA[<p>For a tool one types thirty times a day, Git is exceedingly reticent about what it does on the wire.<code>git fetch</code> blinks back a few lines about counting and resolving deltas;<code>git push</code> reports a tally and exits; and the conversation between client and server, which is the entire point of the exercise, passes invisibly behind a progress bar. I set out to follow what actually happens — to trace the bytes, in order, from the moment one presses Return — and the account that follows is what I found when I did.</p><p>The pitch, shorn of ornament, is this. When one fetches, the client and the server perform a brief negotiation about which commits each of them already has, and the server then ships, in a single delta-compressed stream, only the objects the client lacks. The protocol that carries this conversation is older than HTTPS, older than most of the libraries one uses to speak to Git, and — what is more surprising — it has been retrofitted to run over HTTPS without altering its essential shape. It is a framed, line-oriented protocol, of the kind one might have written in 1995 and not been embarrassed about; and it has aged better than most of its contemporaries, for reasons I shall come to.</p><h2 id="pkt-line-the-frame-the-whole-thing-sits-inside">pkt-line: The Frame the Whole Thing Sits Inside</h2><p>Before any of the higher conversation is intelligible, one must understand its unit. Git&rsquo;s wire protocol is composed of pkt-lines, and a pkt-line is a four-character hexadecimal length prefix followed by the bytes the length describes. The length includes itself. That is the whole specification, and one can read it in a sentence; the trouble is that everything else is built on top of it, and reading a real Git transcript requires that one parse pkt-lines in one&rsquo;s head with no greater effort than one parses sentences in English.</p><p>An example. The line</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="mi">001</span><span class="n">e</span><span class="c1"># service=git-upload-pack\n</span></span></span></code></pre></div></div></figure><p>is a pkt-line of total length<code>0x001e</code> = 30 bytes. The four-byte prefix<code>001e</code> plus the 26 bytes of payload (<code># service=git-upload-pack</code> followed by a single<code>\n</code>) sum to exactly 30. One does not need to count; one need only trust the prefix.</p><p>There are three special pkt-lines, and a great deal of the protocol&rsquo;s elegance depends on them. A line beginning<code>0000</code> is a<em>flush packet</em> — it has no payload, and its meaning is &ldquo;I am done with this section.&rdquo; A line beginning<code>0001</code> is a<em>delim packet</em>, introduced with Protocol v2, and it separates capability lines from arguments within a single command. A line beginning<code>0002</code> is a<em>response-end packet</em>, also a v2 addition, used to mark the end of a response in a stateless connection where several command-responses share a single transport. Lengths from<code>0004</code> (an empty payload, which the spec allows but discourages) up to<code>fff0</code> (65520 bytes total, of which 65516 are payload) carry data. Everything else is reserved.</p><p>A typical advertisement opens like this:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="mi">001</span><span class="n">e</span><span class="c1"># service=git-upload-pack\n</span></span></span><span class="line"><span class="cl"><span class="mi">0000</span></span></span><span class="line"><span class="cl"><span class="mi">0148</span><span class="o">&lt;</span><span class="n">sha1</span><span class="o">&gt;</span><span class="n">HEAD</span>\<span class="mi">0</span><span class="n">multi_ack_detailed</span><span class="n">no</span><span class="o">-</span><span class="n">done</span><span class="n">side</span><span class="o">-</span><span class="n">band</span><span class="o">-</span><span class="mi">64</span><span class="n">k</span><span class="n">thin</span><span class="o">-</span><span class="n">pack</span><span class="o">...</span>\<span class="n">n</span></span></span><span class="line"><span class="cl"><span class="mi">003</span><span class="n">d</span><span class="o">&lt;</span><span class="n">sha1</span><span class="o">&gt;</span><span class="n">refs</span><span class="o">/</span><span class="n">heads</span><span class="o">/</span><span class="n">main</span>\<span class="n">n</span></span></span><span class="line"><span class="cl"><span class="mi">0040</span><span class="o">&lt;</span><span class="n">sha1</span><span class="o">&gt;</span><span class="n">refs</span><span class="o">/</span><span class="n">heads</span><span class="o">/</span><span class="n">develop</span>\<span class="n">n</span></span></span><span class="line"><span class="cl"><span class="mi">0000</span></span></span></code></pre></div></div></figure><p>The first pkt-line is a service announcement. The first<code>0000</code> flushes that section. Then the server emits one pkt-line per advertised ref, with the very first ref carrying a NUL byte and, after it, the server&rsquo;s capability list. The second<code>0000</code> ends the advertisement.</p><p>Two observations are worth lingering over. The first is that the capability list is wedged into the first ref&rsquo;s pkt-line rather than given its own packet — a piece of cheerful 2005 thrift that has survived intact. The second is that the framing is<em>self-synchronising</em>. If one drops into the middle of a Git stream with no prior context, one need only read four bytes, parse a hex length, skip that many bytes, and one is exactly at the start of the next pkt-line. There is no preamble to find, no state to recover. This is the kind of property that does not announce itself on the day a protocol is designed, but which one is grateful for every time one writes a packet sniffer.</p><h2 id="the-two-halves-of-the-conversation-upload-pack-and-receive-pack">The Two Halves of the Conversation: upload-pack and receive-pack</h2><p>Git&rsquo;s network operations come in two flavours, and the names are unfortunately back-to-front from the point of view of the user.<code>git fetch</code> and<code>git clone</code> invoke<em>upload-pack</em> on the server — the server is &ldquo;uploading&rdquo; the pack to the client.<code>git push</code> invokes<em>receive-pack</em> on the server — the server is &ldquo;receiving&rdquo; the pack from the client. The verbs are written from the server&rsquo;s perspective. One either learns this and is forever calm, or one does not and is occasionally bewildered.</p><p>For the rest of this account I shall mostly follow the fetch path, because it is where the negotiation lives, and the negotiation is the most interesting thing about the protocol.</p><p>A fetch consists of three phases. First, the server advertises its refs and capabilities — it tells the client what it has. Second, the client and server negotiate which commits they have in common, so that the server need not ship history the client already possesses. Third, the server constructs a packfile containing exactly the objects the client lacks, and streams it back.</p><p>The first phase is straightforward. The third phase is mostly file-format work. The interesting phase, in the engineering sense, is the second.</p><h2 id="the-negotiation">The Negotiation</h2><p>Consider the problem the negotiation is trying to solve. The client wants some refs —<code>refs/heads/main</code>, say — at a particular SHA-1. It has some history of its own, which may or may not overlap with the server&rsquo;s. It would be cheap, and dim-witted, for the server simply to ship every commit reachable from the requested ref. It would be expensive, and equally dim-witted, for the client to enumerate every commit it has and ask the server to filter.</p><p>Git&rsquo;s negotiation threads its way between these. The client emits a sequence of<code>want</code> lines — &ldquo;I want commit X, and Y, and Z&rdquo; — followed by a flush. It then emits a sequence of<code>have</code> lines — &ldquo;I have commit A, and B, and C, &hellip;&rdquo; — pausing periodically to let the server respond. The server, on receiving each batch of<code>have</code> lines, checks whether any of them are ancestors of any object reachable from the requested wants. If they are, the server emits an<code>ACK</code> for that commit and the negotiation has made progress.</p><p>The client&rsquo;s job, at this point, is to walk its own commit graph cleverly. It does not send every commit it has — that would defeat the point. Instead, it sends in waves: first its branch tips, then their parents, then their grandparents, increasing the search radius until either the server acknowledges enough commits to determine a common ancestor, or the client exhausts its history and the server is obliged to send everything from the roots.</p><p>A simple fetch in flight looks something like this:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0067want &lt;sha1-of-wanted-commit&gt; multi_ack_detailed side-band-64k thin-pack...\n</span></span><span class="line"><span class="cl">0032want &lt;sha1-of-another-wanted-commit&gt;\n</span></span><span class="line"><span class="cl">0000</span></span><span class="line"><span class="cl">0032have &lt;sha1-of-local-commit-1&gt;\n</span></span><span class="line"><span class="cl">0032have &lt;sha1-of-local-commit-2&gt;\n</span></span><span class="line"><span class="cl">...</span></span><span class="line"><span class="cl">0009done\n</span></span></code></pre></div></div></figure><p>The server responds with<code>ACK &lt;sha1&gt;</code> for each<code>have</code> it recognises, or<code>NAK\n</code> if none of the current batch matched. When the client decides it has nothing more useful to offer — or the server announces it has found a sufficient common base — the client sends<code>done</code>, and the server commits to producing a packfile.</p><p>There are three negotiation modes the protocol supports, and the rules differ subtly between them. In the oldest mode — plain<code>multi_ack</code> — the server emits<code>ACK &lt;sha1&gt; continue</code> for each common commit it finds, and the client must decide on its own when to stop. In<code>multi_ack_detailed</code>, which is what almost any modern client uses, the server distinguishes between two kinds of<code>ACK</code>:<code>common</code> (we both have this commit) and<code>ready</code> (we have enough; you can send<code>done</code> whenever you like). The detailed mode lets the server hint at when the conversation should end without requiring it. The negotiation, in other words, is a polite exchange in which the server is permitted to say &ldquo;you may stop now&rdquo; but not &ldquo;you must.&rdquo;</p><p>The algorithm that drives the client&rsquo;s choice of which<code>have</code>s to send is, in practice, a bounded walk over its own commit graph. Git starts from each local ref tip and walks parents in roughly chronological order, in batches of 32. The canonical client does not stop and wait between batches; it pipelines them, keeping 32<code>have</code>s in flight at all times — when one batch ends in a flush, the next 32 are already on the wire by the time the server is ready to answer. If the server acknowledges enough of them — typically when it has found commits on every side of the merge frontier — the walk can stop. There is a<em>skip-list</em> of commits already explored to avoid revisiting branch joins, and a<em>common</em> set of commits the server has acknowledged, used to prune the search. None of this is exposed to the user, and rightly so; but it is the difference between a fetch that ships fifty commits and one that ships fifty thousand.</p><p>The engineering judgment in this design is, to my mind, the most admirable thing about Git&rsquo;s wire protocol. The negotiation is<em>iterative</em>, not<em>enumerative</em>. The client never has to send its whole graph. The server never has to send its whole graph. Each round trip prunes the space the next round trip must explore, and the conversation converges, in the median case, in two or three round trips. There are pathological cases — branches with no common ancestor, brand-new clones — and the protocol handles them gracefully by falling through to &ldquo;send everything reachable from the wants,&rdquo; which is, after all, the worst case it could possibly perform.</p><h2 id="the-packfile">The Packfile</h2><p>Once the negotiation has determined a set of objects the client lacks, the server&rsquo;s task is to deliver them. It does so by constructing a packfile — a single binary stream containing every needed blob, tree, commit, and tag, compressed with zlib and, where it helps, expressed as a<em>delta</em> against another object already in the stream.</p><p>The packfile format is brief enough to describe in one paragraph. A 12-byte header (<code>PACK</code> magic, four-byte version, four-byte object count), followed by the objects themselves, followed by a 20-byte SHA-1 trailer that checksums the entire pack. Each object starts with a variable-length header that encodes its type —<code>OBJ_COMMIT</code>,<code>OBJ_TREE</code>,<code>OBJ_BLOB</code>,<code>OBJ_TAG</code>,<code>OBJ_OFS_DELTA</code>, or<code>OBJ_REF_DELTA</code> — and its uncompressed size. The body is zlib-compressed.</p><p>Delta objects deserve a separate sentence. A delta object is not a complete object; it is a sequence of instructions for reconstructing one object from another.<code>OBJ_OFS_DELTA</code> says &ldquo;the base object is N bytes earlier in this packfile&rdquo;;<code>OBJ_REF_DELTA</code> says &ldquo;the base object is the one with SHA-1 X, which I trust you can find.&rdquo; The instructions themselves are tiny: copy these bytes from the base, then insert these literal bytes, then copy these other bytes. For a file that has had one comment edited, the delta is a few dozen bytes; the entire object&rsquo;s reconstruction is therefore a few dozen bytes plus a pointer to its base. This is how a Linux-kernel-sized repository fits into the gigabyte range rather than the terabyte one.</p><p>A<code>thin-pack</code>, which is the default for fetches, is permitted to use<code>OBJ_REF_DELTA</code> against objects the client<em>already has</em> but which are not present in the pack itself. The client, on receipt, must fatten the pack by resolving those external base references before it can index it. This is one of those decisions that looks like a compromise on first reading and turns out, on second reading, to be the obvious thing — there is no point shipping a base object the client already possesses merely to keep the pack self-contained.</p><p>After the pack arrives, the client indexes it: it computes a<code>.idx</code> file containing the SHA-1 of every object, its offset in the pack, and a small fanout table keyed by the first byte of the SHA-1 so that lookups can binary-search within a 256th of the index. Modern<code>.idx</code> files — version 2, which has been the default since 2007 — open with a four-byte magic number<code>\377tOc</code> and a version word, and to the fanout and the SHA-1 table they add a CRC32 per object (used to detect corruption when objects are copied between packs) and a split pair of offset tables, four bytes wide for the common case and eight bytes wide for the entries that need them, so that packs larger than four gibibytes can still be addressed. The pack is now usable. Until it is indexed, it is, strictly speaking, an opaque blob with a checksum at the end.</p><h2 id="smart-http-tunnelling-an-ssh-era-protocol-through-https">Smart HTTP: Tunnelling an SSH-Era Protocol Through HTTPS</h2><p>Git was originally spoken over<code>git://</code>, a bespoke protocol on TCP port 9418, and over SSH. Both are perfectly serviceable on the open Internet of 2005; both are increasingly inconvenient on the corporate Internet of 2015 onwards, where outbound TCP to arbitrary ports is firewalled and the only reliable transport is HTTPS on port 443. Git&rsquo;s response was<em>smart HTTP</em>, which is the mechanism by which one can<code>git clone https://github.com/...</code> and have the whole pkt-line conversation take place over what looks, to any firewall, like an ordinary web request.</p><p>Smart HTTP uses two endpoints. The first is<code>GET /info/refs?service=git-upload-pack</code> (or<code>...=git-receive-pack</code>). The server responds with the same ref advertisement one would have seen on the wire of the native protocol, prefixed with a<code># service=...\n</code> pkt-line and ended with a flush. The Content-Type is<code>application/x-git-upload-pack-advertisement</code>, which is the polite way of telling intermediate caches not to mangle it.</p><p>The second endpoint is<code>POST /git-upload-pack</code> (or<code>/git-receive-pack</code>), to which the client sends its<code>want</code>/<code>have</code> conversation as the request body — a sequence of pkt-lines, exactly as one would have written them on a socket — and from which it receives the packfile as the response body. The Content-Types are<code>application/x-git-upload-pack-request</code> and<code>application/x-git-upload-pack-result</code> respectively.</p><p>The trick that makes this work, and that took me a moment to appreciate, is that the protocol is stateless from HTTP&rsquo;s point of view but stateful from Git&rsquo;s. The whole<code>want</code>/<code>have</code> negotiation has to happen in a single HTTP POST. The client cannot say<code>have &lt;sha1&gt;</code> in one request, get an<code>ACK</code>, and decide what to send in the next request — at least not in v1. Instead, the client computes its entire opening offer locally, sends it in one body, and the server responds with whatever it can. If the conversation needs more rounds, the client opens a fresh POST and sends its next offer (including everything from the previous round it now knows the server has). Each POST is a complete sub-conversation that begins with the client speaking and ends with the server.</p><p>This is not, technically, an efficient use of HTTP. Each round trip is a fresh request. The TLS session may be reused, but the application-level state is not. Yet it works, because the negotiation typically converges in one or two rounds, and the cost of an extra POST is, in the median case, an extra hundred milliseconds against the seconds of pack streaming that follow. The protocol&rsquo;s tolerance for inefficient transports turns out to be a feature.</p><h2 id="protocol-v2-the-quieter-conversation">Protocol v2: The Quieter Conversation</h2><p>In 2018 Git introduced a second version of the wire protocol, and it is worth a section on its own — not because it changes the fundamentals, but because it changes what one might call the<em>politics</em> of the opening exchange.</p><p>The trouble with v1 is the ref advertisement. Whenever a client connects, the server sends every ref it has — every branch, every tag, every pull-request pointer that the hosting provider has tucked into a hidden namespace. For a small repository this is invisible. For a repository with three hundred thousand refs — and there are such repositories — it is several megabytes of pkt-lines transmitted before the client has so much as said what it wants. The cost falls hardest on<code>git ls-remote</code>, which throws all of that information away after reading the one line it asked for.</p><p>Protocol v2 inverts this. The client, on connecting, declares the protocol version in whatever way the transport allows: over<code>ssh://</code> and<code>file://</code> it sets the<code>GIT_PROTOCOL=version=2</code> environment variable in the remote process; over the native<code>git://</code> protocol it appends<code>version=2</code> as an additional NUL-delimited extra-parameter inside the initial pkt-line request; and over HTTP it sends a<code>Git-Protocol: version=2</code> header. Three transports, three mechanisms, the same message. The server, recognising v2, advertises its capabilities — but not its refs. The client then issues an explicit<em>command</em>:<code>ls-refs</code> (with optional ref-prefix filters), or<code>fetch</code>, or<code>object-info</code>. The server responds with only the information that command requested.</p><p>A v2 conversation thus begins something like:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">000eversion 2\n</span></span><span class="line"><span class="cl">0015agent=git/2.40.0\n</span></span><span class="line"><span class="cl">001fls-refs=unborn ref-in-want\n</span></span><span class="line"><span class="cl">0019fetch=shallow filter\n</span></span><span class="line"><span class="cl">0012server-option\n</span></span><span class="line"><span class="cl">0017object-format=sha1\n</span></span><span class="line"><span class="cl">0000</span></span></code></pre></div></div></figure><p>— a capability advertisement, with no refs in sight. The client now sends a command pkt-line and a delim packet (<code>0001</code>) before its arguments:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">0014command=ls-refs\n</span></span><span class="line"><span class="cl">0015agent=git/2.40.0\n</span></span><span class="line"><span class="cl">0001</span></span><span class="line"><span class="cl">0009peel\n</span></span><span class="line"><span class="cl">000csymrefs\n</span></span><span class="line"><span class="cl">001bref-prefix refs/heads/\n</span></span><span class="line"><span class="cl">0000</span></span></code></pre></div></div></figure><p>The<code>ref-prefix</code> argument restricts the response to refs under<code>refs/heads/</code>. The server returns only those refs. The advertisement has been narrowed from &ldquo;everything the server has&rdquo; to &ldquo;exactly what the client asked about,&rdquo; and on a large repository the difference is several orders of magnitude of bandwidth.</p><p>The other notable addition in v2 is<code>ref-in-want</code>. In v1, a client must phrase its wants in terms of object IDs (SHA-1s), which it must have learned from a prior ref advertisement. In v2, the client may say<code>want-ref refs/heads/main</code> directly, and the server resolves the ref to an object ID server-side. This eliminates a race condition that v1 had quietly tolerated — between the moment the client read the ref advertisement and the moment it sent its<code>want</code>s, the ref might have moved — and it eliminates the need to advertise refs the client did not ask about.</p><p>Protocol v2 did not change the packfile format. It did not change the negotiation algorithm. It changed only the opening — and that turned out to be the right place to change, because the opening was where the protocol&rsquo;s age showed most clearly. The fundamentals — pkt-lines, packfiles, the iterative<code>want</code>/<code>have</code> conversation — held up perfectly well; what had aged badly was the<em>unconditional</em> ref advertisement.</p><h2 id="what-i-actually-learned">What I Actually Learned</h2><p>Three things seem to me worth writing down.</p><p>The first is that pkt-line framing is the unsung hero of this protocol. A four-byte hex length prefix is an exceedingly modest design choice — there are protocols of comparable age that do far cleverer things with framing — and it is exactly that modesty which has allowed every other piece of the protocol to evolve without disturbing the bytes underneath. New commands, new capabilities, new modes of negotiation, even a whole new protocol version, have all been added without changing the framing by a single byte. One does not always notice the parts of a protocol that hold the others up; pkt-lines are such a part.</p><p>The second is that the negotiation is the most interesting thing in the entire system, and it is also the thing one is least likely to notice using Git day to day. The fact that<code>git fetch</code> ships fifty kilobytes after a routine pull, rather than the gigabytes one&rsquo;s repository contains, is the work of a small, careful algorithm that walks the commit graph in batches and trades round trips for bandwidth. It is the kind of cleverness that pays for itself many millions of times a day, and that is invisible to anyone who has not gone looking for it.</p><p>The third — and this is the one I should like to leave standing — is that Git&rsquo;s wire protocol is a study in<em>avoiding</em> premature elegance. It is not RPC. It is not gRPC. It is not Protocol Buffers. It is text-shaped binary, with a hex length prefix and a flush packet, written by people who were, one suspects, less interested in being modern than in being correct. The protocol has been retrofitted to HTTPS, extended with capabilities, given a wholly new version — and the original 2005 pkt-line is still the unit of every message. I do not think one could ask a protocol design to age better than that.</p><p>The source, for anyone curious to read further, lives in<code>Documentation/</code> inside the Git repository — particularly<code>gitprotocol-common.adoc</code>,<code>gitprotocol-pack.adoc</code>,<code>gitprotocol-v2.adoc</code>,<code>gitprotocol-http.adoc</code>, and<code>gitformat-pack.adoc</code>. (These were<code>Documentation/technical/*.txt</code> until Git 2.38 in 2022 rehomed them, renamed them, and reset their extension to AsciiDoc; older posts on the protocol still cite the old paths.) They are not, as documentation goes, light reading; but they are the closest thing the protocol has to a specification, and the bytes one sees on the wire match them with a fidelity one wishes were more common.</p>
]]></content:encoded></item><item><title>What the Benchmarks Don't Catch</title><link>https://mtclinton.com/posts/what-the-benchmarks-dont-catch/</link><pubDate>Tue, 26 May 2026 10:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/what-the-benchmarks-dont-catch/</guid><category>ai</category><description>On the widening gap between what the agentic-coding benchmarks report and what the working engineer experiences — the failure modes the scoreboards are structurally unable to register, and what one is obliged to read instead.</description><content:encoded>&lt;![CDATA[<p>The published benchmarks for agentic coding tools, taken at face value, describe a problem largely solved. SWE-bench Verified, the headline number against which the field measures itself, now sits comfortably above eighty-five per cent for the leading agents — with the latest preview model nudging ninety-four — and continues to climb; LiveCodeBench has saturated for most practical purposes; Aider&rsquo;s polyglot suite, designed to be hard, has been most of the way taken; HumanEval has been considered finished for so long that no one quoting it expects to be taken seriously. A reader who had only the scoreboards to go by would conclude that the engineering profession is past the interesting part of this transition and ought to be turning its attention to what to do with the freed hours. A reader who had spent the day actually using an agent on a real codebase would, after a moment, find that this conclusion did not quite match the evidence of the keyboard in front of them.</p><p>This post is a corrective to<a href="/posts/the-state-of-coding-may-2026/">yesterday&rsquo;s piece on the state of coding</a>, which surveyed the working day in May of 2026 without quite pausing on the question of what one ought to make of the numbers the tools advertise. The argument here is that there exists a real and widening gap between what the published benchmarks report and what working engineers experience using these tools, and that the gap is not closing — that it has, if anything, become harder to read in the direction the scoreboards are moving. The benchmarks are not lying. They are answering a question, with admirable precision, that is not the question the working engineer is in fact asking.</p><h2 id="the-numbers-as-published">The Numbers, As Published</h2><p>It is worth being precise about what the scoreboards measure, because the precision is the larger half of the trouble.</p><p>SWE-bench Verified, the most-cited number in this space, presents the agent with a real GitHub issue from one of a fixed pool of well-known Python repositories, together with the repository at the relevant commit. The agent is to produce a patch. The patch is then evaluated against a held-out test — a test the agent did not see — that the human who fixed the bug had originally written or modified. The agent&rsquo;s score is the fraction of issues for which the patch causes the held-out test to pass without breaking any others. The eighty-per-cent threshold was crossed by the leaders in late 2025; the current top scores sit in the high eighties and low nineties depending on the month and the configuration, with the trailing-twelve-month curve still pointing upward, if visibly flatter than it was. HumanEval, older and easier, asks the model to complete short isolated functions against unit tests; the leaders cleared ninety per cent some time ago. LiveCodeBench rotates competitive-programming problems through to defeat training-set contamination, and even on its hardest tier the frontier models clear half. Aider&rsquo;s polyglot benchmark — Exercism-style problems in six languages — has gone from a curiosity to a metric on which the leaders sit in the high eighties, in about eighteen months, though the leaders are still meaningfully separable on it.</p><p>These are, taken on their merits, real numbers reflecting real progress. The agents are doing things, on the precise tasks the benchmarks pose, that they could not do a year ago and that no one had any business expecting them to do two years ago. One should not be too quick to deride the scoreboards; they capture a genuine accumulation of capability, and the people building the benchmarks know perfectly well what they have built. The trouble is that the working engineer, after a day with the same tool that scored eighty-eight on SWE-bench Verified the week before, comes away with the distinct impression that the tool was not, in any honest accounting, nine-tenths of the way to having handled the day&rsquo;s work for them — that the experience and the score are describing two different objects entirely. The discrepancy is large enough to require an explanation, and the explanation is structural. The benchmarks are not catching certain things, and the certain things they are not catching are precisely the things production engineering is most made of.</p><h2 id="the-closed-world-problem">The Closed-World Problem</h2><p>The first and most consequential gap is the one that follows from the benchmark&rsquo;s own architecture, and one becomes aware of it the moment one tries to specify a real task to an agent.</p><p>A SWE-bench task is closed in three senses at once. The repository is small enough to fit in the agent&rsquo;s context — Django, scikit-learn, sympy, a couple of dozen others, each in the range of tens to low hundreds of thousands of lines. The issue is local — a regression in a particular module, a behaviour change in a particular function — and the patch that resolves it touches, on average, fewer than ten lines of code in fewer than three files. And the success criterion is a test that already exists, written by the engineer who originally produced the fix, sitting in a file the agent has been allowed to read or has been told the name of. The agent has only to find the right code to change and produce a patch that causes the named test to go from red to green.</p><p>A real engineering task is not closed in any of these senses, and the absence of closure is not a minor variation. Consider a recent task of my own — to add a new authentication path to a service that lives in a repository of perhaps a million lines, with several adjacent services in adjacent repositories that the new path will need to interoperate with, no existing test for the behaviour because the behaviour is new, and no clean specification of what<em>correct</em> would look like because the question of what<em>correct</em> means is precisely what most of the conversation with the product manager has been about. There is no held-out test. There is no module to look in. There is, instead, the open world: a system that has grown over six years, that has accumulated three competing conventions for how authentication is done in three different parts of the codebase, that has a deployment pipeline whose constraints are not written down anywhere, and a set of consumers whose expectations have to be inferred from the shape of the support tickets they have filed in the last quarter. The agent, presented with this task, can do something useful. It cannot do what the benchmark suggests it can do, because the benchmark has stripped out the parts of the problem the benchmark cannot represent.</p><p>The closed-world quality bleeds into a related and quieter failure: the<em>fixed-test trap</em>. In SWE-bench the agent passes by producing code that makes a specific predetermined test go green. In real production engineering, deciding what to test is one of the harder and more consequential parts of the work, and is itself a place where the agent&rsquo;s performance falls off a cliff that the benchmark cannot register. Ask an agent to fix a bug given the failing test and it will perform creditably; ask the same agent to determine what tests should exist for a new feature, and the suggestions one gets back are the suggestions of a smart undergraduate — coverage of the happy path, a couple of obvious error cases, nothing on the failure modes that a person who had lived with the codebase for two years would have known to fear. The benchmark, by handing the agent the test, has handed the agent the answer to a question that constitutes a substantial fraction of senior engineering judgment. One does not see this on the scoreboard. One sees it the first afternoon one asks the agent for a test plan.</p><h2 id="compound-failure-and-the-arithmetic-of-long-tasks">Compound Failure and the Arithmetic of Long Tasks</h2><p>The second gap is arithmetic and is, on reflection, the one most easily verified at one&rsquo;s own keyboard.</p><p>Most benchmark tasks are, in their internal structure, short. A SWE-bench task can be resolved by an agent in something between thirty seconds and a few minutes of wall-clock work, occupying perhaps five to fifteen tool calls. HumanEval problems are a single completion. Aider polyglot problems are a small handful of edits and a test run. The unit of evaluation is, in each case, a coherent piece of work that fits inside a single sustained pass and is scored on the artefact at the end.</p><p>The shape of real agentic work in 2026 is not this shape. A real task — refactor this subsystem, add this feature across the three services that touch it, migrate this schema and the dozen call sites that depend on it — decomposes, in the agent&rsquo;s actual execution, into something between ten and fifty sequential steps, each of which has its own success criterion and its own probability of getting it right. The arithmetic that follows is unfriendly. An agent that does each step correctly ninety per cent of the time has, over ten sequential steps, a success rate not of ninety per cent but of<em>thirty-five</em> per cent — and over twenty steps, twelve per cent. This is not a clever framing; it is the elementary product of independent probabilities, and it is what one sees in practice. The agent that handles every small benchmark task with fluent competence breaks down, on the larger end-to-end task, at a rate that the benchmark, with its single-step framing, simply does not see.</p><p>A benchmark could in principle be redesigned to test compound tasks, and one or two of the newer suites are beginning to try; but the difficulty of designing a fair multi-step benchmark is severe — each additional step expands the space of acceptable trajectories combinatorially, grading becomes harder, reproducibility suffers, and the question of<em>what counts as a step</em> is itself contested. The benchmarks that exist are accordingly predominantly single-shot, and the failure mode that dominates production agent use sits almost entirely off the scoreboard.</p><p>I caught a clean instance of this last week. The task was to extract a tangled piece of business logic from one service into a shared library, update the two consuming services to import from it, and migrate the test suites accordingly. The agent handled each of the eight sub-tasks I had identified with what looked, at the time, like ninety-per-cent competence. The end-to-end result was a pull request that built, passed its tests, and was, in three subtle places, wrong — wrong because at step four the agent had inlined a helper it had found inconvenient to import, and at step six had introduced a slight change in error-handling semantics it had judged immaterial, and at step seven had silently downgraded one of the test cases to skip rather than run. No individual step was a benchmark-style failure. The composition was.</p><h2 id="context-drift-over-long-sessions">Context Drift Over Long Sessions</h2><p>The third gap shows up only on tasks long enough to encounter it, which is to say almost never on the benchmarks and almost always in production. The benchmarks, by virtue of their single-shot framing, simply do not exercise the regime in which it appears.</p><p>What one observes, after perhaps thirty or forty tool calls in a single agent session — the threshold varies by model and by the density of the calls — is a degradation in coherence that has no analogue in shorter work. The agent begins to lose track of decisions made earlier in the session. A naming convention agreed upon at step five is quietly violated at step thirty-two. A design constraint stated at the outset —<em>do not introduce a new dependency on this module</em> — is forgotten in the natural flow of a refactor twenty minutes later. The agent&rsquo;s plan, examined three-quarters of the way through, no longer matches the plan it announced at the beginning, and the divergence has not been signposted; the agent does not announce that it has changed its mind, because from the agent&rsquo;s perspective it has not changed its mind. It is simply working from a working context that has, by then, only partial fidelity to the context the session began with.</p><p>The labs are aware of this. Context windows have grown; retrieval is being layered in over raw context; the better agents will, mid-session, summarise their own state and re-load the summary, which buys a useful margin. None of this has solved the underlying drift, because the drift is not a problem of nominal context length — the relevant facts are nominally still in the window — but a problem of the model&rsquo;s<em>attention</em> to the early context relative to the late context. The recency bias is structural; the prompt-engineering remedies are partial; and the working engineer has, by way of practical adaptation, learned to do what the benchmarks never require — to break a long task into separately-prompted shorter tasks, restating the relevant context each time, in order to avoid paying in the second half of a session for the drift that accumulated in the first. The agent that scored brilliantly on a benchmark where the task is over in five minutes has not been tested in the regime where this drift dominates, and the score has nothing to say about it.</p><h2 id="the-plausible-wrongness">The Plausible Wrongness</h2><p>The fourth gap is the one that has cost me the most personal time and that I have come to think is the most important of the four.</p><p>Benchmark tests have a property that production code does not have: they are decisive about whether the code is correct. A SWE-bench task succeeds or fails on whether the held-out test passes. The grading is binary; the answer arrives in seconds; the engineer is never left wondering whether the agent&rsquo;s output is good. In production, the equivalent decisiveness does not exist. An agent produces a patch. The patch compiles. The patch passes the tests one has thought to write. The patch reads, on careful inspection, as though it is doing the right thing. And the patch is, sometimes — by my own informal accounting, perhaps once in five sessions on a non-trivial task — wrong in a way that none of these checks have surfaced, and that is discovered, if at all, by a human three commits later.</p><p>The shape of the wrongness is the consistent thing. It is not the wrongness of code that does not work. It is the wrongness of code that<em>works for the case one looked at</em> and is silently incorrect for a case one did not. The agent has handled the obvious instance of the bug; it has not generalised the fix; the second instance, structurally identical, sits a hundred lines away and is not touched. Or the agent has fixed the symptom without locating the underlying cause; the test the agent added does pass, but it tests the symptom rather than the cause, and a different manifestation of the same cause will surface in a fortnight. Or the agent has made a subtle change in the semantics of a helper function — a default argument, an error-return convention, an implicit assumption about ordering — that is invisible at the call site the agent was working with and breaks a different call site that the agent did not think to look at.</p><p>This failure mode is, by its nature, expensive. It does not present immediately; it presents in a code review, or in production, or in a bug report from a customer. By the time it presents, the engineer who would have caught it on the keyboard has lost the context, the agent has moved on, and the recovery cost — find the regression, diagnose it, fix it, and decide what to do about the trust relationship with the agent — is many multiples of what the original task would have cost a human. The benchmark cannot see this at all, because the benchmark&rsquo;s test is exactly the test the agent&rsquo;s code passes. It is the unwritten test — the one a senior engineer would have known to write — that the code fails, and it is the unwritten test that does not exist in the benchmark&rsquo;s universe.</p><p>The honest name for this failure mode is<em>plausible wrongness</em>, and it is the characteristic failure mode of agent-assisted engineering in 2026. It is also the one the benchmark scoreboards are most catastrophically blind to. An agent that systematically produces plausibly-wrong patches will, on SWE-bench Verified, score within a few points of an agent that produces correctly-general patches, because the held-out test is too narrow an instrument to tell the difference. The two agents look the same on the scoreboard. They are not the same agent. The first is the one most engineers report having; the second is the one the scoreboards report on.</p><h2 id="what-this-is-not">What This Is Not</h2><p>One ought to be plain about what this is not.</p><p>It is not an argument that the benchmarks are useless. They are not useless. The relative ordering of agents on SWE-bench Verified does, in practice, correlate with the relative quality of the agents on production work, and the engineer choosing between two models is well advised to look at the score before they look at anything else. The benchmark is a lower bound on capability and a useful one. The argument here is that it is<em>only</em> a lower bound, and that the gap between the lower bound and the working reality is large, structurally produced, and not closing — and that the trade press and the labs themselves frequently elide this distinction in a way that misleads readers who have not used the tools at length.</p><p>It is not an argument that the benchmarks should be different than they are. Designing a benchmark that captures the closed-world failure, the compound-failure arithmetic, the context-drift regime, and the plausible-wrongness mode is, on inspection, very nearly impossible — each of these failure modes is hard to elicit in a controlled setting, hard to grade reproducibly, and hard to distinguish from noise on any individual run. The benchmarks measure what can be measured. One should not blame an instrument for not measuring what an instrument of that kind cannot measure. One should, however, remember its limits when interpreting its readings.</p><p>And it is not, finally, an argument that the agents are not working. They are working. The state-of-coding post made the case at length and I will not retract it here. The argument is narrower and more specific: the working engineer&rsquo;s day, on a complex task in a real codebase, is shaped substantially by the four failure modes above, none of which the published numbers see — and a reader who takes the numbers as a complete picture of capability will be exactly wrong, in the direction of overconfidence, by exactly the amount of the gap I am describing. That gap is the subject. It is not an argument against the technology; it is an argument against a particular and widespread misreading of it.</p><h2 id="what-one-is-obliged-to-read-instead">What One Is Obliged to Read Instead</h2><p>The structural facts come out, in order, as follows.</p><p>The first is that the benchmark scoreboards capture one shape of capability — the shape of capability one can verify with a held-out test on a closed, short, single-shot task — and have very little to say about the other shape, which is the capability to be useful across the open, long, compound work of a real engineering organisation. Both shapes are real. The first has been climbing for two years and continues to climb. The second has been climbing as well, but more slowly, less legibly, and along a curve that no one has published — because no one knows how to measure it, and the metric one would want does not yet exist.</p><p>The second is that the gap between the two has practical consequences. The engineer who buys the scoreboard reading buys, with it, a particular over-confidence about what the tool can be asked to do unsupervised, and pays for the over-confidence at the rate of the plausible-wrongness defects that survive their reviews. The engineer who reads only the scoreboard and not the experience reports — the developer-survey trust figures, the practitioner blog posts, the maintainers&rsquo; complaints about generated pull requests — is reading half the literature and is the engineer most likely to be surprised by the bill at the end of the quarter.</p><p>The third is the one I should like to leave plainly. The benchmarks describe what the agent can do<em>on the task the benchmark has fully specified for it</em>. The working engineer is in the business of specifying the task. The two are not the same activity, and the gap between them is precisely the gap between an instrument that can be measured and a skill that cannot. The scoreboards will keep going up. The skill will keep mattering. Anyone who reads the first as evidence about the second is reading a thermometer and reporting on the weather.</p>
]]></content:encoded></item><item><title>Louis XIV</title><link>https://mtclinton.com/posts/louis-xiv/</link><pubDate>Tue, 26 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/louis-xiv/</guid><category>antiques</category><description>Thirteenth per-subject post in Reading the Period Cabinet — the late-17th-c French royal cabinet under Louis XIV, the Manufacture Royale des Gobelins as state workshop, André-Charles Boulle's tortoiseshell-and-brass marquetry, chased gilt-bronze ormolu mounts, Le Brun and Berain as designers, and the Versailles-scale court patronage that opens the French royal furniture lineage of the blog.</description><content:encoded>&lt;![CDATA[<p>The post that preceded this one read the Spanish Baroque — dark walnut, hand-wrought iron, tooled leather, a severity chosen rather than forced upon it — and named, on either side of its central distinctions, the French royal cabinet of the same decades as the great opposite of the Spanish line: the splendour to Spain&rsquo;s austerity, the gilt-bronze to Spain&rsquo;s iron, the public magnificence to Spain&rsquo;s private restraint. This post is the post the Spanish Baroque kept pointing across the Pyrenees at. It opens the French royal lineage on the blog — a lineage the Louis XV, the Louis XVI, the Régence, the Empire posts have all leaned on at one remove — by going back behind every one of them to the reign in which that lineage was, quite deliberately and quite politically, invented.</p><p>This is not the earliest French furniture. But it is the period in which the French cabinet became<em>French</em> in the sense the rest of Europe would thereafter recognise: an industrial product of a state workshop, a designed and not merely a made thing, monumental in scale, of an opulence sustained at the state&rsquo;s expense and at the state&rsquo;s command. The Louis XIV cabinet is the furniture of a regime, and the regime knew that the cabinet was part of how it ruled.</p><p>This is the thirteenth post in<em>Reading the Period Cabinet</em>. As with the Italian Renaissance, the Italian Baroque, and the Spanish Baroque before it, it is a taxonomy post — a description of a type and of the evidence by which one reads it. Its type-specimen is the<em>bureau Mazarin</em>, the eight-legged writing desk that names a chief minister and consolidates the period&rsquo;s whole vocabulary into a single object; its load-bearing distinction is the<em>industrialised gilding-and-marquetry combine</em> — Boulle marquetry and chased ormolu produced at scale by the Manufacture Royale — that no other seventeenth-century tradition matched; and its antecedent is the Italian Baroque, which Louis XIV&rsquo;s ministers brought across the Alps as a matter of policy and then taught the French workshops to outdo.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Louis XIV piece is the<em>bureau Mazarin</em> — the writing desk on eight legs that became, late in the reign, the form in which the whole vocabulary of the tradition was most fully concentrated. It is canonical for the same reason the vargueño was canonical for the Spanish Baroque and the stipo for the Italian: it presents every register the period worked in. The veneer, the marquetry, the ormolu, the moulded scale, the architectural legs, the figural ornament at the angles — all of it is in the one form, and a collector who has learned to read a good bureau Mazarin has nearly learned to read the reign entire.</p><p>It is a desk and not a cabinet: a rectangular case of three drawers, raised on<em>eight legs</em> arranged as two banks of four, with a kneehole between them and a stretcher tying each bank. The eight-legged disposition is itself diagnostic — nothing else in the seventeenth-century European cabinet repertory presents itself in quite this way. The case is not painted. It is<em>veneered</em>, and that veneer is the surface on which every other register is composed.</p><p>The veneer, on the apex examples, is Boulle marquetry — the technique that more than any other material distinguishes the Louis XIV piece from every Continental neighbour.<em>André-Charles Boulle</em> (1642–1732), royal cabinet-maker under warrant from 1672, perfected the practice of veneering a case in two materials simultaneously: tortoiseshell and thin sheet brass, glued as a pack, cut by hand with a fret-saw to the same arabesque, and separated into two complementary sheets. The shell-ground is<em>première-partie</em>; the brass-ground is<em>contre-partie</em>; the two are used on facing pieces of a pair so that no cutting is wasted. The pattern is the arabesque drawn from the court ornemanistes&rsquo; engraved plates: a glittering pictorial composition in dark and gold, the most precise hand-work the seventeenth-century decorative arts could produce.</p><figure><img src="/images/posts/louis-xiv/detail-boulle.png" alt="A close detail of Louis XIV Boulle marquetry — tortoiseshell-and-brass arabesque inlay, the première-partie register against which the contre-partie is cut"><figcaption><p>A close detail of Boulle marquetry — the tortoiseshell-and-brass arabesque inlay that names André-Charles Boulle (1642–1732). The shell-ground is<em>première-partie</em>, the brass-ground is<em>contre-partie</em>; the two are cut from a single layered pack with a fret-saw and used on a pair or on opposing faces. The pattern is the arabesque of Jean Berain, executed at the Manufacture Royale.</p></figcaption></figure><p>The ormolu mounts, second.<em>Ormolu</em> —<em>bronze doré</em> — is cast bronze, hand-chased, and fire-gilt by the mercury-amalgam process. The Louis XIV piece carries mounts at every structural point: corner mounts, escutcheons, mascarons on the rails, capitals and bases at the legs, sabots at the feet; on the apex pieces the mounts go beyond hardware into figural sculpture — putti, allegorical figures, the royal sunburst, the interlaced<em>L</em> of the king&rsquo;s cypher. They are not, as on a Spanish piece, hammered iron left frankly visible, nor, as on an Italian piece, gilded carved wood softer than metal. They are cast bronze, fire-gilt to a hard durable gold — and the combination was, in the seventeenth century, more expensive than the case itself.</p><figure><img src="/images/posts/louis-xiv/detail-ormolu.png" alt="A close detail of Louis XIV chased gilt-bronze ormolu mounts — a figural mascaron, escutcheon, or corner-mount in fire-gilt bronze"><figcaption><p>A close detail of chased gilt-bronze ormolu — a Louis XIV figural mount in<em>bronze doré</em>, cast, hand-chased, and fire-gilt by the mercury-amalgam process. The mount passed through the hands of a sculptor, a founder, a chaser, and a gilder before it reached the cabinet-maker — the whole sequence coordinated by the Manufacture Royale.</p></figcaption></figure><p>The veneer ground, where the piece is not in Boulle, is<em>ebony</em> or<em>ebonised pearwood</em> — the dark exotic timber that lent the French word<em>ébéniste</em> its name. On the largest of the early commissions — the great cabinets-on-stand the period produced before the bureau Mazarin took over as the canonical form — the ebony case is supported on a<em>carved giltwood stand</em> of Atlantes, putti, or scrolling consoles, the register borrowed wholesale from the Italian Baroque. The Manufacture Royale produced these carved-giltwood stands concurrently with the Boulle cases that would, by the end of the reign, supplant them.</p><figure><img src="/images/posts/louis-xiv/detail-gilding.png" alt="A close detail of Louis XIV carved-and-gilded stand or pier — water-gilt carved wood over a gessoed bole ground, the architectural-furniture gilding register"><figcaption><p>A close detail of carved-and-gilded woodwork — a Louis XIV pier-glass frame or supporting Atlantes, water-gilt over a gesso-and-bole ground in the architectural register the<em>menuisiers</em> and<em>doreurs</em> practised in parallel with the ébénistes. The carved-giltwood register is the inheritance from the Italian Baroque; the apex Versailles commissions combined the two on a single piece — a Boulle case on a carved-and-gilded stand.</p></figcaption></figure><p>The whole is monumental. The great commissions — Boulle&rsquo;s<em>armoires</em>, the medal-cabinets, the<em>bibliothèques</em> for the king&rsquo;s<em>cabinet du conseil</em> — run to a scale at which the piece functions as architecture as much as furniture. A piece sized for a Parisian apartment would have looked, in the Galerie des Glaces, like an apology. The period made no apologies.</p><h2 id="the-evidence">The Evidence</h2><p>The wood, first. The structural carcass is<em>oak</em> — French oak, hand-cut, never meant to be visible. The Louis XIV case is veneered; the surface is<em>ebony</em> or<em>ebonised pearwood</em> on the plain-ground pieces,<em>tortoiseshell-and-brass</em> on the Boulle pieces. On the carved-giltwood stands and pier-frames the wood is<em>limewood</em> or<em>poplar</em>, gessoed, bole-grounded, and water-gilt in the architectural register the same studios applied to the chapel and ceiling work at Versailles.</p><p>The Boulle marquetry, second, is most of what one is reading for at close range. The materials should be real tortoiseshell — warm translucent, period brown-to-red mottling — set against real cast-or-rolled sheet brass, cut by hand so that the joint reads as a fine hairline rather than a machined edge. The brass should carry hand-engraved internal detail the nineteenth-century revival did not consistently reproduce; the shell is often backed with red foil to enliven the translucence; the pattern is the Berain arabesque, not the later asymmetric scrolling.</p><p>The ormolu, third. Mounts should be fire-gilt by the mercury process — a soft warm yellow durable enough that the apex Versailles commissions still carry their original gilding after three centuries — not the thin electroplating that supplanted mercury gilding in the nineteenth century. The bronze should be hand-chased; the chasing on a period piece carries the slight irregularities of hand-work the late-nineteenth-century reproductions do not.</p><p>The constructional indicators, fourth, are what one reads against the nineteenth-century revival, which produced Boulle-and-ormolu in such quantity and to such quality that period attribution is the working question on most pieces. Carcass joinery should be hand-cut; the marquetry glued with hide-glue (which carries its own seasonal lift at the inlay edges); and the underside of the piece — least retouched — preserves the original tool-marks and is where dating is most reliably argued.</p><figure><img src="/images/posts/louis-xiv/pattern-book-page.png" alt="A plate from Jean Berain or Charles Le Brun — engraved arabesque ornament for the royal manufactures, the design source for Boulle marquetry of the period"><figcaption><p>A plate of engraved ornament after Jean Berain (1640–1711) — the principal<em>ornemaniste</em> of the late reign, whose arabesque-and-grotesque vocabulary the Manufacture Royale executed in marquetry, tapestry, and gilt bronze. The Louis XIV cabinet trade is, in this sense, a<em>designed</em> trade — its surfaces the executed form of an engraved ornamental project at the centre of the court.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Louis XIV period, as a furniture period, runs from about 1660 — the year the young king began to govern personally after Mazarin&rsquo;s death — to about 1715. The decisive decades are the 1660s through the 1690s, when the Manufacture Royale&rsquo;s industrial machinery was at full operation. The state workshop is the load-bearing institution. Colbert — controller-general of finances and architect of the mercantilist policy that organised French manufacturing under state direction — acquired in 1662 the existing dyeing-works on the Bièvre in the Faubourg Saint-Marcel of Paris, the site of the fifteenth-century dyer Jean Gobelin whose family name it had carried ever since, and reorganised it into what would become the<em>Manufacture Royale des Meubles de la Couronne</em>, known thereafter as<em>the Gobelins</em>: a state-owned multi-trade workshop that gathered under one roof the tapestry-weavers, cabinet-makers, bronze-founders, gilders, and sculptors whose combined output furnished the royal palaces. The combined-trade arrangement was the period&rsquo;s industrial innovation, and the Louis XIV cabinet bears its signature: a single piece carried the work of half a dozen specialised trades, coordinated and centrally designed. This is not Italian Baroque, in which the workshop bought its pietra-dura top in Florence and its stand in Bologna and mounted the two as separate procurements. It is industrial production at state scale.</p><p>The designers must be named because the design is the load-bearing intellectual content.<em>Charles Le Brun</em> (1619–1690), named<em>Premier peintre du Roi</em> in 1662 and confirmed in the office in 1664, and director of the Gobelins from 1663, set the iconographic programme — the Apollo iconography, the king-as-Sun.<em>Jean Berain the Elder</em> (1640–1711), at the<em>Menus-Plaisirs du Roi</em>, was the<em>ornemaniste</em> whose engraved arabesques became the vocabulary the cabinet, tapestry, and bronze workshops all executed from.<em>Daniel Marot</em> (1661–1752), a Huguenot in the Berain register, carried that vocabulary to the Netherlands and England after the Revocation of the Edict of Nantes in 1685 — which is how William-and-Mary late-Baroque came to look so substantially French. The antecedent was the<em>Italian Baroque</em>, and the inheritance was deliberate: the young Louis, on Colbert&rsquo;s advice and Le Brun&rsquo;s design, set out to make Versailles outdo Rome — importing Italian artists wholesale into the French workshops and teaching them to produce, in industrial quantity, what the Italians had produced at apex-piece scale only. The French innovation was a scale innovation and a technical-register one: Boulle marquetry the Italians had not consolidated, ormolu they had executed only sparingly, the whole produced at Manufacture-Royale scale rather than single-master-workshop scale. The Italian Baroque is the antecedent in the strong sense: not what Louis XIV imitated, but what it set out to surpass.</p><figure><img src="/images/posts/louis-xiv/antecedent.png" alt="An Italian Baroque stipo of the mid-17th c — the immediate antecedent the Louis XIV state workshop set out to surpass, with carved-and-gilded woodwork and pietra-dura panels"><figcaption><p>A mid-17th-c Italian Baroque stipo — the immediate antecedent, with carved-and-gilded woodwork and a Florentine pietra-dura panel on the case. The Louis XIV piece is the Italian Baroque carried to a different scale by a different institution: Italian artists imported into the French workshops, Boulle and ormolu added on, the whole coordinated by a single state workshop.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four styles stand near enough to Louis XIV that the beginner confuses them with it. Two are seventeenth-century Continental siblings — the Spanish Baroque and the Italian Baroque, contemporaries answering the same century in different national registers. Two are nearer relations of the French line itself — the<em>Régence</em>, the transitional regency that carried Louis XIV into Louis XV, and the<em>William-and-Mary English</em>, the cross-Channel cousin that adapted the French royal vocabulary for a Protestant northern court. To distinguish the four is to fix what is particular to the Louis XIV line.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/louis-xiv/sibling-spanish-baroque.png" alt="A Spanish Baroque vargueño — dark walnut, iron studs, tooled leather, and bone-and-ivory geometric inlay" loading="lazy"/><figcaption>Spanish Baroque<em>— the Iberian sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xiv/sibling-italian-baroque.png" alt="An Italian Baroque stipo — carved-and-gilded woodwork and Florentine pietra-dura, the tradition Louis XIV set out to surpass" loading="lazy"/><figcaption>Italian Baroque<em>— the Continental antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xiv/sibling-regence.png" alt="A French Régence commode under the regency of 1715–1723 — lighter proportions, early rocaille ornament, the bombé front beginning to appear" loading="lazy"/><figcaption>Régence<em>— the transitional French descendant</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xiv/sibling-william-and-mary.png" alt="A William and Mary English cabinet — dark walnut with seaweed marquetry, bun feet, and turned columnar legs" loading="lazy"/><figcaption>William & Mary English<em>— the Anglo-Dutch cousin</em></figcaption></figure></div><figcaption>Four styles most often confused with Louis XIV, drawn for comparison.</figcaption></figure><p>A<em>Spanish Baroque</em> piece is the Iberian sibling and the easiest to tell apart, because it states almost the opposite case. Plain dark walnut, hand-wrought iron, tooled leather, bone-and-ivory geometric inlay, richness reserved for the inside of the fall-front; the Louis XIV piece is Boulle, gilt bronze, ebony, and figural ornament, richness conspicuous on every face. Both were absolutist-court styles. The two courts could hardly have furnished themselves more differently.</p><p>An<em>Italian Baroque</em> piece is the Continental antecedent, and the difficulty is precisely that Louis XIV inherited so much of it. The Italian piece is carved walnut with carved-and-gilded structural members and, on the apex pieces, Florentine pietra-dura tops; the Louis XIV piece carries the gilded-structural register on its stands but layers onto it the Boulle marquetry and ormolu the Italians had not consolidated. The Italian gilds the carved wood and lets the case remain walnut; the French veneers the case in tortoiseshell-and-brass and bolts gilt bronze onto every structural angle.</p><p>A<em>Régence</em> piece is the transitional French descendant — under the regency of Philippe d&rsquo;Orléans, 1715–1723 — and carries most of the Louis XIV vocabulary still. The decisive differences are proportional and ornamental: the case lightens (the bureau Mazarin&rsquo;s eight legs reduce to four, the heavy stretchers fall away, proportions soften toward the<em>commode</em> and the<em>bureau plat</em>); the symmetrical Berain arabesque gives way to the first asymmetric foliate ornament that will become the rocaille; the ormolu thins. Heavy, symmetrically arabesqued, on eight legs with deep stretchers is Louis XIV; lighter and four-legged is Régence.</p><p>A<em>William-and-Mary English</em> piece is the Anglo-Dutch cousin — produced for the joint Protestant monarchy of William III and Mary II (1689–1702) — and the cross-Channel relationship is direct enough to be confusing. Daniel Marot carried the Louis XIV vocabulary north after the Edict of Nantes&rsquo; revocation. The William-and-Mary case is in the same family — late-Baroque, marquetry-and-mount — but executed in dark walnut rather than ebony, in<em>seaweed marquetry</em> of box-and-holly rather than tortoiseshell-and-brass Boulle, with bun feet or turned columnar legs rather than the eight-legged Mazarin disposition, and with brass hardware at restrained scale rather than figural cast ormolu.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>form</em>, because with the Louis XIV piece the form is unusually diagnostic. The bureau Mazarin&rsquo;s eight-legged disposition — two banks of four legs flanking a kneehole, tied by stretchers — is so particular that the form alone places a piece in late-seventeenth-century France. The great cabinet-on-stand on carved-giltwood Atlantes or scrolling consoles is the second canonical form. A piece at this scale, in seventeenth-century materials, is almost certainly French royal.</p><p>One looks next, and most carefully, at the<em>Boulle marquetry</em> where it is present — the load-bearing authentication question. Both<em>première-partie</em> and<em>contre-partie</em> are period; their use on pairs is itself a positive indicator. The indicators against the nineteenth-century revival are hand-engraved internal detail in the brass, a hand-cut hairline joint between shell and brass, hide-glue&rsquo;s seasonal lift at the edges, and red foil sometimes backing the shell.</p><p>One looks then at the<em>ormolu</em>. Mercury-gilt, hand-chased mounts with hand-cut slotted backing screws is the period combination; thin electrogild on unchased bronze with machine screws is the reproduction. On an apex piece the mounts go figural — mascarons, putti, allegorical figures, the royal cypher.</p><p>And one looks, finally, at the<em>combination</em>. A genuine Louis XIV piece brings together monumental scale, an oak carcass of hand-cut joinery, an ebony or Boulle veneer, fire-gilt ormolu at every structural angle, and the arabesque vocabulary of Berain and Le Brun; on the apex examples, a carved-and-gilded stand inherited from the Italian Baroque. Any one of these may appear elsewhere; the four or five together, at the scale Versailles required and through the industrial coordination of the Manufacture Royale, appear only here. The collector reads case, veneer, mount, and gilding not as a checklist but as the evidence of a single workshop tradition operating at state scale — and asks of the word<em>Baroque</em> what, in the French case, it must be made to mean: not the carved exuberance of Rome, not the iron austerity of Castile, but the industrial magnificence of Versailles, splendour produced at state scale by a state workshop on a state mandate, every face elaborated and every angle gilded.</p><p>The next post in the furniture arc will be either<em>Régence</em> — to extend the French royal lineage into the transitional regency under Philippe d&rsquo;Orléans — or<em>William-and-Mary English</em>, to open the Anglo-Dutch late-Baroque cousin with the seaweed-marquetry register the Marot plates carried across the Channel. The choice will depend on what photographic material is available.</p>
]]></content:encoded></item><item><title>Shirvan</title><link>https://mtclinton.com/posts/shirvan/</link><pubDate>Tue, 26 May 2026 09:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/shirvan/</guid><category>antiques</category><description>Thirteenth per-subject post in Reading the Antique Rug — the eastern Caucasian region of Shirvan along the western Caspian coast, with dark navy ground, fine low pile, and small-scale repeat compositions distinct from the broad geometric drawing of the southern Caucasus.</description><content:encoded>&lt;![CDATA[<p>The twelfth post in this arc treated Karabagh, and it spent most of its account holding two things together: a tribal-geometric tradition and a borrowed French floral one, both unmistakably Caucasian beneath the pile. Its closing line named Shirvan and Kuba as the two rugs that might come next, and the choice has fallen on Shirvan — partly because the photographic material was to hand, and partly because the natural movement of the account is eastward, out of the southern mountains and along the western shore of the Caspian, where the loom narrows, the pile drops, and the great medallion gives way to a far quieter habit of drawing. This is the thirteenth post in<em>Reading the Antique Rug</em>. It treats Shirvan in the position the arc has reserved for it: the region along the western Caspian coast in what is now Azerbaijan, south of the Greater Caucasus range with Baku at its eastern edge, that produced the most-collected of the eastern Caucasian rugs and the principal foil to the burgundy-and-rose tradition the prior post described.</p><p>The Shirvan is, of all the Caucasian types, the one a collector is most likely to meet and the one most often misread on first meeting. It is misread because it does not announce itself the way the southern Caucasian rugs do. The Kazak shouts; the Karabagh sings; the Shirvan murmurs. It is a small rug, more often than not, and its design is correspondingly small — organised not around the single stepped medallion the southern rugs hang their composition on, but around a quiet field of repeats: small star medallions, S-form devices, scattered geometric motifs, set into a dark ground at a density the eye must close on before the pattern resolves. One has to step nearer. That habit of approach is the first thing this post is asking the eye to learn, and most of the rest follows from it.</p><h2 id="the-specimen">The Specimen</h2><p>A Shirvan one encounters on the open market is, in the great majority of cases, a nineteenth-century or early-twentieth-century village rug of moderate proportions — a scatter rug perhaps four by six feet, a prayer rug of similar reach, or a long narrow runner. Room-sized Shirvans exist, but they are not the type-defining specimen; the type is keyed to the small piece. The first thing to settle, before any motif is read, is the ground, because the Shirvan ground is the type&rsquo;s signature in the way burgundy was Karabagh&rsquo;s and brick-red was Heriz&rsquo;s. It is, with great reliability, a dark navy — a deep indigo, nearly black at a distance and resolving into the saturated mid-blue of the dye only on close approach. The southern Caucasian rugs run red; the eastern Caucasian rugs run dark blue. The rule is not absolute (a Shirvan on ivory exists; a Shirvan on madder exists), but the canonical Shirvan is navy, and the navy field is the first thing to look at and the first thing to verify.</p><p>Against that dark ground the design is drawn in the eastern Caucasian register. Where the Kazak set a great stepped medallion on a saturated red and the Karabagh hung a French rose-bouquet on burgundy, the Shirvan does neither. The field is broken into a repeat of small motifs in regular ordering — small star medallions, eight-pointed or stepped; S-form devices, the running curl the trade has variously called the<em>running dog</em>; little geometricised flower-heads; the occasional botanical<em>boteh</em>; on the prayer rugs, a directional niche at one end and a lamp suspended within it. The drawing is finer than anything the southern Caucasus produced, for the same reason the pile is lower and the knot closer: the Shirvan weaver, working eastward toward the Persian world, drew at a register the southern loom did not attempt.</p><figure><img src="/images/posts/shirvan/detail-medallion.png" alt="A close detail of a Shirvan star medallion and S-form repeat — small-scale eastern Caucasian devices on dark navy ground"><figcaption><p>A close detail of a Shirvan field — small star medallions and S-form devices set into the dark navy ground, drawn at the fine register the eastern loom is keyed to.</p></figcaption></figure><p>The palette completes the specimen. Where the design picks up colour, it picks it in clear small touches — ivory, a clean madder-red, a soft orange-rust, a pale green, a single saffron note — set against the dark field in a contrast the eye reads at first as restraint and on longer attention as great variety held to small extent. The Shirvan is not polychrome the way an Anatolian village rug is; it is a quietly-coloured rug in which a half-dozen distinct hues each occupy a small part of the field. That distribution — many colours, each in small motifs, on a dominant dark ground — is the visual signature, and it is one to recognise across the sub-types the trade names by village (<em>Marasali</em>,<em>Bidjov</em>,<em>Akstafa</em>,<em>Chajli</em>, and several more), all of which sit beneath the Shirvan label and share the navy ground and the small-scale habit.</p><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence, and for the Shirvan it confirms what the design has already suggested.<em>The Shirvan is woven on a wool foundation</em>, generally with a wool warp and a wool weft, though one encounters a cotton weft now and then on late-nineteenth-century export pieces. The warp is wool with great regularity. One turns the rug over, parts the pile at a worn place, or reads the warp at the fringe — and the threads are wool. A wool warp with a navy field is pointing to the eastern Caucasus; a cotton warp with a similarly dark field is pointing, very probably, to Bidjar or another similarly-dyed Persian district, and the foundation alone settles the question before any motif is read.</p><figure><img src="/images/posts/shirvan/detail-foundation.png" alt="A close detail of a Shirvan knot-back — wool warp, wool weft, symmetric knot at the fine eastern Caucasian density"><figcaption><p>A close detail of the back of a Shirvan — the wool warp and wool weft, the symmetric knot at the fine eastern Caucasian density that separates Shirvan from the looser tying of the southern Caucasus.</p></figcaption></figure><p>The knot is the second piece of structural evidence, and it is where the Shirvan separates itself most cleanly from its southern neighbours. The knot is symmetric — the Turkish knot, used uniformly across the Caucasian and Anatolian world — and that the Shirvan shares with every other rug in the family. What is not shared is the density. The Kazak runs coarse; the Karabagh moderate; the Shirvan is finer than either, between 90 and 160 knots per square inch on a good piece. The consequence is the second feature the rug declares at once:<em>the pile is low</em>. One sets a hand on a Shirvan and feels not the shaggy long pile of the highland Kazak nor the medium clip of the Karabagh, but a short, close, almost flat pile a careless eye may at first mistake for wear. It is not worn. It is woven that way.</p><figure><img src="/images/posts/shirvan/detail-border.png" alt="A close detail of a Shirvan kufic main border — angular script-derived geometric repeat"><figcaption><p>A close detail of a Shirvan main border — the kufic-script-derived repeat, the angular geometricised letterforms that distinguish the eastern Caucasian border vocabulary from the floral and stepped-polygon borders of the south.</p></figcaption></figure><p>The borders complete the structural evidence, and the principal one to learn on a Shirvan is the<em>kufic</em> border — a repeating angular device the trade called kufic because it resembles, at a sufficient remove, the angular Arabic letterforms of the early Islamic Kufic script. Whether the resemblance is historically traceable or merely coincidental is a question the literature has not entirely settled, but the device is unmistakable in the rug: a regular series of geometric stems and uprights set at right angles to each other and repeated along the border, reading at a little distance as a written line. Not every Shirvan carries one, but it is among the most diagnostic of the eastern Caucasian devices, and the southern Caucasian rugs simply do not produce it. A Caucasian rug with a kufic border is, with high probability, an eastern one — and most often a Shirvan or a Kuba.</p><h2 id="the-period">The Period</h2><p>Shirvan is a region, not a town. It lies along the western shore of the Caspian, south of the Greater Caucasus range proper and reaching down to the Kura, with Baku sitting at its eastern edge on the Apsheron peninsula — the coastal plain and low foothills of what is now central and eastern Azerbaijan, country crossed by every imperial power that has reached the Caspian and that has, for that reason, woven for a great variety of customers over a great length of time. The Shirvanshahs ruled here from the ninth century to the sixteenth; the Safavids absorbed the region; the Russians took it, with the rest of the eastern Caucasus, by the Treaties of Gulistan (1813) and Turkmenchay (1828) — the same annexation that pulled Karabagh out of Persian hands and into the Russian commercial orbit. The dating matters, because the Shirvan one collects today is, almost without exception, a post-1828 rug, woven for a market made up partly of the local trade, partly of the Russian one, and partly of the European export buyers who reached Baku in serious numbers in the second half of the nineteenth century.</p><figure><img src="/images/posts/shirvan/antecedent.png" alt="A pre-19th-c Shirvan village rug — looser drawing, more variable palette, the older tradition before the export market regularised production"><figcaption><p>A pre-19th-c Shirvan village rug — the older eastern Caucasian tradition before the post-1828 Russian-mediated export market regularised village production. The drawing is looser, the palette more variable, the conventions less standardised than the canonical nineteenth-century Shirvan that grew out of it.</p></figcaption></figure><p>The export trade had two consequences, both visible in the rugs themselves. The first was a regularisation of design: the village conventions, individual before the trade, became more uniform under it, and the canonical Shirvan vocabulary one now describes is in part the vocabulary the market settled on. The second was the steady production of the prayer-rug format, which had always been woven in the eastern Caucasus but which the trade favoured particularly — for its smaller size and for the legibility of its directional design to buyers unfamiliar with the wider Caucasian repertoire. A great many of the prayer rugs the collector now meets under the Shirvan label were woven specifically for sale, and the conventions were honed accordingly.</p><p>The early twentieth century brought the decline that came to most of the regional weaving districts. The collapse of the Russian Empire, the establishment of Soviet Azerbaijan, and the Soviet reorganisation of the looms into managed production ran across the Shirvan tradition in succession, and the old village independence was, by mid-century, essentially over. Shirvan-design rugs continue to be made; some are made well. But the type as the collector knows it is a nineteenth-century type, woven under one specific commercial arrangement in one specific imperial frame, and the period of the great Shirvan is the period between roughly 1830 and 1910.</p><figure><img src="/images/posts/shirvan/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the eastern Caucasian region — Shirvan / Kuba / Daghestan / Baku"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the eastern Caucasian region — a district map locating Shirvan, Kuba, Daghestan, and Baku along the western Caspian, with archetype drawings of the four sub-types arranged for comparison.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/shirvan/sibling-kuba.png" alt="A Kuba rug — eastern Caucasian neighbour to Shirvan, with even finer knot density and the dense allover small-pattern composition that distinguishes Kuba from the medallion-based repeats of Shirvan" loading="lazy"/><figcaption>Kuba<em>— the eastern Caucasian neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/shirvan/sibling-daghestan.png" alt="A Daghestan rug — northeastern Caucasian prayer-rug type with pale ivory ground and the regular diamond-lattice composition, distinct from the dark-ground field of Shirvan" loading="lazy"/><figcaption>Daghestan<em>— the prayer-rug northeastern type</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/shirvan/sibling-kazak.png" alt="A Caucasian Kazak rug — the southern Caucasian highlands tribal weaving with saturated tomato-red ground, bold large stepped geometric medallions, and shaggy long pile, distinct from the small fine eastern Caucasian register of Shirvan" loading="lazy"/><figcaption>Kazak<em>— the southern Caucasian highlands tribal</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/shirvan/sibling-karabagh.png" alt="A Karabagh rug — mountainous southern Caucasian with deep burgundy ground and either bold stepped medallions or French-rose floral vocabulary, distinct from the dark navy small-repeat register of Shirvan" loading="lazy"/><figcaption>Karabagh<em>— the mountainous southern Caucasian</em></figcaption></figure></div><figcaption>Four Caucasian types most often confused with Shirvan, drawn for comparison.</figcaption></figure><p>The four types set against the Shirvan in the plate are all Caucasian, all woven on the wool foundation at the symmetric knot — so neither the broad region nor the structural family will separate them. The practised eye separates them instead by reading the palette of the ground, the scale at which the field is drawn, and the density to which the knot is tied. The working rule for the eastern Caucasus is one the Karabagh post stated for the south and this post can now extend:<em>the Shirvan is the eastern type in which a dark navy ground, a small-scale repeat, and a fine low pile are all to be found together</em>.</p><p>A<em>Kuba</em> is the comparison that does the most work, because Kuba is the Caucasian rug nearest to Shirvan in everything that matters. Both are eastern Caucasian; both are woven on wool foundations; both run to a dark ground; both are tied at a fine knot count and clipped low. The separation is compositional. The Shirvan organises its field around a repeat of distinct motifs with breathing room between them, and the eye reads it as a series of legible figures. The Kuba goes one step further toward density: its field is the<em>dense allover</em>, a surface covered edge to edge with a tight repeating motif, read not as figures but as a continuous texture. A dark-ground eastern rug with breathing space between its motifs is Shirvan; one with no breathing space at all is Kuba.</p><p>A<em>Daghestan</em> moves the comparison farther north and changes the format. Daghestan is the northeastern Caucasian type most associated with the prayer-rug format, and the canonical Daghestan is a pale-ground prayer rug — an ivory or light field carrying a regular diamond lattice of small flower-heads, with the prayer-niche at one end. A<em>pale-ground</em> lattice prayer rug from the northeast is a Daghestan; a<em>dark-ground</em> prayer rug from the same region — and many Shirvans are prayer rugs — is much more probably a Shirvan. Both types weave prayer rugs; only one weaves them on navy.</p><p>A<em>Kazak</em> carries the comparison south into the highlands, and the separation here is the easiest of the four. The Kazak is a large-scale tribal rug — bold stepped medallions, saturated tomato-red ground, shaggy long pile, coarse symmetric knot — and the Shirvan is its opposite at every point. A bright red highland rug at coarse scale is Kazak; a dark navy coastal rug at fine scale is Shirvan. The two stand at opposite ends of the Caucasian register.</p><p>A<em>Karabagh</em> is the type the most recent post described, and it is included here because the Karabagh is the rug a collector is most likely to be looking at<em>just before</em> meeting a Shirvan — and the eye should not carry the prior reading into the new one. Burgundy with roses or large medallions is Karabagh; navy with small star-and-S repeats is Shirvan. The two share a region, an annexation date, and an export market; they share almost nothing else.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Shirvan comes down, as in the prior rug posts, to a short ordered checklist — and because the Shirvan is the quiet type, the checklist must respect a discipline of its own: one must approach the rug closely. A Shirvan does not read from across the room. The first move of the eye is therefore a move of the body. One steps in.</p><p>One looks first at the<em>ground</em>. A Shirvan field is dark navy, with great regularity, and the navy is the single fastest piece of attribution the rug offers. A Caucasian rug on a dark navy ground is already pointing eastward at one glance, and away from every southern and highland district. The navy is the rug&rsquo;s first declaration, and one should not pass it by simply because dark grounds do not catch the eye the way red ones do.</p><p>One looks next at the<em>scale of the drawing</em>. The Shirvan field is built of small motifs in regular repeat, not a single great medallion. A dark-ground rug carrying a large stepped medallion is pointing somewhere else — perhaps to a Karabagh, perhaps to a darker-palette Kazak — and is almost certainly not Shirvan. A dark-ground rug whose field is a regular series of small star medallions, S-forms, geometricised flower-heads, or a directional prayer-niche of similarly small scale, is the Shirvan field.</p><p>One looks next at the<em>foundation and the knot</em>. One turns the rug over, reads the warp at the fringe, and confirms two things at once: that the foundation is wool (placing the rug in the Caucasian family and not the cotton-warp Persian one) and that the knot is tied finely (placing it in the eastern Caucasus and not the south). A wool foundation at 90 to 160 knots per square inch, with a low close pile, is the eastern register; a wool foundation at 30 to 60 knots with a shaggy pile is the highland one. The single difference of density does most of the remaining attributing work.</p><p>One looks, last, for the<em>coherence of the whole</em>. A navy ground carrying a small-scale repeat of geometric motifs, drawn at the fine eastern Caucasian register, on a wool foundation at fine knot count, with a low pile that announces the type before any wear is read for age — and a kufic main border, where present, settling the matter at a stroke. Where those observations land together, the rug is Shirvan. Where any one is in serious dispute — a bright red ground, a single great medallion, a cotton warp, a shaggy long pile — the attribution is wrong, and the rug belongs elsewhere in the family. The Shirvan is the eastern coastal type, the small fine rug, the quiet rug of the Caucasian tradition; once the eye learns to step in close to it, the rest follows.</p><p>The next post in the rug arc will be either<em>Kuba</em> — to extend the eastern Caucasian into the dense-allover composition that presses the small-repeat habit to its limit — or<em>Daghestan</em>, to continue the eastern Caucasian arc with the pale-ground prayer-rug variant. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>One Year Out</title><link>https://mtclinton.com/posts/one-year-out/</link><pubDate>Mon, 25 May 2026 11:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/one-year-out/</guid><category>ai</category><description>A deliberately aggressive set of falsifiable predictions for where artificial intelligence and the industry around it will stand by roughly May of 2027, each claim carrying its own reasoning and its own concession.</description><content:encoded>&lt;![CDATA[<p>A forecast is a wager dressed in argument, and the honest forecaster owes his reader two things: the date on which the wager can be settled, and an account of why he is willing to make it. What follows is a set of predictions about where artificial intelligence and the industry around it will stand in roughly twelve months — by about May of 2027. They are deliberately aggressive. A cautious observer, surveying the same evidence, would call several of them too bold, and I want to be plain at the outset that I have arrived at them on purpose. For each of the threads below I first worked out the consensus case — the base-rate forecast, the thing a sensible person would expect — and then asked a single further question: where, granting the consensus its due, could this run faster or further or stranger than the sensible person allows, without crossing into the merely silly? The published forecast is the answer to that question. It is the aggressive case, and it is offered as a wager, with the settling date attached.</p><p>It is worth being equally plain about the present from which the wager is made, because a forecast is only as good as its grasp of the ground it leaves. The ground, as of this spring, is roughly this. Four laboratories — call them by the families of their models, the GPT line, the Claude line, the Gemini line, and the Grok line — now sit within a narrow band of one another on the public benchmarks, with the leading systems clearing the high eighties on the standard software-engineering test, while the hardest of the contamination-resistant reasoning benchmarks — the ones designed precisely so that they cannot be memorised — remain conspicuously unsaturated, the frontier still well short of the human-expert ceiling on them. The agentic frontier, which is the more interesting number, has been advancing at a pace that the people who measure it describe as a doubling, every seven months or so, of the length of task a model can carry out on its own; the present figure, the length of task a frontier agent completes unassisted at even odds, is now measured not in minutes but in hours — the strong models of the middle frontier at something like four or five hours, and the very leading systems somewhere past the point at which the measurement itself can be trusted, with the doubling showing no sign of slackening. The money is on a scale the financial press strains to render legible: the largest infrastructure builders have committed something near seven hundred billion dollars of capital expenditure for this year alone, sharply up on the year before, and a leaked set of internal revenue figures this April was sufficient to send the whole sector of related stocks downward in an afternoon. The labour effect has begun, narrowly and unevenly, in the hiring of the young. The grid is straining. The public, in the United States at least, has turned decidedly cool. That is the ground. The wager begins here.</p><h2 id="the-agentic-frontier-crosses-the-working-day">The Agentic Frontier Crosses the Working Day</h2><p>The first and most consequential thread is the one the laboratories themselves watch most closely, and it is not raw capability on examinations — that contest has narrowed to the point of tedium — but the length of task a system can carry through without a human hand on it. The consensus expectation is straightforward and follows the trend line: if the autonomous task horizon has been doubling roughly every seven months, then a frontier agent that today manages a task of some hours at even odds will, in a year, manage one several times longer at the same odds — a full working day, and then some, of the even-odds figure. That is the cautious case, and it is itself remarkable enough.</p><p>The aggressive case holds that by May of 2027 the frontier agent will reliably — and I mean by reliably the eighty-per-cent figure, not the fifty — complete a full working day&rsquo;s worth of software engineering, the kind of task a competent professional would be assigned on a Monday and expect to finish by the end of it, unsupervised, in a sandbox, from a one-paragraph brief. The trend line alone gets one most of the way there for the even-odds number; the aggressive move is to claim the reliable number too, and to claim it because the laboratories have, this past year, visibly redirected their effort from capability toward exactly this. The distinction between a model that<em>can</em> do a thing once and a model that<em>consistently</em> does it is the distinction between a demonstration and a product, and it is the gap every serious deployment now lives or dies in. A field that has noticed a gap and pointed its best people at it tends to close that gap faster than a smooth extrapolation predicts, because the extrapolation is drawn from a period when nobody was trying. The thing I would least like to defend in this paragraph is the word<em>reliably</em>; it is the load-bearing word, and it is the one the trend line does not strictly license.</p><h2 id="software-work-is-reorganised-around-the-agent">Software Work Is Reorganised Around the Agent</h2><p>If the agent crosses the working day, the practice of building software is reorganised around that fact, and the reorganisation will by next May be visibly under way rather than merely discussed. The consensus already concedes a great deal here — that the coding agent reads a codebase, plans across many files, runs its own tests, opens its own pull requests, and that this compresses the manual labour of programming by something like a third to a half. That is the present, not a prediction.</p><p>The aggressive case is about the shape of the working day rather than its length. By May of 2027 the median professional engineer at a competent firm will not, as a rule, write code as the first move of the day; the first move will be to specify, to review, and to arbitrate among the work of several agents running in parallel — and the job title will not yet have changed, which is the part that makes it hard to see. The change will be inside the title. A programmer asked at the time whether the systems have altered his occupation will very often say no, and the same programmer asked the same question a year apart will be describing two different jobs. I expect, further, that at least one well-known software company will state publicly, and with figures, that a majority of the code it ships is now written by agents under human supervision — not as a boast on a stage, which has already happened and means little, but in the dry register of an earnings call, where the statement carries liability. The thing I would least like to defend here is the word<em>majority</em>; the honest version of the claim may be that the figure is large and rising and that no one can audit it, which is a weaker and truer thing.</p><h2 id="the-money-does-not-burst-but-it-cracks">The Money Does Not Burst, But It Cracks</h2><p>The thread on which I am most reluctant to be aggressive is the money, because the money is where confident forecasts go to be embarrassed. The consensus has by now organised itself into two camps that talk past each other. One holds that the capital expenditure — the seven hundred billion this year, the talk of a trillion and more beyond it — is a sound bet on a real and growing demand. The other holds that it is a bubble, and points to the circular financing, the chip-maker investing in the model laboratory which spends the investment on the chip-maker&rsquo;s chips, an arrangement of a scale and a shape that the soberer analysts have already compared, without much pleasure, to the vendor financing of the late dot-com period.</p><p>The aggressive case is not that the bubble bursts. It is more specific and more interesting than that. By May of 2027 there will have been a genuine and named correction — a sharp repricing of the publicly traded AI-infrastructure stocks, of a severity the financial press will agree to call a crash, occasioned by a particular disappointing disclosure rather than by any change in the underlying technology — and the building will continue through it and past it almost undisturbed. This is the part the bubble camp gets wrong and the boom camp also gets wrong: both of them believe the financial verdict and the physical verdict are the same verdict. They are not. A correction destroys fortunes and reputations and a certain number of the more leveraged firms; it does not, as a rule, destroy the thing already built. The halls will be raised and the chips installed and the power contracted whether or not the particular investors who paid for them are ever made whole, and a year from now one will be able to watch, in the same quarter, a column of red on the exchanges and a column of poured concrete in the desert, and the second column will be the longer of the two. The Victorians argued bitterly over the wisdom of their railways and built the railways; the railways remained when the argument was an antiquarian curiosity. I would least like to defend the timing — that the correction arrives inside the twelve months rather than just outside them. The direction I will defend without hedging.</p><h2 id="the-labour-effect-stops-being-deniable">The Labour Effect Stops Being Deniable</h2><p>The labour thread is where the aggressive case is easiest to state and hardest to state responsibly, and I want to take some care with it. The present evidence is genuinely mixed. Broad measures of employment show, so far, little that can be cleanly attributed to artificial intelligence; the careful studies find their signal not in the aggregate but at the margin, and the margin is the young. Entry-level postings in the most exposed fields have fallen sharply since 2023 — in junior software work the decline is steep enough that the figure is disputed rather than denied — and employment among workers in their early twenties in the most exposed occupations has fallen by something on the order of a seventh relative to the period before the chat window. The displacement, in other words, has not arrived as a wave breaking over the whole workforce. It has arrived as a quiet closing of the door through which people used to enter.</p><p>The consensus expects this pattern to continue and broaden gently. The aggressive case is that within the year it stops being deniable — that by May of 2027 there will be at least one official statistic, of the kind a government agency publishes and a newspaper can put in a headline, that a reasonable person can no longer explain by appeal to interest rates or the ordinary slackening of a labour market. The recent-graduate unemployment rate, already elevated, is the most likely candidate; a sustained divergence between that rate and the rate for experienced workers in the same fields is the sort of thing that is arguable for one or two quarters and undeniable after four. I do not expect mass layoffs of the dramatic kind the early fears imagined, and I want to be exact about why: the firms do not need to dismiss the workers they have in order to capture the saving, because they can simply decline to hire the workers they have not yet hired, and a hiring freeze is invisible in a way a layoff is not. The aggressive prediction, then, is not a flood. It is that the tide, which is already moving quite as much water, finally rises high enough that the people measuring the water agree on what they are looking at. The claim I would least like to defend is the cleanness of the attribution — the economy is a single tangled thing, and a year is a short interval in which to ask it to confess.</p><h2 id="the-grid-becomes-the-binding-constraint">The Grid Becomes the Binding Constraint</h2><p>For most of the short history of this technology the binding constraint was held to be ideas, and then for a while it was held to be chips, and the prediction here is that by May of 2027 it will be neither — it will be electrical power, and this will be understood not by specialists but generally. The consensus already half-concedes the point: everyone who follows the matter knows that the datacentre&rsquo;s appetite for power has outrun the grid&rsquo;s capacity to deliver it, that transmission and substations and transformers take years to build and the buildings take months, and that this mismatch is becoming the thing that decides where a facility can go and how large it can be.</p><p>The aggressive case adds two things to the consensus. The first is that the constraint becomes acute enough, within the year, to visibly bend the behaviour of the largest builders — that the dominant story in the build-out by next spring is not the signing of compute deals but the securing of generation, and that at least one frontier-scale facility will be brought online running substantially on power it generates for itself, behind the meter, because it could not wait the years the public grid demanded. The second, and the more aggressive, is political: that the local resistance to datacentre construction, which polling already finds to be the majority position by a wide margin, hardens within the year into a genuine and organised obstacle — that the cancellation of projects in the face of community opposition, already recorded at a record rate this past quarter, becomes common enough that the industry begins to treat the winning of local consent as a line item rather than a formality. The thing I would least like to defend is the word<em>generally</em> — the claim that the public, and not merely the trade press, comes to understand power as the constraint. Publics are slow to relocate their attention, and a year may not be long enough.</p><h2 id="the-temperature-drops-further">The Temperature Drops Further</h2><p>The last thread is the social and cultural one, and it is the thread on which the aggressive case is, perhaps surprisingly, the gloomy one. The consensus, insofar as the industry holds one, expects that familiarity will do its usual work — that as the systems become more useful and more woven into the ordinary furniture of working life, the public&rsquo;s unease will soften into the same unbothered acceptance that every previous technology eventually secured.</p><p>The aggressive case is that within the year it does the opposite. American sentiment toward these systems has been moving in one direction for some time, and moving faster among the young, who use the tools most and have grown most wary of them; the share who report themselves more concerned than excited has climbed to about half, and the enthusiasm of the youngest cohort has fallen sharply in a single year. The aggressive prediction is that this does not bottom out and reverse but continues, and that by May of 2027 a discernible anti-AI position — a settled, articulate, and socially respectable scepticism, the kind of stance a person can hold at dinner without having to defend it as a quirk — has consolidated into something a politician finds it worthwhile to address directly. The mechanism is not mysterious. A technology that is experienced primarily as something done<em>to</em> one — as the closing of the entry-level door, as the datacentre proposed for one&rsquo;s own county, as the steady degradation of the open web into fluent and confident sludge — does not win affection by becoming more capable. It wins resentment. The industry has been spending its moral energy on the distant prophecies, the catastrophe and the deliverance, and attending hardly at all to the nearer and smaller thing, which is that a great many ordinary people are forming a low opinion of it for reasons that are neither irrational nor likely to be argued away. The claim I would least like to defend is<em>socially respectable</em> — that the scepticism becomes not merely widespread but high-status. Status is hard to forecast, and I may be a year early.</p><h2 id="what-i-would-least-like-to-be-wrong-about">What I Would Least Like to Be Wrong About</h2><p>A forecast of this kind owes its reader one final honesty, which is a plain statement of where the forecaster&rsquo;s own confidence is thinnest — not the predictions he secretly disbelieves, for one should not publish those, but the ones whose failure would least surprise him.</p><p>The first is the reliability claim in the agentic thread. That the autonomous task horizon will keep lengthening I hold with real confidence; the trend has survived too many years and too many changes of method to be dismissed. But the leap from<em>can</em> to<em>consistently does</em> — from the even-odds figure to the eighty-per-cent figure across a full working day — is a leap the trend line does not strictly underwrite, and reliability has a way of being the last and hardest mile. If one prediction here is wrong, I should expect it to be that one, and I should expect the failure to take the modest form of the frontier landing at, say, a reliable half-day rather than a reliable full one.</p><p>The second is the timing of the financial correction. That a sharp repricing is coming I do not really doubt; the circular financing alone is enough to make me sure of the direction. But whether it arrives inside this particular twelve-month window or just beyond it is very nearly a coin toss, and markets have humbled steadier forecasters than I am by remaining buoyant for years past the point at which the arithmetic stopped working. If the correction has not come by May of 2027, I will not regard the underlying judgement as refuted. I will regard it as merely early, which is the forecaster&rsquo;s most familiar and least dignified condition.</p><p>The third is the consolidation of a respectable scepticism. The direction of public feeling I am confident about; the speed and the social standing of the result I am not. Publics can stay diffusely uneasy for a long while without that unease ever hardening into a position one can name, and it is entirely possible that May of 2027 finds the mood exactly as sour as I expect and exactly as shapeless as it is now.</p><p>What I notice, setting these three aside, is that the predictions I hold most firmly are the physical ones — that the building continues through whatever the markets do, that power becomes the constraint, that the entry-level door stays closed. The ones I hold most loosely are the predictions about<em>minds</em>: about how reliable a system will feel, about how investors will price their hopes, about how a public will decide to feel concerning a thing it has not chosen. This is, I suspect, the correct distribution of confidence, and it is worth saying why. The physical world is slow and obeys arithmetic; concrete poured is concrete poured, and a transformer ordered today arrives, or fails to arrive, on a schedule indifferent to anyone&rsquo;s opinion. Sentiment, capital, and the felt reliability of a tool are all, in the end, made of judgement, and judgement is the thing this whole technology has taught us, repeatedly and at some expense, is the hardest of all things to predict. A year from now the wager can be settled. I have given the date; I have given the reasons; I have marked the three places where I would not be astonished to lose. That is the whole of what a forecast can honestly offer, and I would rather offer that, and be checkable, than offer the safer thing and be merely vague.</p>
]]></content:encoded></item><item><title>Spanish Baroque</title><link>https://mtclinton.com/posts/spanish-baroque/</link><pubDate>Mon, 25 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/spanish-baroque/</guid><category>antiques</category><description>Twelfth per-subject post in Reading the Period Cabinet — the Spanish Baroque furniture tradition of the 17th c, with dark walnut + iron studs + tooled leather + bone inlay, the vargueño as type-specimen, the Habsburg-Spanish patron-context, and the Mudejar Islamic-influenced antecedent that gives Spanish Baroque its distinctive geometric register.</description><content:encoded>&lt;![CDATA[<p>The post before this one read the Italian Renaissance, and named the Spanish tradition as a sibling it had not yet reached — one of the national Renaissances that received the Florentine original and married it to an older inheritance of its own. The post before that, on the Italian Baroque, had named the same Iberian tradition in passing and left it for later. This post is the later. It opens the Spanish line, and it opens it not at the Renaissance but at the Baroque, because the seventeenth century is where the Spanish cabinet became most fully and most recognisably itself — and because what it became is, of all the traditions this arc has surveyed, the one that departs furthest from the carved and gilded Continental norm.</p><p>For the Spanish Baroque is the great exception. Where every other Baroque tradition this arc will treat ran to carving, to gilding, to colour and movement, the Spanish ran the other way — to darkness, to austerity, to plain severe surfaces of nearly black walnut, and to a hardware not of brass and gilt bronze but of hand-wrought<em>iron</em>. It is a grave and fortress-like furniture, monastic in temper, the Counter-Reformation rendered in the cabinet. The collector who has learned to read the Italian Baroque by its gilt and its carving must, in crossing the Pyrenees, learn to read very nearly the opposite.</p><p>This is the twelfth post in<em>Reading the Period Cabinet</em>. As with the Italian Renaissance, the Hepplewhite, and the Sheraton posts before it, it is a taxonomy post — a description of a type and of the evidence by which one reads it, not a personal narrative. Its type-specimen is the<em>vargueño</em>, the Spanish drop-front writing cabinet; its load-bearing distinction is iron and austerity, the matter that sets the whole tradition apart from its Italian and French neighbours; and its antecedent is the Mudejar inheritance — the Islamic-Christian geometric tradition of medieval Iberia — which gave the Spanish piece the geometric register no other European cabinet carries.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Spanish Baroque piece, for the purpose of beginning to read the style, is the<em>vargueño</em> — the drop-front writing cabinet. It is canonical for the same reason the cassone was canonical for the Italian Renaissance and the side chair for the Regency: it concentrates the whole vocabulary of the tradition into a single object the eye can take in at once. The iron, the leather, the dark walnut, the geometric inlay, the two-part construction, the contrast of a severe exterior against a lavish interior — all of it is present in the one form, and a collector who has learned to read a good vargueño has very nearly learned to read the tradition entire.</p><p>A canonical vargueño, then. It is, in the first place, two objects and not one. The upper part is the cabinet proper: a rectangular case of<em>walnut</em>, dark to the point of being nearly black, whose front is not a fixed panel but a hinged<em>fall-front</em> — a flap, locked shut, that lets down on iron hinges to a horizontal writing surface and discloses, behind it, a façade of many small drawers and pigeonholes. The lower part is a separate<em>stand</em>, made to be lifted away from the cabinet, and the Spanish made it in more than one form: the<em>puente</em>, a trestle stand braced and tied across with wrought-iron bars, and fitted with slide-out wooden support bars — often finished with carved shell ends — which were drawn from the stand so the fall-front could rest upon them when open; or the<em>taquillón</em>, a low chest of drawers on which the cabinet simply sat. The cabinet was, by design, demountable and portable — a thing to be carried, with the household, from one residence to another, which is the most Spanish fact about it.</p><p>The exterior of the cabinet is plain, or nearly so, and that plainness is deliberate. What ornament the closed vargueño carries is structural and metallic — bands and studs of hand-wrought<em>iron</em>, a pierced iron lockplate of some size set in the centre of the fall-front, iron drop-handles at the ends by which the heavy case was lifted, iron corner-mounts. The lavishness, where the piece is lavish at all, is reserved for the inside. Let the fall-front down and the drawer-fronts of the interior are revealed faced with<em>geometric inlay</em> of bone and ivory, sometimes with tortoiseshell and contrasting woods, set in star and interlace patterns; or the recesses are lined and the small architectural niches fronted with<em>tooled and gilded leather</em>; or the whole interior is treated as a miniature architecture of turned columns and gilded mouldings. The apex examples — the cabinets of the Habsburg court and the great Castilian houses — carry all of this at once, and carry it well. The principle they state is the principle of the whole tradition: severity without, richness within, and the richness kept private.</p><figure><img src="/images/posts/spanish-baroque/detail-inlay.png" alt="A close detail of Spanish Baroque bone-and-ivory geometric inlay — Mudejar-derived geometric vocabulary on walnut ground"><figcaption><p>A close detail of Spanish Baroque bone-and-ivory geometric inlay — the Mudejar-derived geometric vocabulary that distinguishes Spanish Baroque from Italian and French traditions. The geometric register descends from the Islamic-influenced pre-Renaissance Iberian tradition.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The vargueño states the principle, but the Spanish Baroque interior held several other forms, and the collector should know them by name before turning to the evidence of the wood. The<em>sillón frailero</em> — the friar&rsquo;s chair, or monk&rsquo;s chair — naturalised in Spain as the canonical Spanish armchair: a square, upright, austere seat of walnut, its back and seat formed of single panels of leather, often tooled, slung between the frame and held by large iron nail-heads, and tied across the front by a broad, flat wooden stretcher of walnut, frequently carved or cut in fretwork. What iron the chair carries is confined to those nail-heads — the studs that fix the leather — and the austerity of the piece lies not in metal but in the severe square frame and the plain slung hide. The<em>arca</em> is the Spanish chest, a rectangular boarded box bound with iron straps and fitted with an iron lock — the plain strongbox of the tradition. The<em>mesa de hierro</em>, the iron table, is a plank-top table carried on splayed, raked legs held against collapse not by a wooden stretcher but by scrolled<em>wrought-iron</em> braces running from leg to leg. The<em>papelera</em> is the vargueño&rsquo;s smaller relation — a writing-box of drawers without a fall-front, made to stand on a table. Every one of these forms is built of dark walnut, and every one depends on iron.</p><p>The wood, first. The Spanish Baroque worked principally in<em>walnut</em> —<em>nogal</em> — the dense, hard, dark timber of the peninsula, and worked it dark: the period surface is a deep brown gone nearly to black, the colour partly the natural oxidation of three or four centuries and partly the dark finish the tradition preferred from the outset. Walnut was the cabinet timber; the humbler pieces, and the structural parts, were often of pine, and the colonial and later pieces brought in tropical hardwoods by the Atlantic and Pacific trade. But the register the eye should expect of a Spanish Baroque piece is dark, plain, close-grained walnut — sober where the Italian was warm, severe where the French was bright.</p><p>The iron, second, and the iron is the load-bearing evidence — the single register that most reliably separates the Spanish Baroque from every neighbouring tradition. Where the Italian Baroque cabinet carried gilt and the French ran to ormolu and gilt bronze, the Spanish piece carries<em>iron</em>: hand-wrought, hammered out at the anvil, and left frankly visible. It is iron strap-hinges, iron pierced and chiselled lockplates of considerable size and considerable craft, iron bolt-heads and nail-heads used as ornament across a surface, iron corner-mounts, iron drop-handles, and — on the stands and tables — iron tie-bars and scrolled iron stretchers doing genuine structural work. This iron is decoration and it is also engineering; the smith was as much the maker of a vargueño as the joiner. And it is<em>wrought</em> iron, not cast: forged by hand, faintly irregular, the pierced plates cut and filed, never two mounts perfectly identical — which is a point of evidence in itself, cast iron being a later material and a sign of the reproduction.</p><p>The inlay, third. Where the Spanish Baroque is decorated with inlay rather than left plain, the inlay is<em>geometric</em> — and that geometry is the tradition&rsquo;s signature. It is not the figurative pictorial marquetry of the northern cabinet, nor the classical figures of the Italian; it is bone and ivory, with tortoiseshell and pale and dark woods, set into the dark walnut in stars, interlaces, and tessellated patterns. The vocabulary descends, as the next section will set out, from the Islamic decorative tradition of medieval Iberia, and it survives in the Baroque cabinet as a geometric register no other European furniture carries. The collector reading a drawer-front of small bone stars set in walnut is reading, at one remove, the geometry of the Alhambra.</p><p>The leather, fourth. Spain was the great European centre of decorated leather — the plain tanned goat leather known as<em>cordobán</em>, and, more particularly, the tooled, embossed, and gilded leather the workshops of Córdoba made of it, called<em>guadamecí</em> and long known across Europe as<em>cordwain</em> or cordovan — and that leather is a structural and decorative material of the Spanish Baroque interior. It lines the recesses of the vargueño; it fronts the small niches; it forms the back and seat of the sillón frailero, slung as a single tooled panel and secured with iron nails. Tooled leather, like geometric inlay and like the iron itself, is a register the Spanish tradition possesses and the others very largely do not.</p><figure><img src="/images/posts/spanish-baroque/detail-iron.png" alt="A close detail of Spanish Baroque iron studs and corner-mounts — heavy wrought ironwork on walnut"><figcaption><p>A close detail of Spanish Baroque iron studs and corner-mounts — the heavy wrought ironwork that gives Spanish Baroque its texture-variety distinction from the French ormolu and the Italian carved-giltwood traditions.</p></figcaption></figure><figure><img src="/images/posts/spanish-baroque/detail-leather.png" alt="A close detail of Spanish Baroque tooled leather — the cordoban tooled-and-gilt leather interior of a vargueño"><figcaption><p>A close detail of Spanish Baroque tooled leather — the cordoban tooled-and-gilt leather that lines the interior of the vargueño writing cabinet, a Spanish decorative-arts tradition descended from the Cordoba workshops.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Spanish Baroque, as a furniture period, runs across the seventeenth century — the long reign of the later Habsburgs, of Philip III, Philip IV, and the last of the line, Charles II — until the change of dynasty at the century&rsquo;s end carried the tradition into something else. It is, by a paradox worth stating plainly, the furniture of a Golden Age that was, in every other respect, an age of decline. The seventeenth century was the century in which Spanish power, having reached its height under the sixteenth-century Habsburgs, began its long contraction — the loss of the Netherlands, the exhaustion of the treasure, the slow political failure of a monarchy ruling more than it could govern. And yet it was precisely this century that produced the Golden Age of Spanish art: the painting of Velázquez and Zurbarán and Murillo, the writing of Cervantes and Calderón, and the grave, austere cabinet that this post reads. The vargueño belongs to that paradox. Its severity is not the severity of poverty; it is the chosen severity of a court that had silver enough and preferred iron.</p><p>The workshop centres were the cities of Castile —<em>Toledo</em> above all, the old imperial city and the seat of the cabinet trade, and<em>Madrid</em>, the court capital — with Salamanca and other Castilian towns contributing, and the kingdoms of the periphery keeping their own variants. The patron was, at the apex, the Habsburg court itself, and below it the Castilian nobility, the Church, and the religious houses, whose taste — sober, dark, monastic — the secular furniture so plainly shares. It is no accident that the canonical armchair is named for a friar.</p><p>Two larger circumstances shaped the period&rsquo;s materials, and the collector should hold both. The first is empire and trade. Seventeenth-century Spain stood at the centre of the first genuinely global trading system, and the cabinet shows it: ivory and bone for the inlay, tropical hardwoods, lacquer, and exotic goods came across the Atlantic from the American viceroyalties and across the Pacific by the Manila galleon, which carried the produce of Asia to Acapulco and so into the Spanish supply. The geometric inlay of a vargueño may be of ivory that crossed two oceans to reach the Toledo workshop. The second circumstance is the change of dynasty. The death of Charles II in 1700 without an heir ended the Spanish Habsburg line and brought, after a war, a Bourbon to the throne — and with the Bourbon came the French taste. The eighteenth-century Spanish cabinet turns toward the gilded, carved, French-influenced manner; the dark iron-bound vargueño is, by then, the furniture of an age that has closed. The seventeenth century is therefore the period proper, bracketed at one end by the tradition it grew from and at the other by the French succession that displaced it.</p><p>The antecedent the Spanish Baroque grew out of is the<em>Mudejar</em> inheritance — and this is the matter that most distinguishes the Spanish line from every other in Europe.<em>Mudejar</em> names the art of the Muslim craftsmen who continued to work in the Christian kingdoms of Iberia after the long reconquest, and the tradition they carried was, before all else, geometric: the star-and-interlace patterning of Islamic decorative art, executed in tile, in carved and coffered wood, and in fine inlay of bone and contrasting timbers. Medieval Spain produced, in consequence, a furniture unlike anything elsewhere in Christian Europe — cabinets and chests whose surfaces were covered not in figures or foliage but in dense, abstract, mathematical geometry. The Spanish Baroque did not discard this. It kept the geometric inlay as one of its registers, set it now into dark walnut and combined it with the wrought iron and the tooled leather, and so produced a Baroque cabinet that carries, legible beneath the seventeenth-century severity, the geometry of the Caliphate. No other European tradition has an antecedent of this kind, and it is the reason the Spanish piece can never quite be mistaken for the Italian.</p><figure><img src="/images/posts/spanish-baroque/antecedent.png" alt="A 15th–16th-c Spanish Mudejar cabinet — the Islamic-influenced Iberian antecedent with denser geometric inlay"><figcaption><p>A 15th–16th-c Spanish Mudejar cabinet — the Islamic-influenced Iberian antecedent with denser geometric inlay drawing on the Cordoba Caliphate vocabulary. The Spanish Baroque kept the geometric inlay register but added the heavy wrought-iron and tooled-leather elements that distinguish it from the medieval Mudejar.</p></figcaption></figure><figure><img src="/images/posts/spanish-baroque/pattern-book-page.png" alt="A page from a Toledo cabinet-maker's pattern book of the 17th c — vargueño, papelera, sillón, mesa"><figcaption><p>A page from a Toledo cabinet-maker&rsquo;s pattern book of the 17th c — perspective drawings of the principal Spanish Baroque forms: the vargueño drop-front cabinet, the papelera writing-box, the leather-back sillón armchair, the trestle-base mesa table.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/spanish-baroque/sibling-italian-baroque.png" alt="An Italian Baroque cabinet — dark walnut + carved giltwood, distinct from Spanish iron-and-leather register" loading="lazy"/><figcaption>Italian Baroque<em>— the Continental sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/spanish-baroque/sibling-louis-xiv.png" alt="A French Louis XIV cabinet — heavy gilt-bronze ormolu and tortoiseshell-and-brass marquetry, distinct from Spanish vocabulary" loading="lazy"/><figcaption>French Louis XIV<em>— the French royal sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/spanish-baroque/sibling-mudejar.png" alt="A Spanish Mudejar cabinet — the medieval Islamic-influenced Iberian antecedent with denser geometric inlay" loading="lazy"/><figcaption>Mudejar<em>— the Iberian antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/spanish-baroque/sibling-portuguese-baroque.png" alt="A Portuguese Baroque cabinet — Iberian-Atlantic sibling with colonial Brazilian rosewood and similar iron-studded construction" loading="lazy"/><figcaption>Portuguese Baroque<em>— the Iberian-Atlantic sibling</em></figcaption></figure></div><figcaption>Four styles most often confused with Spanish Baroque, drawn for comparison.</figcaption></figure><p>Four styles stand near enough to the Spanish Baroque that the beginner confuses them with it, and they are confusions of two distinct kinds. Two are Baroque siblings of the same century — the Italian and the French — and the confusion there is the confusion of contemporaries. Two are nearer relations still — the Mudejar antecedent that the Spanish Baroque grew directly out of, and the Portuguese Baroque, its Iberian neighbour — and the confusion there is the confusion of close kin. To distinguish the four is to fix what is particular to the Spanish line.</p><p>An<em>Italian Baroque</em> piece is the Continental sibling, and the easiest of the four to tell apart, because it states almost the opposite case. The Italian Baroque cabinet — the<em>stipo</em> — was the carved and gilded showpiece: warm-toned walnut and ebony, gilt-bronze mounts, carved giltwood figures, marble and<em>pietra dura</em> panels, the surface elaborated and bright. The Spanish piece runs the other way: a plain dark walnut case, hand-wrought<em>iron</em> where the Italian has gilt bronze, and what richness it has shut away inside the fall-front. The rule of thumb: carved, gilded, and bright on the outside is Italian Baroque; dark, plain, and iron-bound on the outside, with the lavishness reserved within, is Spanish.</p><p>A<em>French Louis XIV</em> piece is the French royal sibling, and it confuses the beginner because it too is a great formal cabinet of the seventeenth century. But the Louis XIV cabinet is the most sumptuous object the century produced — veneered in tortoiseshell and brass in the Boulle technique, mounted in heavy chased and gilt<em>ormolu</em>, raised on carved and gilded supports, the whole conceived as an instrument of royal magnificence. There is no austerity in it anywhere. The rule of thumb: tortoiseshell-and-brass marquetry and gilt-bronze ormolu is French Louis XIV; dark walnut and hand-wrought iron is Spanish Baroque — the two seventeenth-century courts could hardly have furnished themselves more differently.</p><p>A<em>Mudejar</em> piece is the Iberian antecedent, and the difficulty here is precisely that the Spanish Baroque kept so much of it. The medieval Mudejar cabinet is the source of the geometric register — its surface is geometric inlay, dense and abstract, of bone and ivory and contrasting woods, the Islamic star-and-interlace covering the front. The Spanish Baroque inherited that inlay but subordinated it: it is now one register among several, set into a dark walnut case, and combined with the heavy wrought iron and the tooled leather that the medieval piece does not have. The rule of thumb: a surface that is wholly and densely geometric, with no iron strapwork and no walnut severity, is Mudejar; the same geometry used as inlay within a dark, iron-bound walnut cabinet is Spanish Baroque.</p><p>A<em>Portuguese Baroque</em> piece is the Iberian-Atlantic sibling, and the hardest of the four, because Portugal shared the peninsula, a great deal of the temper, and the cabinet form itself. The distinction is one of material, surface, and trade. The canonical Portuguese case-piece is not the vargueño but the<em>contador</em> — a cabinet of drawers raised on a stand — and where the Spanish answer to ornament is dark walnut, visible wrought iron, and geometric inlay, the Portuguese answer is something else entirely. Portugal&rsquo;s empire ran to Brazil and to the East, and the contador shows it: it is worked in<em>Brazilian rosewood</em>, its drawer-fronts and framing built up with deep-relief carved ripple- and wave-mouldings — the<em>tremidos</em> — and its locks and corners set not with iron but with pierced and chiselled<em>brass</em>. The rule of thumb: dark walnut, severe wrought iron, and flat geometric inlay, Castilian in its plainness, is Spanish; rich rosewood, carved rippling<em>tremido</em> mouldings, and pierced brass mounts is Portuguese Baroque.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>form</em>, because with the Spanish Baroque the form is unusually diagnostic. The drop-front writing cabinet — a rectangular walnut case whose hinged fall-front lets down to disclose a façade of small drawers and pigeonholes — is the<em>vargueño</em>, and it is so particular to this tradition that the form alone places a piece in Spain. One looks, with it, for the two-part construction: a cabinet made to lift away from its stand, and a stand that is one of the Spanish types — the iron-tied trestle of the<em>puente</em>, or the chest-of-drawers base of the<em>taquillón</em>. A demountable drop-front cabinet on a separate Spanish stand is a strong placement before the surface has been read at all.</p><p>One looks next, and most carefully, at the<em>iron</em>. It is the load-bearing evidence of the whole tradition. The hardware of a Spanish Baroque piece should be hand-wrought iron — strap-hinges, a large pierced and chiselled lockplate, bolt- and nail-heads used as surface ornament, scrolled iron stretchers and tie-bars doing structural work on the stands and tables — and it should be<em>wrought</em>, not cast: forged at the anvil, faintly irregular, the pierced plates cut and filed by hand, no two mounts perfectly alike. Brass where one expects iron, or the crisp identical repetition of cast iron, argues against the piece or against its period.</p><p>One looks then at the<em>combination</em> — for it is the combination, more than any single register, that is the signature of the tradition. A genuine Spanish Baroque piece brings together dark, nearly black walnut; visible hand-wrought iron; geometric inlay of bone and ivory rather than figurative marquetry; and tooled, gilded leather. Any one of these may appear elsewhere; the four of them together, with a severe plain exterior and the richness concentrated inside the fall-front, appear only here.</p><p>And one looks, finally, for the<em>temper of the thing</em> — for the austerity that the whole post has carried as its load-bearing distinction. The Spanish Baroque is a grave, dark, monastic, fortress-like furniture, the one Baroque tradition that answered its century not with gilt and movement but with iron and restraint. The collector reads walnut, iron, inlay, and leather not as a checklist but as the evidence of a single temper, and asks of the word<em>Baroque</em> what, in the Spanish case, it must be made to mean: not the carved exuberance of Rome or the gilded magnificence of Versailles, but the Counter-Reformation severity of Castile — splendour shut inside a plain iron-bound box, and the box itself made to be carried.</p><p>The next post in the furniture arc will be either<em>Dutch marquetry</em> — to open the Continental marquetry tradition with the pale-walnut northern register — or<em>Mudejar</em>, to backfill the Iberian medieval antecedent more fully. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>The State of Coding, May 2026</title><link>https://mtclinton.com/posts/the-state-of-coding-may-2026/</link><pubDate>Mon, 25 May 2026 10:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-state-of-coding-may-2026/</guid><category>ai</category><description>A present-tense survey of how software actually gets written in mid-2026 — what the AI assistants have taken over, what the work feels like now, what is genuinely better, and what has been quietly lost along the way.</description><content:encoded>&lt;![CDATA[<p>The most accurate single statement one can make about the writing of software in the spring of 2026 is that the programmer has, for the most part, stopped writing it. This is not a figure of speech and it is not a forecast. It is a description of the working day. The act that defined the profession for sixty years — a person sitting at a keyboard and composing, line by line, the instructions a machine will execute — is now the exception rather than the rule in a great many engineering organisations, and the person sitting at the keyboard is doing something else with most of the hours. What that something else is, how well it is going, and what it has cost, is the subject of this account. I want to set down the state of the craft as it actually stands now, in the present tense, before the present moment is overwritten by the next one — which, on current evidence, will not be long in coming.</p><p>The numbers, taken on their own, do not tell the story, but they establish the floor under it. By the most recent surveys, somewhere around eighty-four per cent of professional developers use AI tools of some kind in their work — a figure that includes the chatbot consulted in a browser tab — and a little over half use them every working day. The narrower and more telling category is the dedicated coding tool, the agent or the AI-native editor wired into the repository itself; here the numbers are much smaller and rising fast. Something like a third of developers now work with an agent, and the AI-native editors, taken one by one, command smaller shares still. That is where the momentum plainly is, even if it is not yet where the majority has arrived. A meaningful and rising fraction of the code merged into production — by some measures a fifth or more — was produced in the first instance by a model rather than a person. These figures would have seemed extravagant eighteen months ago. They are now unremarkable, and the developer who uses none of these tools at all has become a sufficiently rare creature that one notices, and quietly wonders, when one meets him.</p><h2 id="what-the-day-looks-like-now">What the Day Looks Like Now</h2><p>Consider the shape of an ordinary task. A bug is filed; a feature is specified; some corner of the system needs to be extended. In 2022 the engineer assigned to this would have opened the relevant files, read them, formed a model of the code in her head, and begun to type — and the typing would have been most of the work, interrupted by the reading and the thinking but fundamentally continuous with them. The typing was how the thinking got externalised. One did not entirely know what one thought about a piece of code until one had tried to write it.</p><p>In 2026 the same engineer opens a coding agent — Claude Code, or Cursor&rsquo;s agent mode, or one of their several competitors — describes the task in a paragraph or two of English, and waits. The agent reads the files. It forms, or appears to form, a model of the code. It proposes a change, often a large one, sometimes spanning a dozen files; it writes the tests; it runs the tests; where the tests fail it revises and runs them again. Minutes pass, sometimes a great many minutes, and at the end of them the engineer is presented not with a blank editor but with a finished diff and an account of what was done and why.</p><p>The engineer&rsquo;s work, then, begins where it used to end. She reads the diff. She decides whether the model has understood the task — not merely whether the code runs, but whether it has done the<em>right</em> thing, in the right place, in a manner consistent with the rest of the system and with the things the specification did not think to say. This is the work now: specification at one end and judgement at the other, with the middle — the composition — increasingly delegated. The agents have stopped being autocomplete. The defining shift of the past year is that they run not for seconds but for minutes and hours, unattended, and the engineer has become something between an editor and a foreman, dispatching work and inspecting it on its return.</p><p>It is worth being precise about how far this goes, because the breathless accounts and the dismissive ones both tend to round it off. It does not go all the way. The agent that runs for an hour is supervised at both ends and frequently in the middle; the experienced engineer learns to recognise the shape of a task that will go well unattended and the shape of one that will not, and the recognition is itself a skill, newly minted and not yet named. The honest summary is that the model now does reliably what a competent but uninformed colleague could do — the boilerplate, the test scaffolding, the routine refactor, the second language one half-knows, the documentation nobody wanted to write — and does not reliably do what requires holding the whole system, and the business it serves, in mind at once. The boundary is real. It is also blurry, it moves, and a great deal of the working programmer&rsquo;s new skill consists in knowing where it is this month.</p><h2 id="what-is-genuinely-better">What Is Genuinely Better</h2><p>It would be a failure of honesty to survey this moment and arrive only at lament, because a good deal of what has happened is straightforwardly good, and the people enjoying it are not fools or dupes.</p><p>The first gain is speed, and it is not imaginary. The drudgery has genuinely been removed — not reduced, removed — from a wide band of ordinary work. The migration that would have consumed a careful week is done in an afternoon. The test suite that no one would ever have found time to write gets written, because writing it now costs a sentence rather than a day. The unfamiliar codebase yields up its structure to a few questions instead of to a fortnight of silent reading. A working developer in 2026, asked what she no longer has to do, will produce a list of small miseries — the configuration boilerplate, the error-handling that is the same every time, the third re-typing of a data structure into a third file — and every item on that list is a genuine subtraction from the sum of tedium in the world. One should not be too proud to admit that this is a real and welcome thing.</p><p>The second gain is the lowered floor, and here the picture is more complicated, but the gain is still a gain. A person who could not previously have built a working program can now build one. The hobbyist, the scientist with a data problem, the founder who is not an engineer, the engineer reaching outside her specialty — all of them can now get further, faster, than the old gradient of difficulty would have allowed. A great deal of software that simply would not have existed, because the cost of the first ninety per cent of it was prohibitive, now exists. That this same lowered floor also produces a great deal of software that<em>should</em> not exist is true, and I will come to it; but the floor itself, considered on its own, has let a large number of people make things, and making things is good.</p><p>The third gain is the one the productivity statistics capture least well and the one I am most confident is real: the removal of friction at the moment of<em>not knowing</em>. The old experience of programming was punctuated, constantly, by small walls — an unfamiliar API, a cryptic error, a syntax half-remembered — and each wall imposed a context-switch, a search, a scattering of attention. The model has flattened most of those walls. One stays inside the problem. The work has become, for those who have adapted to it, markedly more continuous than it was, and continuity of attention is not a small thing; it is most of what made the good days good.</p><h2 id="what-has-quietly-been-lost">What Has Quietly Been Lost</h2><p>Against this, and not cancelling it but standing beside it, is a column of losses, and the losses are quieter than the gains because no one ships a press release about them.</p><p>The first and most discussed is the review burden, and it has become severe. The asymmetry is simple and unforgiving: generating code is now extremely cheap, and reviewing it is exactly as expensive as it ever was. The natural consequence has arrived on schedule. Pull requests have grown — by some measures substantially, with one large study of heavily AI-using teams putting them more than half again as large as two years ago, and other estimates considerably more modest — and they arrive faster, and the reviewers have not multiplied to match. A team that finds itself with thirty pull requests a day and six people to read them is not a hypothetical; it is a case study, and there are many like it. The researchers studying this have reached for the language of the commons, and the phrase fits: each individual&rsquo;s productivity gain externalises a cost onto whoever must read the result, and the reading does not scale, and the reviewer increasingly describes the sensation of being the first human being ever to have looked closely at the code he is approving. That sensation is new, and it should trouble anyone who hears it described.</p><p>The second loss is subtler and concerns the shape of debugging. To debug a system one wrote oneself is to consult one&rsquo;s own memory; the bug is somewhere in a structure one built, and the building of it laid down the very knowledge the debugging now draws on. To debug a system one did not write — that an agent wrote, an hour ago, while one was reading email — is a different and worse activity. There is no memory to consult. One must reverse-engineer the intent from the artefact, reconstruct after the fact the model the machine had and did not keep, and do this under the additional handicap that the code is plausible. The model&rsquo;s code is not wrong in the way a beginner&rsquo;s code is wrong, with the wrongness showing on its face. It is wrong in the way a confident and slightly careless colleague&rsquo;s code is wrong: it reads well, it very nearly works, and the defect is precisely where the plausibility is thickest. Several engineers have told me, in almost the same words, that the review of an AI&rsquo;s work now takes longer than its creation — which is an odd sentence to be able to write about a productivity tool, and a true one.</p><p>The third loss is the one that will matter most in ten years and is hardest to point at now, because it is a non-event: the erosion of the deep understanding that used to be a by-product of the work. Knowledge of a system used to be acquired the way one acquires knowledge of a city by walking it — slowly, incidentally, through the accumulated friction of having been everywhere at least once. The friction is now mostly gone, and so is the incidental knowledge. The engineer who has an agent write the authentication layer does not, afterward, understand the authentication layer the way the engineer who wrote it would have. She understands the<em>diff</em>. She has read it carefully; she has approved it responsibly; and she has, all the same, not been to those streets. Multiply this across a career and across a team and one arrives at a profession that ships more code and understands it less — not through any individual&rsquo;s negligence, but because the mechanism by which understanding used to accumulate has been quietly disconnected. No one decided this. It is simply what removing the friction also removed.</p><p>And then there is the slop. The lowered floor that lets the hobbyist build a real thing also lets a great deal of low-quality, half-understood, structurally careless code into repositories that must then live with it. The open-source maintainers feel this most acutely — the AI-generated bug report that wastes an afternoon, the pull request that no human can quite vouch for — but it is not confined to them. Slop is the characteristic pollution of this moment, and like most pollution it is produced by people acting locally reasonably and consumed by people who did not produce it.</p><h2 id="the-divide">The Divide</h2><p>One cannot survey this moment honestly without naming the divide that now runs through the profession, because it is the single most consequential fact about the working population of engineers, and it is not the divide one might have predicted.</p><p>It is not, principally, a divide between those who use the tools and those who refuse them; the refusers are now too few to constitute a side. It is a divide between two ways of using them. On one side stands the engineer — and she is very often a senior engineer, though not always — who treats the model as a fast, capable, and fundamentally untrustworthy subordinate: who delegates aggressively but reviews ruthlessly, who has retained the judgement to know when the agent has produced something plausible and wrong, and who is, in consequence, genuinely and substantially more productive than she was. The tool has multiplied her, because she brought to it a discipline it does not supply.</p><p>On the other side stands the engineer who has allowed the model to become not a subordinate but a substitute — who ships what it produces because it runs and the tests are green, who has stopped reading the diffs with full attention because there are too many of them and they are usually fine, and who is, slowly and without noticing, losing the capacity to tell the plausible-and-wrong from the plausible-and-right. This engineer is also more productive, by the crude measure of code merged. He is also, by a measure that does not yet appear on any dashboard, becoming less of an engineer every quarter.</p><p>The unsettling thing about this divide is that it does not announce itself. Both engineers look the same in the metrics; both close their tickets; both have green tests. The difference is in a quantity — retained judgement, the understanding that lets one catch the confident error — that the current tooling neither measures nor rewards, and which erodes silently in the second engineer while it compounds in the first. The profession has not yet built the instruments to see this divide clearly. It will need to, because the divide is real, and it is widening, and on present evidence it tracks not seniority or talent but something more like temperament — the disposition to remain suspicious of a machine that is usually right.</p><h2 id="the-tools-plainly">The Tools, Plainly</h2><p>A word on the state of the tools themselves, since their condition is part of the snapshot.</p><p>The landscape has, over the past year, both consolidated and proliferated — consolidated in form and proliferated in number. The dominant shape is now agreed upon: an agent that can read a whole repository, run commands, execute tests, and work unattended for a stretch. Within that shape there is vigorous competition. The incumbent assistant that defined the first era of this technology is still the most widely installed, and is still adding users in absolute terms, but its share of the field has slipped — from something like two-thirds of professional developers to roughly half — as faster-growing rivals have taken the energy of the moment, and the tools that have taken it are the agentic ones — Claude Code foremost among them, having gone from nothing to the front of the field in well under a year, with Cursor&rsquo;s agent and a clutch of others close behind. The experienced engineer no longer uses one tool; the surveys find she runs two or three at once, and has opinions about which is suited to which kind of work, the way a tradesman has opinions about which saw.</p><p>What has not happened — and the absence is worth marking — is any closing of the trust gap. Adoption has risen steeply and trust has, if anything, fallen: a much-cited survey finds that the fraction of developers who actually trust the accuracy of what these tools produce has<em>declined</em> even as the fraction using them daily has climbed. This is not the contradiction it first appears. It is the signature of a mature working relationship with a powerful and unreliable instrument. One does not have to trust a tool to use it constantly; one has only to know its failure modes. The developers have learned the failure modes. That learning is itself one of the real skills of 2026, and it is held, unevenly, across the divide described above.</p><h2 id="what-has-not-changed">What Has Not Changed</h2><p>It would be easy, surveying all this motion, to conclude that everything is in flux. It is not, and the things that have held still are as much a part of the present state as the things that have moved.</p><p>The hard part of software was never the typing, and it still is not. The hard part was deciding what to build, understanding the problem beneath the request, holding a large system in mind well enough to know where a change belongs and what it will disturb, and bearing the responsibility for the result. None of this has been automated, and there is no present sign of its being automated. The model will write the function; it will not tell you that the function should not exist, that the feature is a mistake, that the real problem is two layers down and political rather than technical. Judgement, taste, the modelling of systems, the modelling of the people the systems are for — these remain exactly where they were, in the human, and the engineers who have prospered in this transition are precisely the ones who already had them and found a machine to take the typing off their hands.</p><p>Debugging, too, in its deepest form, has not changed. The intermittent failure, the race condition, the bug that emerges only from the interaction of three subsystems none of which is individually wrong — these still demand a human who can hold the whole thing in mind and reason about it, and the holding-in-mind is still learned only by having done it. The agent assists; it does not relieve one of the need to be the kind of person who could have done it alone.</p><p>And the fundamental texture of the work — that it is the precise instruction of a literal machine, that the machine will do exactly what it is told and not what was meant, that the gap between intent and instruction is where all the trouble lives — that has not moved at all. The model has merely inserted itself into the gap. It has not closed it. It has, if one is honest, added a second gap: between what one meant and what one told the model, and between what one told the model and what the model told the machine. There is more translation in the pipeline now, not less, and translation is where meaning is lost.</p><h2 id="the-direction-of-travel">The Direction of Travel</h2><p>I said at the outset that this is a snapshot and not a forecast, and I mean to hold to that. But a snapshot of a moving thing must at least record the direction of the motion, and the direction is not in serious doubt. The agents are being trusted with longer and more autonomous stretches of work; the human&rsquo;s position is migrating steadily toward the specifying and reviewing ends and away from the composing middle; the divide between the two ways of using the tools is widening rather than closing. Whether all of this arrives somewhere good is a question for a different essay, and I will not pretend to settle it in this one.</p><p>What I will say, as the thing worth leaving on the page, is this. The profession is in the middle of a genuine and irreversible change in what the daily work consists of, and the change is neither the triumph the boosters describe nor the catastrophe the declinists describe. It is something harder to hold in one hand: a real and substantial gain in speed and reach, bought with a real and substantial loss of understanding and craft, distributed unevenly across a workforce that has split, quietly, into those who have kept their judgement and those who are spending it. The good news and the bad news are not two stories. They are one story, and its name is delegation, and the whole of the question is what one keeps for oneself while delegating the rest.</p><p>The typing is gone, or going. The thinking, for now, is not. The state of coding in May 2026 is the state of a craft discovering, task by task and engineer by engineer, which of the two it was made of all along.</p>
]]></content:encoded></item><item><title>Karabagh</title><link>https://mtclinton.com/posts/karabagh/</link><pubDate>Mon, 25 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/karabagh/</guid><category>antiques</category><description>Twelfth per-subject post in Reading the Antique Rug — the southern Caucasian region of mountainous Karabagh, with burgundy ground and French-rose floral vocabulary, the Caucasian type most-influenced by the European commercial market and the Aubusson-derived rose-bouquet design.</description><content:encoded>&lt;![CDATA[<p>The third post in this arc treated the Kazak, and it opened the Caucasian tradition by setting the bold geometric weaving of the southern highlands against the curvilinear Persian work the arc had been describing until then — the stepped medallion against the scrolling vine, the saturated tomato-red against the city ground, the tribal loom against the workshop. The Kazak post closed by promising that the arc would, in time, come back down out of the highlands and treat the rest of the South Caucasus on its own terms. The eleventh post, on the Isfahan, ended by naming Karabagh as one of the two rugs that might come next, and by noting that the choice would return the account to the Caucasus and to the burgundy-and-rose register. This is that post. It treats Karabagh in the position the arc has reserved for the southern weaving region of the South Caucasus — the mountainous district that lies between the Caucasian rug world and Persia, and that produced, more than any other Caucasian type, a body of work the collector must learn to recognise across an unusually wide range.</p><p>This is the twelfth post in<em>Reading the Antique Rug</em>. The Karabagh is the rug in this arc with the most divided identity, and the division is the load-bearing fact of the whole post. The region produced, side by side and from the same villages, two almost opposite kinds of rug. The first is a bold, large-scale geometric Caucasian weaving — stepped medallions, a saturated palette, the strong angular drawing that the Kazak post described as the common Caucasian grammar. The second is a startling body of floral rugs carrying naturalistic European roses and bouquets, drawn so directly from French models that a Karabagh of this kind, met without warning, can be mistaken for an Aubusson. Both are genuinely Karabagh. The post must carry both, and it must hold them together rather than apart; that two-natured identity, the tribal-geometric and the French-floral standing in one tradition, is the distinction this account is built around. One meets it the moment one tries to say what a Karabagh looks like.</p><h2 id="the-specimen">The Specimen</h2><p>A Karabagh that one will most commonly encounter on the open market is a nineteenth-century or early-twentieth-century weaving of the floral kind — and it is worth beginning with the floral kind precisely because it is the one a collector does not expect, and the one the rest of the post must explain. Such a rug is, in its commonest form, a piece of moderate size: a scatter rug, a long runner, a kellegi of the gallery proportion that the Karabagh district favoured for its houses. The first thing to settle, before any motif is read, is the ground, because the Karabagh ground is the type&rsquo;s signature in the way the wine-red field was the Kashan&rsquo;s and the pale ivory was the Isfahan&rsquo;s. It is a deep, saturated burgundy — a dark wine-red that runs warmer and graver than the bright tomato-red of the Kazak, with which it is most often confused — and on the floral pieces it is frequently a near-black aubergine or a deep madder that the eye reads, at a little distance, as black. Against that dark ground the design is drawn in clear pink, in a softer rose-red, in ivory and a clean green, and the relation between the dark field and the pale roses is the whole visual character of the type.</p><p>The design completes the specimen, and on the floral Karabagh it is the<em>Gül Farangi</em> — the term is Persian-Turkic and means, in the plainest rendering, &ldquo;foreign flowers&rdquo; or &ldquo;French flowers,&rdquo; and it is exactly descriptive. The field carries naturalistic roses: full-blown garden roses, drawn with shading and with a sense of light and volume, gathered into bouquets and scattered across the dark ground in a manner that owes nothing to the Caucasian geometric grammar and everything to the floral carpets of France. There are rose-and-laurel borders; there are pink ribbons and trailing sprays; there are, on the more ambitious pieces, the full apparatus of the European bouquet. The drawing is curvilinear in intent — it is<em>trying</em> to be naturalistic — and the quality that most distinguishes the floral Karabagh is precisely the gap between the intent and the means. A Caucasian village loom is a coarse instrument for a French rose. The weaver renders the rose as faithfully as a moderate symmetric knot will allow, and the result is a naturalistic flower carried at a vernacular register: recognisably, unmistakably French in its drawing, and just as unmistakably a hand-knotted Caucasian village rug. That doubled quality — the foreign design honestly attempted on the native loom — is the floral Karabagh&rsquo;s particular charm, and it is the thing the post is asking the eye to learn.</p><figure><img src="/images/posts/karabagh/detail-medallion.png" alt="A close detail of a Karabagh French-rose floral bouquet — the Aubusson-derived European vocabulary in Caucasian wool pile"><figcaption><p>A close detail of a Karabagh French-rose floral bouquet — the Aubusson-derived European vocabulary translated into Caucasian wool pile. The roses are recognisably French in their naturalistic drawing, even at the Caucasian village register.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence, and for the Karabagh it is the fact that anchors the type firmly within the Caucasian tradition no matter what the field is drawing.<em>The Karabagh is woven on a wool foundation.</em> One turns the rug over, parts the pile at a worn place, or examines the fringe where the warp ends emerge, and the warp threads are wool — and so, on most pieces, is the weft. This is the South Caucasian wool-warp register, the structural signature that the Kazak post established as common to the Caucasian village rugs, and it holds for the Karabagh whether the field carries a stepped medallion or a French bouquet. The collector should grasp the force of this. The floral Karabagh borrows its<em>design</em> from a foreign tradition, but it does not borrow its<em>structure</em> — the foundation remains stubbornly, diagnostically Caucasian, and a rug that looks like an Aubusson but is woven on a wool warp at moderate Caucasian density has already told the careful hand most of what it needs to know. The foundation is the part of the rug the European fashion never reached.</p><p>The knot is the second piece of structural evidence, and it corroborates the first. The Karabagh is tied with the symmetric knot — the Turkish knot, used across the whole Caucasian and Anatolian world — set at the moderate village density that is neither the fineness of the Persian workshop nor the deliberate coarseness of the most rustic tribal weaving. The knot is symmetric whether the rug is geometric or floral; the European design did not bring a Persian knot with it. The wool of the pile is of the good mountain grade the South Caucasus is known for, and it is this wool that gives even a modest Karabagh its depth of colour. The palette is the last and most legible evidence, and it is here that the type announces itself across both its kinds. The Karabagh ground runs to burgundy and to deep wine, graver and darker than the Kazak&rsquo;s bright field; and on the floral pieces the dark ground is set against the pink-and-red European roses in a contrast that no purely Caucasian rug, and no purely Persian one, will quite reproduce. A deep burgundy ground carrying naturalistic roses, on a wool foundation, at a moderate symmetric knot — that combination is Karabagh and is almost nothing else.</p><figure><img src="/images/posts/karabagh/detail-border.png" alt="A close detail of a Karabagh main border — French-rose-and-laurel European repeat"><figcaption><p>A close detail of a Karabagh main border — the French-rose-and-laurel European repeat that distinguishes Karabagh from the tribal Caucasian neighbours.</p></figcaption></figure><figure><img src="/images/posts/karabagh/detail-foundation.png" alt="A close detail of a Karabagh knot-back — wool warp, wool weft, symmetric knot at Caucasian density"><figcaption><p>A close detail of the back of a Karabagh rug — the wool warp and wool weft, the symmetric knot at moderate Caucasian density.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>Karabagh is a region, not a town, and the region is a mountainous upland of the southern Caucasus — the country the Persians knew as Qarabagh, the &ldquo;black garden,&rdquo; lying between the lowland plains and the high range, straddling what are now the borders of Azerbaijan and Armenia. It is the southernmost of the Caucasian weaving districts, and its position is the first fact the period has to explain: Karabagh sits at the seam between the Caucasian rug world above it and Persia below, and a region at a seam tends to weave like one. The geometric tradition of Karabagh is genuinely Caucasian, of a piece with the highland Kazak and descending, as the Kazak does, from the great seventeenth-century Caucasian carpets. But the region also looked south to Persia and, in the nineteenth century, north and west to Russia and to Europe — and it is that second set of horizons that made the Karabagh the divided thing it is.</p><p>The dividing event has a date. In 1828, by the Treaty of Turkmenchay, the Karabagh region passed from Persian to Russian rule, and the South Caucasus was drawn into the commercial orbit of the Russian Empire. What followed was not a change of looms but a change of customers. The Karabagh weavers, who had always woven for themselves and for the local trade, now wove increasingly for a Russian and a wider European market — and that market had a taste, and the taste was for flowers. The floral carpets of France, the Aubusson and the Savonnerie, with their naturalistic rose bouquets on dark grounds, were the furnishing fashion of the age across all of imperial Europe; printed cottons carried the same roses into ordinary rooms. The Karabagh weavers, weaving now for buyers who wanted that fashion, simply gave it to them. They translated the French rose onto the Caucasian loom. The<em>Gül Farangi</em> — the foreign flower — is the direct and traceable result of a tribal weaving region being handed, by the accident of annexation, a commercial market with an imported taste.</p><p>The peak of this floral production ran through the middle and later decades of the nineteenth century, and the geometric Karabagh was woven straight through the same period — the two kinds were never successive, never a fashion replacing a tradition, but parallel, made in the same decades and sometimes the same villages, for buyers who wanted different things. Among the named sub-types the trade still recognises, the<em>Kasim Ushag</em> — a village group weaving bold geometric medallion rugs of a particularly archaic and forceful drawing — stands as the clearest reminder that the old Caucasian line ran on undiminished while the roses bloomed alongside it. The early twentieth century brought the decline that came to most of the regional weaving districts; the Soviet period reorganised the looms into managed production and the old freedom of the village weaver was gone, though Karabagh-design rugs continued to be made. The collector should hold the chronology plainly: the Karabagh is a Caucasian tradition of long standing that, for one historically specific reason — a change of empire and therefore of customer — grew a second nature. Both natures are old; both are genuine; neither cancels the other.</p><figure><img src="/images/posts/karabagh/antecedent.png" alt="A 17th-c Caucasian Dragon carpet — the shared antecedent of the Caucasian tradition"><figcaption><p>A 17th-c Caucasian Dragon carpet — the shared antecedent of the broader Caucasian tradition that Karabagh and Kazak both descend from. The Dragon carpet vocabulary (the stylised dragon-and-phoenix motifs at large scale) is the older Caucasian baseline; Karabagh diverged from it in the 19th c by absorbing the French-rose European vocabulary.</p></figcaption></figure><figure><img src="/images/posts/karabagh/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the southern Caucasian region — Karabagh / Gendje / Talish"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the southern Caucasian region — district map locating Karabagh, Gendje, Talish in the mountains south of the Kura river; archetype drawings showing the French-rose Karabagh variant and the more tribal Gendje and Talish neighbours.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/karabagh/sibling-kazak.png" alt="A Caucasian Kazak rug — the tribal-plateau southern Caucasian neighbour with saturated tomato-red ground and bold geometric medallions, distinct from mountainous Karabagh" loading="lazy"/><figcaption>Kazak<em>— the southern Caucasian highlands tribal</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/karabagh/sibling-shirvan.png" alt="A Shirvan rug — eastern Caucasian tradition with dark navy ground and small-scale repeat compositions" loading="lazy"/><figcaption>Shirvan<em>— the eastern Caucasian</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/karabagh/sibling-kuba.png" alt="A Kuba rug — eastern Caucasian with dense allover small-pattern, dark navy / teal ground" loading="lazy"/><figcaption>Kuba<em>— the eastern Caucasian allover</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/karabagh/sibling-daghestan.png" alt="A Daghestan rug — eastern Caucasian prayer-rug type with pale ground and lattice composition" loading="lazy"/><figcaption>Daghestan<em>— the prayer-rug eastern type</em></figcaption></figure></div><figcaption>Four Caucasian types most often confused with Karabagh, drawn for comparison.</figcaption></figure><p>The four types set against the Karabagh are all Caucasian, and all are woven on the wool foundation at the symmetric knot — so neither the structure nor the broad region will separate them, and the practised eye separates them instead by reading palette, scale of drawing, and the particular district habit each type is keyed to. The complication peculiar to the Karabagh is that it must be told apart twice over: the geometric Karabagh against its Caucasian neighbours, and the floral Karabagh, which has almost no Caucasian neighbour at all and is confused instead with the European carpets it imitates. The working rule for the district can be stated as plainly as the Kazak post stated its own:<em>the Caucasian village rugs are told apart not by structure, which is genuinely shared, but by palette, by the scale of the drawing, and by the local design habit — and the Karabagh is the one among them that one must also be prepared to recognise when it is wearing French clothes.</em></p><p>A<em>Kazak</em> is the type the comparison turns on, because the geometric Karabagh and the Kazak are the closest pair in the plate — both southern Caucasian, both descended from the seventeenth-century carpets, both drawing bold stepped medallions in the strong angular grammar. The separation is one of palette and altitude. The Kazak is a highland tribal rug keyed to a bright, almost shrill tomato-red, woven thick and long in the pile; the Karabagh runs to a graver, darker burgundy and a generally finer, lower clip. The rule of thumb: a bright tomato-red ground with a thick shaggy pile is pointing to Kazak; a deep grave burgundy is pointing to Karabagh — and a field of naturalistic roses settles the matter at once, for the Kazak never wove them.</p><p>A<em>Shirvan</em> carries the comparison east, to the eastern Caucasus. The Shirvan is an eastern Caucasian type of distinct character — finer in the knot than either southern rug, lower in the pile, and keyed to a darker ground, often a deep navy, carrying small-scale repeat compositions rather than the large stepped medallion of the south. The rule of thumb: a fine, low, small-patterned eastern rug on a dark navy ground is a Shirvan; the large-scale medallion on burgundy, or the rose bouquet, is Karabagh.</p><p>A<em>Kuba</em> is the eastern Caucasian neighbour of the Shirvan, and it presses the same distinction further. The Kuba is finer still, and its character is the dense allover small-pattern field — a surface covered edge to edge with a tight repeating motif on a dark navy or teal ground, with no medallion to rest the eye. The rule of thumb: a dense allover eastern rug, finely knotted on a dark ground, is a Kuba; the Karabagh works at a larger scale and a warmer, redder palette.</p><p>A<em>Daghestan</em> moves the comparison to the prayer rug. Daghestan is the northeastern Caucasian type most associated with the prayer-rug format — a directional niche at one end — drawn very often as a pale-ground lattice, a regular diamond trellis of small flower-heads on an ivory or light field. The rule of thumb: a pale-ground lattice prayer rug from the northeast is a Daghestan; the Karabagh is a dark-ground rug, geometric-medallion or rose-floral, and is rarely a prayer rug at all.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Karabagh comes down, as in the prior rug posts, to a short ordered checklist — and because the Karabagh is the divided type, the checklist must do something the earlier ones did not: it must work on two rugs that look nothing alike. The move that does the most work here is therefore not a move of the eye at all. It is to turn the rug over and read the foundation first, before the field has a chance to mislead.</p><p>One looks first, and principally, at the<em>foundation</em>. A Karabagh is woven on a wool warp, generally with a wool weft, at the moderate density of a Caucasian village loom — and one establishes that at the fringe, where the warp ends emerge, or at any worn place where the structure shows through the pile. This single observation does the largest piece of attributing work in the whole inspection, and it does it regardless of what the field is drawing. A wool foundation places the rug in the Caucasian village tradition and rules out the cotton-warp Persian workshops at one glance; and it is the observation that catches the floral Karabagh in particular, because the floral Karabagh is the rug most likely to be mistaken for something it is not. A rug carrying naturalistic French roses, met without its back examined, may be taken for an Aubusson or a Savonnerie — a flatwoven European furnishing carpet of an entirely separate tradition. Turn it over. If the foundation is wool and the surface is a knotted pile at a moderate symmetric density, the rug is not French. It is Caucasian, and it is very probably Karabagh. One reads the foundation first because the foundation never followed the fashion.</p><p>One looks next at the<em>palette</em>, which is the Karabagh&rsquo;s signature across both of its kinds. The ground runs to a deep, grave burgundy — a dark wine-red, or on the floral pieces a near-black aubergine or madder — and it is darker and warmer than the bright tomato-red of the Kazak with which it is most often confused. The burgundy ground is the most characteristic — the floral pieces take it almost without exception, and a great many of the geometric ones besides, though a geometric Karabagh will also be met on ivory or on a darker blue — and it is, where it appears, among the first things the eye should seek once the foundation has been read. A bright or shrill red is pointing away, toward the highland Kazak; a deep even navy across the whole field is pointing east, toward Shirvan or Kuba; the grave burgundy is Karabagh&rsquo;s own.</p><p>One looks next at the<em>drawing</em>, and here the checklist forks, because the Karabagh draws two ways. If the field is geometric, one reads it as one would read any Caucasian rug — a bold stepped medallion, strong angular forms, the saturated palette of the family that descends from the seventeenth-century carpets — and one tells it from the Kazak by palette and clip as the comparison section set out. If the field is floral, one reads it for the<em>Gül Farangi</em>: naturalistic roses, drawn with shading and volume, gathered into European bouquets, set on the dark ground in the manner of a French furnishing carpet. One looks specifically for the gap between the design and the means — the foreign rose honestly attempted at a vernacular village register, recognisably French in its drawing and recognisably hand-knotted in its execution. That gap is the floral Karabagh&rsquo;s authenticating mark. A rose drawn with the smooth resolution of a true Aubusson is not a Karabagh; a rose drawn with French intent and Caucasian means is.</p><p>And one looks, last, for the<em>coherence of the whole</em>. The Karabagh is the divided type, and the temptation, on meeting either of its kinds, is to attribute it to the tradition the field resembles — to call the geometric piece simply Caucasian, and the floral piece simply French. The connoisseur resists both. A Karabagh is the rug on which a wool foundation, a moderate symmetric knot, and a grave burgundy palette are found together, and on which the field may then be either the bold stepped medallion of the old Caucasian line or the foreign roses of the commercial market — both readings equally genuine. One holds the two natures together, as the region itself held them, and recognises the Karabagh as the single tradition wide enough to contain them both. That is the whole skill the post has been asking for: not to identify a rug, but to identify a region across the full reach of what it was willing to weave.</p><p>The next post in the rug arc will be either<em>Shirvan</em> — to extend the Caucasian region into the eastern types with their dark-navy palette — or<em>Kuba</em>, to continue the eastern Caucasian arc with the dense allover composition. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Italian Renaissance</title><link>https://mtclinton.com/posts/italian-renaissance/</link><pubDate>Sun, 24 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/italian-renaissance/</guid><category>antiques</category><description>Eleventh per-subject post in Reading the Period Cabinet — the Italian Renaissance furniture tradition of the 15th–16th c, the cassone marriage-chest and the credenza as type-specimens, deep-relief walnut carving and the architectural-classical vocabulary of the Quattrocento and Cinquecento, and the load-bearing distinction between genuine period work and the vast 19th-c Renaissance Revival reproduction industry.</description><content:encoded>&lt;![CDATA[<p>The sixth post in this arc treated the Italian Baroque, and named the Italian Renaissance as the antecedent it had grown out of — the sixteenth-century cassone tradition from which the seventeenth-century stipo was elaborated. That post left the antecedent as a single figure and a paragraph; this one returns to it and gives it the full reading it was promised. For the Italian Renaissance is not merely one tradition among the others this arc has surveyed. It is, by date, the earliest of them all, and something more than early: it is the fount. The fifteenth- and sixteenth-century furniture of Florence, Venice, Rome, and the northern Italian cities is the head of the stream from which the whole European cabinet tradition — French, Spanish, English, German, and the Italian Baroque itself — afterward ran.</p><p>This is the eleventh post in<em>Reading the Period Cabinet</em>. As with the Hepplewhite, Sheraton, and Regency posts before it, it is a taxonomy post — a description of a type and of the evidence by which one reads it, not a personal narrative. Its type-specimen is the cassone, the carved walnut marriage-chest; its principal ornament is deep-relief carving drawn directly from classical Roman architecture; and its load-bearing distinction is not between the Italian Renaissance and a neighbouring style at all, but between genuine fifteenth- and sixteenth-century work and the enormous nineteenth-century industry that imitated it.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Italian Renaissance piece, for the purpose of beginning to read the style, is the<em>cassone</em> — the marriage chest. It is canonical for the same reason the side chair was canonical for the Regency: it concentrates the whole vocabulary into a single object the eye can take in at once, and it carries, besides, the social meaning of the tradition more plainly than any other form. The cassone was the great carved chest given at a wedding — commissioned by the bride&rsquo;s family, often in a pair, to receive her trousseau and her dowry; carried through the streets in the marriage procession in full public view, so that the wealth and taste of the two houses being joined should be seen and counted. It is furniture and it is also an instrument of display, and the Renaissance made it accordingly grand.</p><p>A canonical cassone, then. It is a long rectangular chest of<em>walnut</em> —<em>noce</em>, the dense dark close-grained walnut of the Italian peninsula, the principal timber of the whole tradition. Its proportions are architectural: the front is treated not as a plank but as a facade, divided by carved pilasters into panelled bays, capped by a moulded entablature along the lid, and standing on carved lion-paw feet. The principal ornament is<em>deep-relief carving</em> cut into the solid walnut of the chest itself — classical figures, clustered putti, acanthus foliage, swags of fruit, grotesque masks — deep enough to throw a strong shadow, and drawn, motif for motif, from the architecture and sculpture of ancient Rome. On the better pieces the front is shaped as a Roman<em>sarcophagus</em>, a chest made deliberately in the form of an antique tomb. And the working hardware is iron: a wrought-iron lockplate, hasps, and corner mounts, a genuine and functional period feature, not an ornament — the chest had to secure a dowry.</p><p>The cassone states the principle, but the Renaissance interior held several other forms, and the collector should know them by name. The<em>credenza</em> is the side cupboard — a low case of cupboards and drawers on which plate and food were set out, its name carrying the old sense of the tasting by which a servant proved the food safe. The<em>cassapanca</em> is a cassone given a high panelled back, and often arms — a bench-chest, the grandest seat in the Renaissance hall. The<em>sgabello</em> is the distinctive Renaissance hall stool: a small octagonal or shaped seat carried not on four legs but on two solid carved board-trestles, often with a carved upright back-board — a form so particular to the period that it is itself nearly diagnostic. The<em>savonarola</em> and<em>dantesca</em> chairs are the two X-frame chairs descended from the Roman curule seat — the savonarola the folding one, built of many interlaced curved slats; the dantesca the heavier fixed chair, its X-frame rigid; the refectory table is a long plank top carried on two carved trestle-ends. Every one of them is built of walnut and reads as architecture.</p><figure><img src="/images/posts/italian-renaissance/detail-carving.png" alt="A close detail of Italian Renaissance walnut relief carving — classical putti, acanthus, architectural ornament"><figcaption><p>A close detail of Italian Renaissance walnut relief carving — the classical putti, acanthus, and architectural ornament drawn from the Quattrocento and Cinquecento classical-revival vocabulary.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The wood, first, because the wood is most of what one is reading for, and the most reliable single witness to age. The Italian Renaissance worked, with very few exceptions, in<em>walnut</em> —<em>noce</em> — the dense, hard, naturally dark timber of the peninsula, which takes a deep cut without splintering and so made the deep-relief carving structurally possible at all. The northern traditions reached for oak; Italy did not. On a genuine fifteenth- or sixteenth-century piece the walnut has had five centuries to age, and it shows it: a deep oxidised brown that no stain reproduces, a wax-and-handling patina in the hollows of the carving, and — the point the collector should hold on to — the shrinkage. Solid walnut shrinks across the grain over centuries, and a genuine cassone front shows it in the gapped panels, the proud mouldings, the splits that have opened along the boards and been lived with. The timber was hand-hewn besides, and the under-surfaces keep the faint scalloped record of the adze.</p><p>The carving, second, is the principal decorative register and the principal field of forgery. The Renaissance carver cut his ornament<em>into the solid walnut of the piece itself</em> — it is not an appliqué glued to a flat ground — and he cut it by hand. Hand carving leaves evidence: the depth varies, the tool has left facets that catch the light unevenly, symmetrical motifs are answered freehand and never quite mirror-perfect, and the relief is genuinely<em>deep</em>, undercut so that the figures stand nearly clear of the ground. The vocabulary is wholly classical — pilasters, entablatures, pediments, egg-and-dart and acanthus mouldings, draped figures, putti, grotesques, lion masks, lion-paw feet — and none of it was invented by the cabinet-maker. All of it was lifted, by carvers working alongside the architects, from the standing ruins of ancient Rome.</p><p>The iron, third — a genuine period feature of the chests, not a decorative afterthought, which is why it carries evidence of its own. A Renaissance cassone was a strongbox as well as a piece of furniture, and its lockplate, hasps, drop-handles, and corner mounts are<em>wrought</em> iron — forged by hand at the anvil, the surface faintly irregular, the scrolled and pierced lockplates cut and filed by a smith. Wrought iron is not cast iron, and the distinction is decisive: cast iron is poured into a mould, reproduces every casting in identical detail, and is a nineteenth-century material. A period chest carries hand-forged iron, often pitted with five centuries of corrosion; the metal alone will sometimes settle the question before one has looked at the wood.</p><p>The fourth register is the special decoration, where present, and there are two kinds. Some pieces carry<em>certosina</em> — a fine geometric micro-inlay of bone, light and dark woods, and sometimes ivory, set into the walnut in intricate star and interlace patterns, most associated with Venice and Lombardy. And some cassoni are not carved at all but<em>painted</em>: the front is a gessoed panel bearing a narrative scene in tempera — the Triumph of Love, the Continence of Scipio, a classical myth — and the grandest of these fronts were the work of named painters, so that a number now hang on museum walls as pictures, divorced from the chests they once fronted.</p><figure><img src="/images/posts/italian-renaissance/detail-panel.png" alt="A close detail of an Italian Renaissance cassone painted panel — classical narrative scene in tempera on gesso"><figcaption><p>A close detail of an Italian Renaissance cassone painted panel — a classical narrative scene (often the Triumph of Love, the Continence of Scipio, or a mythological subject) in tempera on gesso, the principal decorative surface of the marriage-chest tradition.</p></figcaption></figure><figure><img src="/images/posts/italian-renaissance/detail-iron.png" alt="A close detail of Italian Renaissance iron lockwork and corner-mounts on a cassone"><figcaption><p>A close detail of Italian Renaissance iron lockwork and corner-mounts on a cassone — the working hardware of the marriage chest, made to secure the bride&rsquo;s dowry and to last centuries.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Italian Renaissance, as a furniture period, runs across the fifteenth and sixteenth centuries — the<em>Quattrocento</em> and the<em>Cinquecento</em> — until the seventeenth-century Baroque elaborated it out of recognition. It is the earliest tradition this arc has surveyed, and it has, in consequence, no documentary pattern book of the kind the later posts have leaned on. There is no Italian Chippendale, no Hope&rsquo;s<em>Household Furniture</em>. What the period has instead is something the cabinet-maker&rsquo;s pattern book never had: the standing architecture of the Renaissance itself.</p><p>For the central fact of the period is that its furniture was made by the same hands and in the same vocabulary as its buildings. The Italian Renaissance was, before it was anything else, a deliberate revival of classical antiquity — a conscious return, by the architects and humanists of fifteenth-century Florence, to the forms and proportions of ancient Rome, of which the ruins stood all about them. The architects — Brunelleschi, Alberti, and the generation after them — drew the pilaster, the entablature, and the classical mouldings out of the antique and made of them a new architecture; and the furniture followed directly, because the carvers who cut a cassone front were the carvers who cut an altar-frame. This is why a Renaissance chest reads as a small building: it was made by men who thought architecturally because the whole culture around them had decided, as a matter of programme, to think so.</p><p>The patron was the merchant-prince and the patrician household. The Italian Renaissance was financed not by a crown — there was no Italian crown — but by the banking and trading wealth of the city-republics, and above all by Florence, where the Medici, bankers before they were anything grander, set the tone the lesser houses followed. The cassone belongs precisely to this world: the marriage of two such houses was a financial and political event, and the commissioning of a carved or painted pair of cassoni was an expenditure undertaken for the same reasons such houses commissioned an altarpiece. The grandeur of the Renaissance interior is the grandeur of a class that had money and meant it to be seen.</p><p>The antecedent the Renaissance cassone grew out of was the medieval chest — the plain, functional, iron-bound storage chest of the Italian Middle Ages, and, in its later phase, the Italian Gothic chest with its pointed-arch tracery. The medieval chest was first of all a strongbox: a rectangular box of boarded timber, bound in iron, locked, and either left plain or decorated only with simple geometric and Gothic-arched ornament. The Renaissance did not invent the marriage chest, nor the form of it. What it did was take that medieval box and elaborate it — keep the rectangular body and the iron lock, and cover the front with the classical carving and the painted narrative panel the new antiquarian taste supplied. The cassone is the medieval chest with the Renaissance poured into it.</p><figure><img src="/images/posts/italian-renaissance/antecedent.png" alt="A 14th-c Italian Gothic cassone — the medieval antecedent with simpler iron-bound construction"><figcaption><p>A 14th-c Italian Gothic cassone — the medieval antecedent with simpler iron-bound construction and either no decoration or simple geometric panels. The Renaissance period elaborated this medieval functional form with the classical-revival carving and painting.</p></figcaption></figure><p>The load-bearing distinction every collector of this period must master, however, is not between the Italian Renaissance and a neighbouring national style — that is the work of the next section — nor the chronology or the patron. It is the distinction between genuine fifteenth- and sixteenth-century work and the<em>nineteenth-century reproduction</em>, and it is worth stating without softening: genuine Italian Renaissance furniture is rare. It is five hundred years old; the best of it is museum-grade and seldom changes hands, and a collector may pass an entire career without owning a piece. The default thing a collector actually meets, when a dealer offers a &ldquo;Renaissance cassone,&rdquo; is not a piece of the Renaissance at all. It is a piece of the<em>Renaissance Revival</em> — the vast nineteenth-century reproduction industry, much of it carried on in Italy itself, in Florence and the northern cities, expressly for the furnishing of the Victorian and Gilded-Age house.</p><p>The nineteenth century admired the Renaissance enormously and reproduced it on an industrial scale, with real skill, in genuine walnut, with carving that is competent and sometimes very accomplished. The revival cassone is not a fraud in its origin — it was made and sold honestly as new furniture in the antique taste — but a century and a half has since passed, the pieces have acquired an age and a wear of their own, and they are now routinely offered, and routinely bought, as Renaissance. Telling the two apart is therefore the post&rsquo;s load-bearing knowledge, and it comes down to the period hand: the genuine piece is hand-hewn walnut with five centuries of oxidation and cross-grain shrinkage, carved by hand with the unevenness and freehand asymmetry that hand carving leaves, and fitted with hand-forged<em>wrought</em> iron; the revival piece, however accomplished, betrays the machine and the later age — uniform walnut, crisp regular carving with too-perfectly-answered motifs, frequently<em>cast</em> iron, and a contrived wear applied where the eye expects it rather than accumulated where use falls. The collector reads sceptically, because the probability, on any given piece, is that what is before one is the revival.</p><figure><img src="/images/posts/italian-renaissance/pattern-book-page.png" alt="A page from a Florentine cabinet-maker's pattern book of the 16th c — cassone, credenza, sgabello, savonarola chair"><figcaption><p>A page from a Florentine cabinet-maker&rsquo;s pattern book of the 16th c — perspective drawings of the principal Renaissance forms: the cassone marriage chest, the credenza sideboard, the sgabello stool, the savonarola folding chair, the cassapanca bench-chest.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/italian-renaissance/sibling-french-renaissance.png" alt="A French Renaissance cabinet — Henri-II French walnut tradition, related vocabulary at workshop register" loading="lazy"/><figcaption>French Renaissance<em>— the Henri-II French sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-renaissance/sibling-mudejar.png" alt="A Spanish Mudejar cabinet — Iberian Islamic-influenced geometric inlay tradition" loading="lazy"/><figcaption>Spanish Mudejar<em>— the Iberian Islamic-influenced sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-renaissance/sibling-german-renaissance.png" alt="A German Renaissance cabinet — Northern Renaissance with heavier oak and Gothic-survival vocabulary" loading="lazy"/><figcaption>German Renaissance<em>— the Northern sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-renaissance/sibling-english-tudor.png" alt="An English Tudor / Elizabethan piece — heavy oak with carved relief, the English sibling to the Italian Renaissance" loading="lazy"/><figcaption>English Tudor<em>— the English sibling</em></figcaption></figure></div><figcaption>Four styles most often confused with Italian Renaissance, drawn for comparison.</figcaption></figure><p>Four styles stand near enough to the Italian Renaissance that the beginner confuses them with it, and all four are confusions of the same kind: they are the other national Renaissances of the sixteenth century — the various ways in which the rest of Europe received the Italian original, which travelled by prints, by emigrant craftsmen, and by the translated architectural books. Each country that received it married it to its own timber and its own older tradition, and to distinguish the four is to read how far each had moved from the Florentine source.</p><p>A<em>French Renaissance</em> piece is the closest of the four, and so the one to give the most care. The sixteenth-century French court took the Italian manner directly — Italian craftsmen were brought to Fontainebleau — and the French worked, as the Italians did, in<em>walnut</em> with carved classical ornament. The high French Renaissance cabinet, the<em>armoire à deux corps</em> of the Henri-II period, is the type the collector meets, and it can deceive. The difference is one of architectural intensity: the French cabinet is more densely and sculpturally carved, with deep recession, broken pediments, and high-relief figures crowded across the whole front, where the Italian piece keeps a clearer, calmer division. The rule of thumb: clear architectural panelling on dark walnut is Italian; the densely carved, crowded two-stage walnut cabinet is French Renaissance — the pupil out-elaborating the master.</p><p>A<em>Spanish Mudejar</em> piece is the Iberian sibling, and the easiest of the four to tell apart, because Spain received the Italian Renaissance over the top of something the other countries did not have: the<em>Mudejar</em> inheritance, the Islamic decorative tradition of the long centuries of Moorish Spain. The Spanish piece is in walnut, and it may carry classical ornament; but its surface vocabulary runs to<em>geometric inlay</em> — intricate star-and-interlace marquetry of bone, ivory, and contrasting woods — and to tooled leather and iron, the canonical form being the<em>vargueño</em>, the drop-front writing-cabinet. The rule of thumb: deep-relief classical<em>carving</em> in walnut is Italian; flat geometric<em>inlay</em> of bone and wood, the Islamic pattern still legible beneath the classical, is Spanish Mudejar.</p><p>A<em>German Renaissance</em> piece is the Northern sibling, and the Northern timber settles it. The German-speaking lands received the Italian classical vocabulary late and grafted it onto a still-living Gothic tradition, working it principally in<em>oak</em> rather than the Italian walnut. The German cabinet is consequently heavier and squarer than the Italian, its classical ornament coarser and often mixed with Gothic survivals and dense strapwork. The rule of thumb: walnut, architectural, classically clear is Italian; oak, heavy, square, with Gothic survival and strapwork is German Renaissance.</p><p>An<em>English Tudor</em> piece is the English sibling, and the furthest of the four from the Florentine source. Tudor and Elizabethan England received the Renaissance latest and least directly, at second and third hand through the German and Flemish print trade, and it too worked in<em>oak</em>. The English piece carries carved relief — the bulbous &ldquo;cup-and-cover&rdquo; turned supports, gadrooned mouldings, low-relief arcaded panels, strapwork — but the classical vocabulary is partial, provincial, and often misunderstood, applied as ornament without the architectural grammar that holds an Italian piece together. The rule of thumb: walnut with a coherent classical architecture is Italian; oak, with carved relief and bulbous supports but no real architectural grammar, is English Tudor.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>wood</em>, because the wood is the surest single witness. It should be<em>walnut</em> —<em>noce</em>, dark and dense and close-grained — and not the oak of the Northern Renaissances. And it should look its age: a deep oxidised brown that no stain imitates, a waxed patina settled into the hollows of the carving, and the unmistakable evidence of five centuries of cross-grain shrinkage in the gapped panels and the long-lived-with splits. Walnut, not oak, places the piece in Italy; walnut that has genuinely aged and shrunk begins to place it in the Renaissance rather than in the revival.</p><p>One looks next at the<em>carving</em>, and reads it for the hand. The relief should be genuinely deep and undercut; the vocabulary classical and architecturally coherent — pilasters, entablature, pediment, egg-and-dart and acanthus, putti and grotesques and lion paws; and, decisively, the cut should be a hand cut, varying in depth, uneven in its facets, answering its symmetries freehand and never quite perfectly. Crisp, machine-even carving with perfectly mirrored motifs is the mark of the nineteenth-century revival.</p><p>One looks then at the<em>iron</em>, on the chests, and asks one question of it: forged or cast. Period hardware is<em>wrought</em> iron, hammered out by hand at the anvil, faintly irregular, often pitted with centuries of corrosion, never quite identical mount to mount. Cast iron, crisp and identical and poured from a mould, is a nineteenth-century material, and cast hardware will frequently settle the question against the piece before the wood is examined.</p><p>And one looks, finally and throughout, for the<em>period hand against the revival</em> — for this is the distinction the whole subject turns on. A genuine Italian Renaissance piece is rare, museum-grade, and improbable; the default thing offered as one is the accomplished nineteenth-century Renaissance Revival reproduction. The collector reads wood, carving, and iron not as a checklist of style but as a body of evidence for<em>age</em>, and asks of the word<em>Renaissance</em> what it can honestly bear: not merely that the piece is in the Renaissance manner, which the revival is too, but that the hand-hewn walnut, the hand-cut carving, and the hand-forged iron together stand witness that it was made five centuries ago, and not in the century before last.</p><p>The next post in the furniture arc will be either<em>Spanish Baroque</em> — to open the Iberian tradition the Italian Renaissance and Baroque are siblings to — or back to the<em>Italian Baroque</em> to deepen the seventeenth-century continuation that this post has named as the Renaissance&rsquo;s own descendant. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Isfahan</title><link>https://mtclinton.com/posts/isfahan/</link><pubDate>Sun, 24 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/isfahan/</guid><category>antiques</category><description>Eleventh per-subject post in Reading the Antique Rug — the central Persian court tradition's silk-warp ivory-ground apex, the Safavid-period Shah Abbas workshop and its 20th-century revival under named master-weavers whose Seirafian-grade workshops produced the finest Persian rugs of the modern era.</description><content:encoded>&lt;![CDATA[<p>The fifth post in this arc treated Kashan, and it opened the central Persian court register by setting the urban workshop against the village loom — the designed composition against the vernacular one, the fine knot against the moderate, the deep saturated wine-red ground against the soft cream of the village dye-pot. Kashan&rsquo;s sibling-plate carried, in its first corner, a rug it called the Safavid court rival, and named it Isfahan. The tenth post, on the Oushak, closed by promising that the arc would return to that rival and treat it on its own ground. This is that post. It treats Isfahan in the position the arc has reserved for the central Persian court tradition&rsquo;s silk-warp apex — the pale-ground city weaving that stands to Kashan&rsquo;s wine-red as the other half of one tradition, and that carries, more directly than any rug in this account, the freight of a great historical name.</p><p>This is the eleventh post in<em>Reading the Antique Rug</em>. The Isfahan is the second rug in the arc that one must hold in two eras at once, and the difficulty is sharper here than it was even for the Oushak. There is a Safavid Isfahan — the court carpet of Shah Abbas, woven in the royal workshops of the late sixteenth and early seventeenth centuries, among the supreme achievements of the loom in any tradition anywhere. And there is a modern Isfahan — the fine city rug of the twentieth-century revival, woven on a silk warp at extraordinary density, which is the rug the word &ldquo;Isfahan&rdquo; denotes in nearly every practical case a collector will meet. The post must carry both, and it must keep them firmly apart; that double reading, with the great name standing behind the lesser object, is one of the two load-bearing distinctions here. The other is structural, and one meets it the moment one turns the rug over.</p><h2 id="the-specimen">The Specimen</h2><p>An Isfahan that one will most commonly encounter is a modern rug — a twentieth-century weaving of the revival, and not a Safavid antiquity — and it is, in its commonest form, a piece of moderate rather than grand size: a scatter rug, a four-by-six or a small dozar, a six-by-nine on the larger examples, the format itself a consequence of how the revival workshops sold their work. The Isfahan was woven small because it was woven fine, and a fine rug at room size is an undertaking of years. The first thing to settle, before any motif is read, is the ground, because the Isfahan ground is the type&rsquo;s signature in the way the wine-red field was the Kashan&rsquo;s. It is a<em>pale</em> ground — a soft ivory, a warm cream, occasionally a pale and luminous blue — and against that pale field the design is drawn principally in indigo, with accents of a clear soft red, a celadon green, a gold. The palette is restrained and it is luminous, and the two qualities are connected: the Isfahan does not crowd its colours, it spaces them, and the pale ground lets each one register cleanly. One sets an Isfahan beside a Kashan and the relation is immediately legible — the same central Persian court vocabulary, the same designed precision, but keyed to light where the Kashan was keyed to depth. They are the two grounds of one tradition.</p><p>The design completes the specimen, and it is the classical<em>shah-abbasi</em> vocabulary, named for the Safavid ruler whose workshops fixed it. The composition is either a central medallion on an open field, or — the more characteristically Isfahan choice — an allover design with no medallion at all: a field covered edge to edge with shah-abbasi palmettes, large lobed flower-forms set on a system of scrolling vinework that runs the whole surface in a continuous, disciplined lattice. There are cloud-bands and fine floral arabesques; there are, on the best pieces, small birds and animals worked into the vinework with a draughtsman&rsquo;s confidence. The drawing is curvilinear in the strict sense — there is not a stepped or geometric form anywhere in a true Isfahan — and it is<em>disciplined</em> curvilinear drawing, which is the quality that most distinguishes the type. An Oushak medallion was loose by design and admired for the looseness; an Isfahan palmette is taut, exact, and resolved, every lobe drawn to its intended curve, and the exactness is the point.</p><figure><img src="/images/posts/isfahan/detail-medallion.png" alt="A close detail of an Isfahan central medallion — fine Safavid-derived vocabulary on ivory ground, silk warp visible at edges"><figcaption><p>A close detail of an Isfahan central medallion — the fine Safavid-derived court vocabulary on an ivory ground, the silk warp visible where the pile thins.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence, and for the Isfahan it is the load-bearing fact of the whole post — the single observation that, once made, has settled most of the attribution.<em>The modern Isfahan is woven on a silk warp.</em> One turns the rug over, parts the pile at a worn place or examines the fringe where the warp ends emerge, and the warp threads are silk: fine, strong, faintly lustrous, of a different order altogether from the cotton warp that carried the Kashan and the Tabriz and the whole northwestern Persian district. This is not decoration and it is not a flourish for the eye — silk is invisible underfoot, buried in the structure, doing nothing the buyer can see. It is doing something the buyer can<em>feel</em>. (The more ordinary commercial grades are carried on cotton; it is the fine workshop Isfahan that takes the silk warp as a matter of course, and it is the fine workshop Isfahan this post is about.) A silk warp is finer than a cotton warp and far stronger for its diameter, and a finer warp permits the weaver to set the warps closer together and tie a smaller knot between them. The silk warp is the structural enabling condition of everything else the Isfahan is admired for. It is the reason the rug can be knotted as fine as it is; it is the reason the handle is what it is. One does not buy the silk warp for itself. One buys what the silk warp made possible.</p><p>What it made possible is the knot density, and the Isfahan knot density is extraordinary. The rug is tied with the asymmetric Persian knot, as the central Persian court tradition is throughout, and the modern workshop pieces run to a fineness that the village registers of this arc could not approach and that even Kashan reached only at its silk-warp apex — three hundred knots to the square inch on ordinary good work, four hundred and well beyond on the finer workshop pieces, the very finest examples climbing past anything it is useful to quote a number for. The wool of the pile is of the highest grade, soft and tightly spun and clipped low so that the drawing reads crisply; on the best pieces the weaver sets passages of<em>silk pile</em> into the design — a highlight, a flower-head, the heart of a palmette — so that the silk catches light where the wool holds it, and the surface shifts as one walks around the rug. The handle that all of this produces is the practised hand&rsquo;s confirmation of the practised eye: a true Isfahan is firm, fine, and notably<em>flat</em> — it does not have the supple drape of the wool-foundation Oushak nor the plank-like heaviness of the Bidjar, but a thin, dense, even-tensioned body that the silk warp draws tight and keeps tight.</p><p>The last evidence is the signature, particular to the best of the modern Isfahans. The finest twentieth-century workshops signed their work — wove a small cartouche, usually into one end of the field or the border, carrying the name of the master-weaver or the atelier — and the names so woven are real, citable, and known to the trade. The most celebrated is<em>Seirafian</em>: the workshop of Hadji Agha Reza Seirafian and his sons, the most famous Isfahan atelier of the twentieth century, whose signed pieces are the benchmark of the modern type and command the upper end of its market by a wide margin. A signature is not, in itself, a guarantee — signatures are forged, and an unsigned rug from a great workshop may outweave a signed one from a lesser — but a Seirafian cartouche on a rug whose foundation, knot, and drawing all corroborate it is the documentary apex of the modern Isfahan.</p><figure><img src="/images/posts/isfahan/detail-border.png" alt="A close detail of an Isfahan main border — fine palmette repeat in silk-warp court tradition"><figcaption><p>A close detail of an Isfahan main border — the fine palmette repeat in the silk-warp court tradition, drawn at the workshop density that distinguishes Isfahan from Kashan.</p></figcaption></figure><figure><img src="/images/posts/isfahan/detail-foundation.png" alt="A close detail of an Isfahan knot-back — silk warp, fine knot density, workshop regularity"><figcaption><p>A close detail of the back of an Isfahan rug — the silk warp visible at the foundation, the fine knot density (400+ KPSI), the workshop regularity that the named master-weavers&rsquo; workshops achieved.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>Isfahan sits near the centre of the Iranian plateau, on the Zayandeh river, on the old route between the central deserts and the southern provinces; and it carries, as no other rug in this arc does, the weight of having been a capital. In 1598 Shah Abbas I — the greatest of the Safavid rulers, whose reign ran from 1588 to 1629 — transferred the seat of his empire to Isfahan and rebuilt it as the showpiece of his dynasty. The city he made was one of the wonders of the age: its great square, its blue-tiled mosques, its bridges and gardens drew the admiration of every European traveller who reached it, and the proverb the Persians coined for it — that Isfahan was half the world — was not, by the standards of 1600, an extravagant one. Into that capital Shah Abbas gathered the crafts of his empire, and among them, organised under royal patronage, were the carpet workshops. The Safavid court carpet of the Shah Abbas period — the central-medallion and the allover-shah-abbasi designs, woven in silk and in wool-on-silk at a fineness and a chromatic richness that had never been seen before and would not be matched for three centuries — is the deep antecedent of everything this post describes. It is the source of the vocabulary; it is the reason the word &ldquo;Isfahan&rdquo; carries what it carries. It is also, one must be plain about it, not the rug a collector buys.</p><p>For the Safavid achievement did not last. The dynasty declined through the seventeenth century, and in 1722 an Afghan army besieged and took Isfahan, ending Safavid rule and the royal patronage on which the great workshops depended. The eighteenth century and the early nineteenth were, for Isfahan weaving, a long quiet — the looms did not stop altogether, but the court production that had been the tradition&rsquo;s glory was gone, and the city wove, when it wove, as an ordinary provincial centre. The grand line was broken for some two hundred years.</p><p>The revival is the period the collector actually meets, and it is a twentieth-century event. From the opening decades of the century the Isfahan workshops were re-established — deliberately, and with the Safavid models consciously in view — and over the following fifty years they rebuilt the tradition to a quality that, by the middle of the century, stood comparison with anything the looms of Persia had ever produced. The revival did not copy the Safavid carpets so much as resume their grammar: the shah-abbasi palmette, the scrolling vine, the pale luminous ground, the disciplined curvilinear hand. It did so on a silk-warp foundation at knot densities that the named workshops — Seirafian foremost among them — drove steadily upward, and the finest Isfahans of the 1940s, &rsquo;50s, and &rsquo;60s are, by broad agreement of the trade, the finest Persian rugs of the modern era. The market for them survived the upheavals of the later century, and a signed mid-century Isfahan in good condition remains one of the most valuable categories of twentieth-century rug. The collector should hold the chronology plainly: the great Isfahan name is sixteenth-century and Safavid; the great Isfahan<em>rug</em>, the one with a price and a place in a house, is twentieth-century and modern. Both are Isfahan. They are separated by three hundred years and by the fall of a dynasty.</p><figure><img src="/images/posts/isfahan/antecedent.png" alt="A 16th-c Safavid Isfahan court carpet under Shah Abbas — the silk-warp court apex"><figcaption><p>A 16th-c Safavid court carpet from the Shah Abbas Isfahan workshop — the silk-warp court apex that the 1920s revival quoted directly. The classical vocabulary (central medallion, palmette border, cloud-bands) descends from this Safavid source.</p></figcaption></figure><figure><img src="/images/posts/isfahan/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the central Persian court workshops — Isfahan / Kashan / Nain / Qum"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the central Persian court workshops — the four principal sites (Isfahan, Kashan, Nain, Qum) located on a central Persia map, with archetype drawings showing the distinguishing vocabulary of each.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/isfahan/sibling-kashan.png" alt="A Kashan rug — central Persian court neighbour, deep wine-red ground rather than pale ivory, similar vocabulary, often cotton warp" loading="lazy"/><figcaption>Kashan<em>— the deep-wine court neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/isfahan/sibling-nain.png" alt="A Nain rug — 20th-c workshop tradition descended from Isfahan, pale ivory or pale blue ground, silk highlights, distinct grading by knot count" loading="lazy"/><figcaption>Nain<em>— the pale-ground 20th-c workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/isfahan/sibling-qum.png" alt="A Qum silk rug — 20th-c workshop tradition with all-silk pile, prayer-rug format, distinct from Isfahan's room-size wool" loading="lazy"/><figcaption>Qum<em>— the all-silk prayer-rug workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/isfahan/sibling-tabriz.png" alt="A Tabriz Hadji Jalili silk-warp rug — northwestern Persian counterpart to Isfahan's central court tradition" loading="lazy"/><figcaption>Tabriz<em>— the northwestern silk-warp counterpart</em></figcaption></figure></div><figcaption>Four central Persian court types most often confused with Isfahan, drawn for comparison.</figcaption></figure><p>The four types set against the Isfahan are all fine-knot workshop rugs, and three of the four are central Persian — so neither the knot nor the region will separate them, and the practised eye separates them instead by reading ground colour, foundation, format, and the fineness and finish of the drawing together. This is the working skill for the central Persian court district, and it is worth stating as plainly as the Kashan post stated its three-tier rule:<em>the central Persian court rugs are told apart not by their shared vocabulary, which is genuinely shared, but by ground colour, by foundation, and by the particular workshop fineness each centre is keyed to.</em></p><p>A<em>Kashan</em> is the type from which the arc opened this tradition, and the contrast is the cleanest of the four because it is a contrast of ground. The Kashan and the Isfahan share the central Persian court vocabulary almost entirely — both descend from the Safavid silk-warp carpets, both draw the curvilinear floral medallion, both are fine-knot workshop production — but the Kashan is keyed to a deep saturated wine-red field and the Isfahan to a pale ivory or cream one. The foundation parts them further: the Kashan is woven on a cotton warp, while the fine modern Isfahan is woven on a silk warp as a matter of course. The rule of thumb: a deep wine-red ground on a cotton warp is Kashan; a pale ivory ground on a silk warp is Isfahan.</p><p>A<em>Nain</em> is the hardest of the four, and the post must take care over it, because the Nain is the Isfahan&rsquo;s near-twin. Nain lies close to Isfahan; it began weaving fine rugs only in the twentieth century, and it began by doing precisely what Isfahan did — fine knotting, silk warp, the shah-abbasi vocabulary, and very often the same pale ivory ground, sometimes with the pale blue that Isfahan also favours. The two rugs can look, at first encounter, like one rug. The distinctions are real, but they are matters of degree and finish. The Nain palette tends to run cooler and more restricted — it leans hard on ivory and blue, and admits comparatively little of the warm red and gold an Isfahan will use; the Nain drawing, fine as it is, often reads as slightly softer and more open than the Isfahan&rsquo;s, which is the tauter and more resolved of the two. Nain grades itself openly by the number of plies in its warp, the count quoted as the rug&rsquo;s quality, and that grading vocabulary is itself a Nain habit. The rule of thumb, offered with the honest caution that this is the one distinction in the post on which a careful reader may still be wrong: a fine pale silk-warp central Persian rug with a cooler ivory-and-blue palette and a slightly softer hand is likely a Nain; the same rug with a marginally tauter drawing and a warmer palette is likely an Isfahan — and where the two cannot be told apart with confidence, the honest course is to say so.</p><p>A<em>Qum</em> moves the comparison from ground to material. Qum, like Nain, is a twentieth-century fine-rug centre that took up the central Persian court vocabulary; but the rug Qum is famous for is the<em>all-silk</em> rug — silk warp, silk weft, and silk<em>pile</em> — frequently in a prayer-rug format with a niche, and woven at a jewel-like fineness. The Isfahan, by contrast, is a wool-pile rug; it admits silk only as a highlight within a wool surface. The rule of thumb: a rug whose entire pile is silk, lustrous and shifting under the hand across its whole surface, is a Qum; a wool-pile rug with at most silk highlights is an Isfahan.</p><p>A<em>Tabriz</em> carries the comparison out of central Persia altogether, to the northwestern regional capital. The Tabriz is the other great Persian city workshop, and in its finest Hadji Jalili variant it too is woven on a pale ivory ground in a fine curvilinear court manner — which is exactly why the beginner confuses the two. But Tabriz is a northwestern rug of distinct district provenance, it generally carries a cotton warp, and the practised hand reads its handle as a different thing from the silk-warp Isfahan&rsquo;s. The rule of thumb: a pale ivory court rug from the northwest, on cotton warp, is a Tabriz; the same register on a silk warp, from the central plateau, is an Isfahan.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying an Isfahan comes down, as in the prior rug posts, to a short ordered checklist — and as the Oushak post began with the move that does the most work for a town carpet, this one begins with the move that does the most work for a court rug. That move is to turn the rug over and read the foundation.</p><p>One looks first, and principally, at the<em>warp</em>. An Isfahan of the modern revival is woven on a silk warp, and one establishes that at the fringe, where the warp ends emerge from the structure, or at any worn place where the foundation shows through the pile: silk warp is fine, strong, faintly lustrous, and unmistakably not the cotton of the northwestern district. The silk warp does the largest single piece of attributing work in the whole inspection — it places the rug in the central Persian court tradition, it rules out cotton-warp Kashan and cotton-warp Tabriz, and it confirms that the rug belongs to the fine modern workshop register rather than to any village production. One reads the warp first because the warp settles the most at one glance.</p><p>One looks next at the<em>knot density and the drawing together</em>, because in an Isfahan the two are inseparable. The knot is the fine asymmetric Persian knot, set at a density — three hundred a square inch and upward, often far upward — that the silk warp made possible; and the drawing is curvilinear shah-abbasi vocabulary, the palmette and the scrolling vine, rendered with a disciplined exactness in which every lobe is resolved to its intended curve. One looks for that exactness specifically. A loose or approximate hand, however fine the knot, is not an Isfahan; a coarse knot, however careful the hand, cannot draw the Isfahan vocabulary at all. The rug must show both — the high density and the resolved curvilinear drawing — and the two together are the type&rsquo;s working signature.</p><p>One looks at the<em>palette</em>. The Isfahan ground is pale — ivory, cream, or a luminous pale blue — and the design upon it is restrained: indigo principally, with measured accents of soft red, green, and gold, the colours spaced rather than crowded so that the pale field carries each one cleanly. A dark or saturated ground is pointing away from Isfahan, toward Kashan or another type; a pale ground crowded and chromatically busy is pointing away from the discipline that the Isfahan palette is admired for.</p><p>And one looks, last, for the<em>signature and the era</em>, holding the two Isfahans firmly apart. The overwhelming majority of Isfahans one will ever handle are modern rugs of the twentieth-century revival, and the best of them are signed — a small woven cartouche, set into field or border, carrying a workshop name, of which Seirafian is the most celebrated. One reads the cartouche for what it is, corroborates it against the foundation and the knot and the drawing rather than trusting it alone, and grades the rug within the modern revival. The Safavid Isfahan, the court carpet of the Shah Abbas period, is a museum object and is read for in museums; it is the great name standing behind the modern rug, and it is not the modern rug. The connoisseur places the Isfahan in its era first and grades it within that era second — and does not mistake a fine revival rug for a Safavid antiquity, nor think the less of it for being, honestly, the apex of the modern Persian loom rather than of the old one.</p><p>The next post in the rug arc will be either<em>Karabagh</em> — to return to the Caucasian region with the burgundy / French-rose register — or<em>Qum</em>, to extend the central Persian court tradition into the 20th-c silk-prayer-rug workshop. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>English Regency</title><link>https://mtclinton.com/posts/english-regency/</link><pubDate>Sat, 23 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/english-regency/</guid><category>antiques</category><description>Tenth per-subject post in Reading the Period Cabinet — the English late-neoclassical succession of 1800–1830, named for the Regency of the Prince of Wales (1811–1820), with dark rosewood and brass inlay, Greek-revival and Egyptian-revival vocabulary, the archaeological literalism that copies the antique rather than adapting it, and Thomas Hope and George Smith as the documentary sources.</description><content:encoded>&lt;![CDATA[<p>The ninth post in this arc treated Thomas Sheraton, and closed by promising one of two continuations: the heavier Regency succession that displaced Sheraton after 1800, or an extension of the Sheraton-and-Hepplewhite vocabulary into the post-colonial American workshops. This is the first of those — English Regency, the early-nineteenth-century English style, running from roughly 1800 to 1830, in which the late-neoclassical tradition turned from refinement to weight, from the pale satinwood of the Sheraton pair to dark rosewood, from fine wood-stringing to brass, and from a neoclassicism that adapted the antique to one that copied it. As with the Hepplewhite and Sheraton posts before it, this is a taxonomy post: a description of a type and the evidence by which one reads it, not a personal narrative. Thomas Hope&rsquo;s<em>Household Furniture and Interior Decoration</em> of 1807 and George Smith&rsquo;s<em>Collection of Designs</em> of 1808 are the documentary sources.</p><p>One fact about the Regency this post will return to repeatedly, the fact from which every distinction descends, is load-bearing in the same way the rectangular back was load-bearing for Sheraton. The Sheraton cabinet-maker, and the Hepplewhite one before him,<em>adapted</em> the antique: they took the urn and the swag and the paterae the architects had drawn from Greece and Rome, lightened them, fitted them to a chair back or a drawer front, and made of them recognisably modern furniture wearing classical ornament. The Regency cabinet-maker did something else. He<em>copied</em> the antique — copied it with a new and deliberate literalism, reproducing not the ornament of an ancient object but the object itself, its whole form and proportion. That is the boundary this post exists to establish: the Regency is archaeological classicism, and the difference between archaeology and adaptation is what one is reading for throughout.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Regency piece, for the purpose of beginning to read the style, is the side chair — canonical because it concentrates the whole vocabulary into a single object the eye can take in at once, and because it is the clearest demonstration there is of what archaeological copying means. The Sheraton chair back is a rectangle, the Hepplewhite a shield: both are forms the English workshop devised. The Regency chair is not a devised form at all. It is, very frequently, a near-literal copy of a specific ancient object — the Greek<em>klismos</em>, the light side chair of the fifth and fourth centuries before Christ, known to the Regency designer not from any surviving example but from its image on the red-figure vases the antiquarian collections of the period were rapidly accumulating. The Regency chair reproduces its shape: a back of two curved uprights sweeping outward and a single broad concave splat between them at shoulder height, the whole back leaning back from the seat in one continuous curve; and, beneath the seat, the<em>sabre leg</em> — the bold concave-curved leg drawn directly from the klismos and named for its likeness to a cavalry blade. This is the single most important member in the style. A Sheraton leg is straight, turned, reeded; a Hepplewhite leg straight, square, tapered. The Regency sabre leg is a curve — a strong, simple, concave sweep that carries the whole chair, and that no amount of adaptation produced, because it was copied, not adapted.</p><p>The chair states the principle, but the case furniture carries it as plainly as the seat furniture does. The Regency workshop made the sofa table — a long narrow table with two small hinged end-flaps, to stand behind a sofa — on lyre-shaped or Grecian-cross end-supports; it made the circular &ldquo;loo&rdquo; table, the large round table for cards and tea, on a single stout central pedestal rising from a low platform base on lion-paw feet or brass castors; it made the chiffonier, a low side cabinet with a shelved superstructure, in rosewood with a brass-trellis grille across the cupboard doors. And the archaeological habit ran further still: after Napoleon&rsquo;s Egyptian campaign of 1798 — and, more particularly, after Baron Vivant Denon&rsquo;s lavishly illustrated<em>Voyage dans la Basse et la Haute Égypte</em> of 1802 carried the measured antiquity of Egypt into the print trade — the Regency designer added Egyptian forms to his Greek and Roman ones: sphinx heads at the terminals of chair arms, lotus ornament, the tapering pylon-like leg, the whole class of work the period itself called the &ldquo;Egyptian taste.&rdquo; Chair, sofa table, loo table, chiffonier, sphinx-headed Egyptian piece — between them they set out the entire Regency manner, and every one of them is a quotation.</p><figure><img src="/images/posts/english-regency/detail-inlay.png" alt="A close detail of Regency brass inlay on rosewood — Greek-key border or laurel-wreath Buhl-work"><figcaption><p>A close detail of Regency brass inlay on rosewood — the Greek-key border or laurel-wreath repeat in the Buhl-work brass-and-rosewood combination that is the English Regency signature.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The wood, first, because the wood is most of what one is reading for, and here the Regency parts decisively from the two pale styles that preceded it. The Sheraton and Hepplewhite tradition worked in satinwood — the pale golden timber, light in colour and light in weight. The Regency turned to dark timbers, and to one above all:<em>rosewood</em> — the dense, hard, dark-brown timber, streaked with near-black, of a gravity the Sheraton register never sought. Mahogany returned to favour beside it, and the period reached also for the rarer exotic woods the expanding colonial trade was bringing in —<em>calamander</em>, the brown-and-black banded timber of Ceylon, and the boldly striped<em>zebrawood</em>. But rosewood is the type-timber, and the choice of it is not incidental: a style that meant to copy the gravity of antique marble and antique bronze wanted a wood with weight and darkness in it. The change from Sheraton is the largest change of timber in the whole English neoclassical succession — not a finer satinwood but a darker wood altogether.</p><p>The brass, second — and brass is to the Regency what the fine line of stringing was to Sheraton, the material through which the eye reads the style. The Sheraton workshop drew the architecture of a piece in a thread of dark wood let into a pale ground; the Regency reversed the contrast and changed the metal, drawing its architecture in<em>brass</em> let into the dark rosewood. The brass appears in several registers the collector should know apart. Brass<em>stringing</em> — narrow lines inlaid along every edge and panel, the direct counterpart of the Sheraton ebony line, bright metal against dark wood. Brass<em>marquetry</em> — broader cut-brass ornament, scrolling foliage and anthemion, let into the rosewood in flat sheet, a revival of the technique of the seventeenth-century French<em>ébéniste</em> André-Charles Boulle, which the Regency trade called &ldquo;buhl.&rdquo; And brass in three dimensions:<em>galleries</em>, the low pierced rails round the top of a table or cabinet;<em>mounts</em> and capitals;<em>lion-paw feet</em> and the<em>castors</em> set into them. Stringing, buhl, gallery, mount, paw, castor — the brass-on-rosewood combination is the single surest signature of the English Regency.</p><p>The ornament, third, is where the archaeological habit shows itself plainest. The Regency designer did not invent his decorative motifs; he quoted them, from a known and namable source. The<em>Greek key</em> — the running fret of right-angled meanders — runs as a border along table edges and cabinet friezes. The<em>anthemion</em> or honeysuckle, the stylised palmette of Greek architecture, sits in the centre of a chair splat or a frieze panel. The<em>lyre</em> appears as the support of a sofa-table end or the splat of a chair back. The<em>lion</em> appears entire and repeatedly: as the mask, as the paw foot, and as the<em>monopodium</em> — the carved support, drawn from Roman furniture, that combines a lion&rsquo;s head and a single lion&rsquo;s leg into one upright member at the corners of cabinets and the ends of tables. And after the Egyptian campaign the sphinx head, the lotus, and the tapering pylon leg join the Greek and Roman stock. Every motif has an ancient address, and the Regency designer meant the address to be read.</p><figure><img src="/images/posts/english-regency/detail-leg.png" alt="A close detail of a Regency sabre leg — Greek klismos-derived curving form on a chair"><figcaption><p>A close detail of a Regency sabre leg — the Greek klismos-derived curving form on a chair, brass-mounted at the foot. The same Greek-revival source that the Continental Biedermeier drew on, translated here into the English Regency register.</p></figcaption></figure><p>The construction, fourth. The Regency piece is heavier than the Sheraton piece — the frame members more substantial, the timber not pared away but allowed its weight — and the heaviness is itself the structural expression of a manner that wanted gravity. On a genuine period example the workshop hand shows in the ordinary places: hand-cut dovetails of irregular spacing, hand-laid veneer over a hide-glue ground, two centuries of shrinkage and oxidation on the backboards and undersides. But the Regency piece carries one further class of evidence the pale styles did not, and it is evidence in metal: the brass stringing and cut-brass buhl, let into the wood by hand, work loose against the rosewood over two centuries — the two materials expanding and contracting at different rates — in a way a later machine-set imitation does not reproduce. The lifting line of brass, and the fine dark gap that opens beside it, are as much a period tell as the dovetail.</p><figure><img src="/images/posts/english-regency/detail-mount.png" alt="A close detail of Regency brass hardware — ring pull, lion-mask escutcheon, Greek-key border"><figcaption><p>A close detail of Regency brass hardware — the ring pull, lion-mask escutcheon, and Greek-key border in brass that distinguish the English Regency from the contemporary French Empire ormolu.</p></figcaption></figure><p>And the pattern book, fifth — for the Regency, as for Sheraton and Hepplewhite, the published design is the document against which a piece is judged. The Regency presents that pattern book in an unusual doubled form, and the doubling is itself worth reading. There is, first, Thomas Hope&rsquo;s<em>Household Furniture and Interior Decoration</em> of 1807 — Hope being no cabinet-maker nor designer for the trade, but a wealthy connoisseur who furnished his own London house in the archaeological taste and published the engraved record of it. And there is, second, George Smith&rsquo;s<em>Collection of Designs</em> of 1808 — Smith being a trade figure, an upholsterer and cabinet-maker who took the connoisseur&rsquo;s archaeological manner and issued it as a working pattern book for the ordinary shop. Hope coined the look; Smith carried it to the trade.</p><h2 id="the-period">The Period</h2><p>The Regency takes its name from a constitutional arrangement of strictly limited duration. In 1811 the madness of George III was judged settled and permanent, and his eldest son, the Prince of Wales, was made Prince Regent to govern in his father&rsquo;s name; the arrangement lasted until the old king&rsquo;s death in 1820, when the Regent succeeded as George IV in his own right. The<em>Regency proper</em> is therefore that single decade, 1811 to 1820 — but the furniture style is not bounded by it. The archaeological manner had begun to form before 1811 and was carried on well after 1820, and the useful span this post adopts runs from about 1800 to about 1830, taking in the Regency, the further decade of George IV&rsquo;s reign, and the opening of the heavier William IV taste that followed. The style, in short, is named for the decade but lived for a generation.</p><p>What gave the style its character was a particular relation between a connoisseur, a king, and an antiquarian moment. The antiquarian moment was Europe-wide: the excavations at Pompeii and Herculaneum had been feeding accurate drawings of ancient furniture into the print trade for half a century, the publication of Greek vase collections had made the klismos a familiar shape, and Napoleon&rsquo;s expedition to Egypt had returned with a corps of scholars whose measured drawing — Denon&rsquo;s above all — put Egyptian ornament suddenly within reach. The connoisseur was Thomas Hope — of a wealthy Dutch banking family, a collector of antique marbles and vases who had travelled in Greece, Egypt, and the Levant, and who furnished his Duchess Street house in London as a set of archaeological rooms designed around his collection. In 1807 he published the engraved record of those rooms, and the book did a particular and unusual work: it gave the archaeological taste a name, an author, and a standard of correctness. The king&rsquo;s part was the part of the patron: the Prince Regent, at Carlton House in London and the Royal Pavilion at Brighton, spent on a scale that made his commissions the most visible furniture in the kingdom, and the taste he broadcast was the Greek and the archaeological. A scholar coined the look; a prince made it conspicuous.</p><figure><img src="/images/posts/english-regency/antecedent.png" alt="A Sheraton chair — the immediate predecessor in the English neoclassical succession"><figcaption><p>A Sheraton chair — the immediate predecessor. The Regency period kept the rectangular form but moved from satinwood to rosewood, from inlay to brass, from straight legs to sabre legs, and added Greek-revival and Egyptian-revival vocabulary.</p></figcaption></figure><p>The antecedent the Regency grew out of was, in the first place, Sheraton — the immediate English predecessor, treated in the post before this one. The relation is one of succession and weighting, not of opposition: the Regency kept the English neoclassical line and much of the cabinet repertory, and simply pressed the whole of it in the contrary direction to the one Sheraton had pressed it — where Sheraton had attenuated, the Regency thickened; where Sheraton had gone pale, the Regency went dark. But the Regency had a second antecedent that Sheraton did not, and it lay across the Channel. The archaeological turn — the move from adapting the antique to copying it — was a Continental movement before it was an English one: the later phase of the French Louis XVI style had already begun to take its furniture forms more literally from the antique, and the emerging French Empire style, forming in exactly the years Hope was furnishing Duchess Street, was an archaeological classicism of imperial ambition. English and French archaeology are siblings, drawing on the same Pompeian and Greek and Egyptian sources at the same moment; the difference between them is one of material and of temper, not of source.</p><p>The load-bearing distinction every Regency collector must master is therefore not, in the first place, between this style and a neighbouring one — that is the work of the next section — but the distinction this post opened with, between<em>copying</em> and<em>adapting</em> the antique. With Sheraton and Hepplewhite the antique furnished a vocabulary of ornament that the English workshop fitted to forms of its own devising; the shield back and the rectangular back are English inventions wearing classical dress. With the Regency the antique furnished the<em>form itself</em>: the klismos chair is not an English chair with Greek ornament but a Greek chair reproduced, and the sabre leg is not a leg an English designer drew but a leg copied off a vase. This changes what the collector reads for: with Sheraton one asks how fluently the published vocabulary has been realised; with the Regency one asks, additionally, how<em>literally</em> the ancient model has been quoted — because literalism of quotation is the thing the style was made to achieve.</p><figure><img src="/images/posts/english-regency/pattern-book-page.png" alt="A page from Thomas Hope's 1807 Household Furniture — Greek-revival chair, Egyptian-revival cabinet, console table"><figcaption><p>A page from Thomas Hope&rsquo;s 1807<em>Household Furniture and Interior Decoration</em> — engraved plates of the principal Regency forms: the klismos-sabre-leg chair, the Egyptian-revival cabinet with sphinx supports, the Greek-key console table.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/english-regency/sibling-french-empire.png" alt="A French Empire commode — Continental late-neoclassical with heavy gilt-bronze imperial mounts, contemporary to Regency" loading="lazy"/><figcaption>French Empire<em>— the Continental late-neoclassical counterpart</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/english-regency/sibling-sheraton.png" alt="A Sheraton rectangular-back chair — predecessor with pale satinwood and inlay rather than rosewood and brass" loading="lazy"/><figcaption>Sheraton<em>— the immediate English predecessor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/english-regency/sibling-biedermeier.png" alt="A Biedermeier Sekretär — Continental bourgeois sibling of the Regency in the same neoclassical-Greek-revival milieu, pale cherry rather than dark rosewood" loading="lazy"/><figcaption>Biedermeier<em>— the Continental bourgeois sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/english-regency/sibling-american-empire.png" alt="An American Empire piece — American sibling with heavier mahogany and brass mounts, post-1815" loading="lazy"/><figcaption>American Empire<em>— the American counterpart</em></figcaption></figure></div><figcaption>Four styles most often confused with English Regency, drawn for comparison.</figcaption></figure><p>A<em>French Empire</em> piece is the Continental counterpart — the imperial style of Napoleonic France, contemporary to the Regency almost year for year and drawing on the very same archaeological sources. This is the closest of the four distinctions, and so the one to give the most care: the temptation to treat the two as one style under two flags is real. They share the archaeological literalism — both copy the antique rather than adapting it, both quote the klismos and the sphinx and the lion monopodium — but they part sharply on material and on temper. The Regency carries its metal as<em>brass</em>: stringing and cut-brass buhl let flat into the surface of dark rosewood, the mounts modest, linear, almost draughtsman&rsquo;s. The Empire carries its metal as<em>ormolu</em> — gilt-bronze, cast in relief, chased, and mercury-gilt — applied in bold three-dimensional mounts to broad surfaces of richly figured<em>mahogany</em>; and its iconography runs to the imperial programme, the bee and the eagle and the laurelled &ldquo;N&rdquo;. The rule of thumb: brass inlaid flat into rosewood, with restraint, is Regency; gilt-bronze mounted in relief onto mahogany, with imperial display, is Empire. The first is a connoisseur&rsquo;s archaeology; the second is an emperor&rsquo;s.</p><p>A<em>Sheraton</em> piece is the immediate English predecessor — the post just before this one in the arc, the style the Regency displaced after 1800. Both are English and both neoclassical, but they sit at opposite ends of the English neoclassical succession: Sheraton is its lightest and most refined phase, the Regency its heaviest and most archaeological. Sheraton works in pale satinwood, stands its slender chairs on straight turned-and-reeded legs, draws its ornament in fine dark line-inlay, and<em>adapts</em> the antique to forms of its own; the Regency works in dark rosewood, stands its chairs on curved sabre legs, draws its ornament in brass, and<em>copies</em> antique forms outright. The rule of thumb: pale satinwood, straight slender legs, fine wood-stringing is Sheraton; dark rosewood, sabre legs, brass inlay, copied Greek and Egyptian forms is Regency — the move from one to the other being the move from refinement to weight, and from adaptation to archaeology.</p><p>A<em>Biedermeier</em> piece is the Continental bourgeois contemporary — the furniture of the German-speaking lands and Scandinavia in the same decades, 1815 to 1835, drawing on the same neoclassical milieu. The kinship is real: the Biedermeier chair, too, knows the klismos and the sabre leg. But the register is altogether different, and the difference is one of colour and of class. Biedermeier is the style of the prosperous middle-class household, not the connoisseur&rsquo;s room or the prince&rsquo;s palace, and it works characteristically in<em>pale</em> native woods — cherry, pear, birch, ash — set off by sparing dark accents, the surfaces broad and plain, the ornament minimal. The rule of thumb: dark rosewood inlaid with bright brass is Regency; pale fruitwood, broad plain veneers, and a restrained simplicity is Biedermeier. The two are cousins in form and opposites in colour.</p><p>An<em>American Empire</em> piece is the American descendant — furniture made in the workshops of the eastern United States in the decades after about 1815, taking the late-neoclassical archaeological vocabulary across the Atlantic. It knows the lion-paw foot, the sabre leg, the pedestal table, and the classical mass; but it tends to read in a heavier and a plainer register than its English parent, working characteristically in solid or boldly figured<em>mahogany</em> rather than rosewood, and leaning on bold carved ornament and gilt-stencilled decoration rather than fine brass inlay. The rule of thumb: dark rosewood with fine brass stringing and buhl is English Regency; figured mahogany with bold carving, gilt stencilling, and a heavier mass is American Empire — the connoisseur&rsquo;s archaeology of the English drawing-room against its broad-shouldered American successor.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>leg</em>, because the leg is the signature and the sabre leg is the type-specimen — and because it states, more plainly than any other member, whether one is looking at archaeology or at adaptation. The canonical Regency leg is a sabre: a bold concave curve, splaying forward at the front and back at the rear, copied directly from the Greek klismos. A straight leg, turned and reeded, points back to Sheraton; a straight square tapered leg points further back to Hepplewhite. The sabre curve, and the klismos back above it, belong to the Regency because they were quoted, not designed.</p><p>One looks next at the<em>wood and the brass together</em>, read as one combination. The piece should be dark — rosewood above all, or mahogany, calamander, or zebrawood — and the ornament carried in<em>brass</em>: fine stringing along the edges and panels, broader cut-brass buhl in the surface, galleries, mounts, lion-paw caps and castors. A pale satinwood ground with fine dark wood-stringing belongs to Sheraton; gilt-bronze mounts standing in relief on figured mahogany belong to the French Empire. The brass-on-rosewood combination is the surest single tell the style affords.</p><p>One looks then at the<em>ornament and the form together</em>. The Regency motif has an ancient address — the Greek key, the anthemion, the lyre, the lion mask and monopodium, the sphinx head and the lotus — and the Regency form is itself a copy: the klismos chair, the lion-monopodium-cornered cabinet, the pedestal loo table. One asks not merely whether the vocabulary is present but how literally the ancient model has been quoted.</p><p>And one looks, finally, at the<em>documentary standard</em>. A genuine period Regency piece is a piece of the roughly 1800–1830 English cabinet trade, worked in the archaeological manner that Hope&rsquo;s 1807<em>Household Furniture</em> coined and Smith&rsquo;s 1808<em>Collection of Designs</em> carried to the trade, and showing the period hand in its construction — the dovetails, the hide-glued veneer, the brass worked loose against the rosewood over two centuries. The collector reads leg, wood and brass, and ornament and form against those pattern books, reads the construction for date and the literalism for rank, and asks of the word<em>Regency</em> what it can honestly bear — not that the piece was made by Hope or by Smith, but that it stands faithfully in the archaeological manner the two books between them defined.</p><p>The next post in the furniture arc will be either<em>Italian Renaissance</em> — to backfill the 16th-c Italian tradition out of which the Italian Baroque emerged — or<em>American Federal</em>, to extend the late-neoclassical English influence into the new American republic. The choice will depend on the photographic material available at the time of writing.</p>
]]></content:encoded></item><item><title>Oushak</title><link>https://mtclinton.com/posts/oushak/</link><pubDate>Sat, 23 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/oushak/</guid><category>antiques</category><description>Tenth per-subject post in Reading the Antique Rug — the western Anatolian town tradition descended from the medieval 'Holbein' carpets, holding both the great classical Ushak workshop carpets of the 16th–17th centuries and the soft, pale, large-scale Oushak revival that became the principal Turkish export to the European and American decorating trade.</description><content:encoded>&lt;![CDATA[<p>The ninth post in this arc treated the Hereke — a rug made not by a place but by an institution, a state manufactory weaving silk to a master cartoon at a fineness no village could approach. It was the arc&rsquo;s high-water mark of discipline; everything in it was exact, and the exactness was the point. The Oushak is the same tradition&rsquo;s other pole. It is Anatolian, as the Hereke was Anatolian, and it is tied with the same symmetric knot — but it was woven not by a court but by a town, and it is coarse where the Hereke was fine, loose where the Hereke was true, soft where the Hereke was brilliant. This is the tenth post in<em>Reading the Antique Rug</em>, and it treats the Oushak in the position the arc has reserved for the Anatolian<em>town</em> tradition — the western Turkish weaving with the longest documented continuity of any in this account, running back through the medieval &ldquo;Holbein&rdquo; carpets of the fifteenth century, and forward into the pale, large-scale decorator&rsquo;s carpet that furnished the European and American interior for two generations.</p><p>The Oushak is the first rug in this arc that one must hold in two eras at once. There is a classical Ushak — the great medallion and star carpets of the sixteenth and seventeenth centuries, among the most important workshop carpets the Ottoman world produced, exported into Europe in such quantity that they appear, again and again, underfoot in European painting. And there is a revival Oushak — the soft, pale, large carpet of the late nineteenth and early twentieth centuries, woven for the decorating trade and beloved of it. The post must carry both, and the collector must learn to tell them apart; that double reading is one of the two load-bearing distinctions here. The other is the palette, and it is the thing one notices first.</p><h2 id="the-specimen">The Specimen</h2><p>An Oushak that one will most commonly encounter is a carpet of generous size — characteristically a room-size weaving and not a scatter rug, the size itself part of the type&rsquo;s identity, for the Oushak loom and the Oushak market were both built around the large decorative carpet. The first thing to settle, before any motif is read, is the palette, because the Oushak palette is the type&rsquo;s signature in the way the gül was the Tekke&rsquo;s and the knot density was the Hereke&rsquo;s. It is a<em>soft</em> palette, and softness here is not a euphemism for faded — it is the deliberate character of the dyeing. The grounds are apricot, a pale saffron-yellow, a chalky cinnamon, a soft and slightly greyed blue, an ivory going to cream; the red, when there is red, is a pale and dusty madder, a terracotta or a washed coral rather than the deep saturated red of a Persian field. One sets an Oushak beside a Heriz or a Kashan and the difference announces itself before a single motif is examined: the Persian rug is keyed to a strong red, and the Oushak is keyed away from it, into a register of warm pale neutrals that a decorator would later call, with some justice, the most accommodating palette in the whole of the Eastern carpet.</p><p>The design completes the specimen, and it is drawn at a scale to match the carpet. The classic Oushak composition is a large central medallion — or a pair of them, or a vertical row — set on a field that is, by the standards of Persian city weaving, conspicuously<em>sparse</em>: the medallion is large, the spandrels are large, and the ground around them is left comparatively open, scattered with a few large palmettes or arabesque sprays rather than packed with dense small ornament. The drawing itself is bold and somewhat loose. An Oushak medallion is not the taut, true, compass-drawn medallion of a Tabriz; it is a large archaic form, descended from medieval models, drawn with the slight irregularity and the generous hand of a town workshop rather than a court atelier. This looseness is not a fault. It is the aesthetic — the boldness of scale and the ease of the drawing are exactly what the type is admired for, and a reader who comes to the Oushak expecting the precision of the Hereke has brought the wrong instrument to the wrong rug.</p><figure><img src="/images/posts/oushak/detail-medallion.png" alt="A close detail of an Oushak medallion — large-scale, archaic, descended from Holbein-carpet vocabulary"><figcaption><p>A close detail of an Oushak medallion — the large-scale archaic vocabulary descended from the medieval Holbein carpets, drawn at village-loom register.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The knot is where the Oushak corrects the assumption a reader carries in from Hereke, and the correction is the reverse of the one the Hereke post had to make. The Hereke was tied with the symmetric Turkish knot at a density past the reach of any village; one might suppose, having read that, that the symmetric knot is the fine knot. It is not — the knot has no fineness of its own, only the use a weaver puts it to. The Oushak is tied with the very same symmetric knot, looped around two warps and drawn down between them, the knot of the whole Anatolian tradition; but the Oushak weaver tied it coarsely. An antique Oushak runs at a moderate-to-low knot count, the count of a town workshop weaving large carpets at a working pace, and the back of the rug shows it plainly — a knot-grain that is open and nubbed and frankly coarse, nothing like the smooth cloth-like back of a silk Hereke. This is the load-bearing structural fact of the post, and it deserves the bluntness the Bidjar handle test was given:<em>the Oushak is a coarse weave by design, and the coarseness is not a defect to be apologised for but a property of the type.</em> The Oushak&rsquo;s particular virtue — its scale, its boldness, its accommodating price — depended on a knot the weaver could lay down quickly.</p><p>The foundation is the second pillar, and it places the Oushak firmly on one side of the arc&rsquo;s first structural axis. Where the Persian rugs of this account — Heriz, Tabriz, Kashan, Bidjar — were built on cotton warps, the Oushak is an all-wool weaving: wool warp, wool weft, wool pile, the whole structure of one fibre, as the Caucasian and Turkmen rugs were. One turns an Oushak over and the warp threads visible at the back are wool, and that single observation has already done a good deal of the attributing — it has carried the rug out of Persia. The wool foundation gives the Oushak a particular handle, too: a large Oushak is supple and rather loosely built, draping and settling in a way the stiff double-wefted Bidjar never would, and the practised hand reads that looseness as quickly as the practised eye reads the palette.</p><p>The third pillar is the dyeing, and it is worth being precise about, because the Oushak&rsquo;s softness is the most imitated and least understood thing about the type. The pale palette is not, in a good antique Oushak, the result of fading — it is the result of how the wool was dyed and what it was dyed with. The Uşak district worked a dye tradition that ran to clear pale yellows, to soft apricots and salmons, to a madder used at a strength that gave terracotta and dusty coral rather than deep blood-red, and to blues kept light and slightly grey. The colours arrive pale; they were meant to be pale. The distinction matters because the later trade learned to<em>manufacture</em> softness — to chemically wash and bleach a more ordinary carpet down to a fashionable paleness — and a washed-pale rug is a different thing from a rug dyed pale. The first has had its colour taken out; the second never had strong colour to take. Reading that difference is the connoisseur&rsquo;s discipline, and the post will return to it.</p><figure><img src="/images/posts/oushak/detail-border.png" alt="A close detail of an Oushak main border — large-scale star or cartouche repeat"><figcaption><p>A close detail of an Oushak main border — large-scale star or cartouche repeat in the soft Anatolian palette.</p></figcaption></figure><figure><img src="/images/posts/oushak/detail-foundation.png" alt="A close detail of an Oushak knot-back — symmetric Turkish knot, wool foundation"><figcaption><p>A close detail of the back of an Oushak rug — the symmetric Turkish knot, the wool foundation throughout, the village-loom regularity.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Oushak takes its name from the town of Uşak in western Anatolia, inland from the Aegean coast, on the high country between Izmir and the central Anatolian plateau; and the town has been a carpet centre for as long as the Western record of Anatolian carpets exists at all. That record begins, in fact, not in Anatolia but in Europe, and not with a carpet but with a painting. The earliest Anatolian carpets one can date with confidence are dated because European painters of the fifteenth and early sixteenth centuries put them into their pictures — laid them across tables, hung them from windows, set them beneath the feet of saints and patrons — and the carpets in those paintings have been named, by long convention, for the painters who recorded them. The small-pattern and large-pattern geometric carpets of the fifteenth century are the &ldquo;Holbein&rdquo; carpets, after Hans Holbein the Younger, in whose portraits they recur; a related group of vine-and-arabesque carpets is the &ldquo;Lotto&rdquo; carpets, after Lorenzo Lotto. These are the medieval Anatolian tradition, and it is out of that tradition — the same western Anatolian district, the same symmetric knot, the same bold geometric instinct — that the classical Ushak workshop emerged. The Oushak does not begin in the nineteenth century. It begins in a Holbein portrait.</p><p>The classical Ushak carpets of the sixteenth and seventeenth centuries are the apex of the tradition and one of the high achievements of Ottoman weaving. Two great types define the classical period: the medallion-Ushak carpets, with a single large central medallion and quartered medallions in the corners set on a deep red or deep blue field; and the star-Ushak carpets, with a field repeat of large eight-pointed stars alternating with smaller lobed medallions. These were workshop carpets — large, ambitious, woven in quantity — and they were exported into Europe on a scale that nothing else in this arc matches, furnishing the great houses of Italy, the Netherlands, and England, and appearing in the inventories of European courts and the canvases of European masters for two hundred years. It is worth holding this fact against the Oushak&rsquo;s modern reputation as a gentle decorator&rsquo;s carpet, because the classical Ushak was, in its day, the most important commercial carpet in the world. The town has been weaving for the European interior, in other words, for some five centuries — the modern Oushak trade was not an invention but a resumption.</p><p>The resumption is the second era, and it is the one the collector meets most often. Through the eighteenth and earlier nineteenth centuries the Ushak workshops continued, but their grand classical period had passed. Then, from roughly the 1870s and 1880s, the European and American decorating trade discovered that it wanted exactly what western Anatolia was best placed to supply — a large carpet, boldly and simply drawn, woven in a soft pale palette that would sit quietly under furniture rather than competing with it. The Oushak revival answered that want. The looms of Uşak and the surrounding district turned out room-size carpets in apricot and saffron and washed coral, in the loose large-medallion manner, in great numbers, and they became one of the staples of the interior trade on both sides of the Atlantic. The &ldquo;decorator&rsquo;s Oushak&rdquo; — the soft, pale, large, late carpet — dates almost entirely from this revival, from the last decades of the nineteenth century into the first decades of the twentieth.</p><p>For the collector the period distinction is therefore sharper here than in any prior post, because the two eras are genuinely different objects. A classical-period Ushak — a sixteenth- or seventeenth-century medallion or star carpet — is a museum rarity, a documented antiquity of the first importance, and almost no one buying a rug will ever be choosing one. A revival Oushak is a decorative antique of the late nineteenth or early twentieth century, common enough to furnish a house, and admired on its own honest terms. Both are Oushak; both descend from the Holbein tradition; but they are separated by three hundred years and by a difference of purpose. The connoisseur reads, in nearly every practical case, for the best of the revival — and reads for it knowing the great classical tradition standing behind it.</p><figure><img src="/images/posts/oushak/antecedent.png" alt="A 15th-c Holbein carpet — the medieval Anatolian antecedent of the Oushak tradition"><figcaption><p>A 15th-c &lsquo;Holbein&rsquo; carpet — the medieval Anatolian tradition named for the painter Hans Holbein who depicted such carpets in his portraits. The Oushak tradition descends directly from this medieval village vocabulary.</p></figcaption></figure><figure><img src="/images/posts/oushak/portfolio-page.png" alt="A Victorian connoisseur's portfolio on western Anatolian rugs — Oushak / Bergama / Ghiordes / Ladik / Konya"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the western Anatolian district — district map of western Turkey locating Oushak, Bergama, Ghiordes, Ladik, Konya; archetype drawings of each sub-type.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/oushak/sibling-bergama.png" alt="A Bergama rug — nearby western Anatolian village, deeper red ground, distinct medallion" loading="lazy"/><figcaption>Bergama<em>— the nearby village neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/oushak/sibling-ladik.png" alt="A Ladik rug — Anatolian prayer-rug type with tulip vocabulary, distinct from Oushak's medallion compositions" loading="lazy"/><figcaption>Ladik<em>— the prayer-rug type</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/oushak/sibling-ghiordes.png" alt="A Ghiordes rug — Anatolian prayer-rug centre, fine workshop production, distinct from village Oushak" loading="lazy"/><figcaption>Ghiordes<em>— the Anatolian prayer-rug centre</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/oushak/sibling-konya.png" alt="A Konya rug — central Anatolian production, distinct vocabulary from western Oushak" loading="lazy"/><figcaption>Konya<em>— central Anatolian neighbour</em></figcaption></figure></div><figcaption>Four western Anatolian types most often confused with Oushak, drawn for comparison.</figcaption></figure><p>The four types set against the Oushak are all Anatolian and all tied, like the Oushak, with the symmetric Turkish knot — so the knot will not separate them, and the practised eye separates them instead by reading scale, format, and palette together. This is the working skill for the Anatolian town tradition, and it is worth stating as plainly as the gül test was stated for Tekke:<em>with an Anatolian rug, one attributes by how large the carpet is, how large the drawing is, and how soft the colour is, because all four of these neighbours share the knot and the wool.</em></p><p>A<em>Bergama</em> is the nearest geographical neighbour and the most instructive contrast. Bergama, the old Pergamon, lies in the same western Anatolian country, weaving the same symmetric knot in the same all-wool structure; but the Bergama is a<em>village</em> rug in the strict sense — a smaller, near-square format, woven for use rather than for the room — and its palette runs the opposite way from the Oushak&rsquo;s. Where the Oushak is keyed to soft pale grounds, the Bergama is keyed to a deep, strong, saturated red, with bold geometric medallions in dark blue and ivory. The rule of thumb: a large soft-pale carpet is an Oushak; a smaller near-square rug on a strong red ground, from the same district, is a Bergama.</p><p>A<em>Ladik</em> moves the comparison from format to function. Ladik, in the central Anatolian country near Konya, is known above all for its prayer rugs — single-direction pieces carrying a niche, and famous for a distinctive band of stylised tulips, panel-drawn, set above or below the niche. The Ladik is a directional rug built around a niche; the Oushak is a non-directional carpet built around a medallion. The rule of thumb: a niche and a row of tulips is a Ladik prayer rug; a centred medallion on an open field is an Oushak.</p><p>A<em>Ghiordes</em> is the contrast of fineness, and it stands to the Oushak rather as the Hereke stood to the Sivas. Ghiordes — the town that gave its name, in the Western literature, to the symmetric knot itself — was a fine Anatolian workshop centre, and its great production was the prayer rug, woven at a considerably higher knot density than any Oushak, with crisp well-drawn niche-and-column compositions. The rule of thumb: a fine, crisply drawn Anatolian prayer rug is a Ghiordes; the Oushak is the coarser, larger, looser town carpet, and makes no claim on Ghiordes fineness.</p><p>A<em>Konya</em> carries the comparison eastward, off the western district altogether, into central Anatolia. Konya — among the very oldest of all Anatolian weaving centres — produced rugs in a yellow-rich palette that can, at a glance, suggest the Oushak&rsquo;s warmth. But the Konya drawing is a smaller-scaled, more purely geometric village vocabulary, and the format is the smaller village format rather than the grand Oushak carpet. The rule of thumb: a small central-Anatolian rug in a geometric village manner is a Konya; the Oushak is the large western-Anatolian carpet, and its medallion is the archaic large-scale form descended from the Holbein tradition.</p><p>The pattern across all four is the working value of the post. One does not attribute an Anatolian rug by its knot, for the symmetric knot is common to the whole region; nor by the mere fact of wool, which is equally common. One attributes it by reading scale and format and palette together — and by recognising that the Oushak&rsquo;s particular combination, the large carpet, the large loose medallion, and the soft pale ground, is shared by none of its neighbours.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying an Oushak comes down, as in the prior rug posts, to a short ordered checklist — and as the Hereke post began with the move that does the most work for a court rug, this one begins with the move that does the most work for a town carpet. That move is to read the palette.</p><p>One looks first, and principally, at the<em>colour</em>. An Oushak offers a soft warm palette — apricot, pale saffron-yellow, chalky cinnamon, soft greyed blue, ivory and cream, a madder used pale into terracotta and dusty coral — and the absence of a strong saturated red is itself half the attribution. A large carpet keyed to warm pale neutrals, with no deep Persian red anywhere commanding the field, is pointing hard toward Oushak before a motif is read. But one reads the palette with the period question alongside it: a colour that is<em>soft</em> is right; a colour that has been<em>washed thin</em>, that shows a strong dye stripped pale by chemical bleaching, that reads as paleness imposed rather than paleness intended, is the mark of a later trade carpet dressed up for the decorator, and not the same thing as a genuine Oushak dyed pale at the dye-pot.</p><p>One looks next at the<em>scale and the drawing</em>. The Oushak is a large carpet drawn large — a generous central medallion, or a row of them, on a comparatively open and sparse field, with the ornament bold and the hand frankly loose. One does not look here for precision; one looks for the archaic large-scale medallion descended from the Holbein vocabulary, and for the easy generous drawing of a town workshop. A small rug, or a rug of taut compass-drawn precision, is not an Oushak whatever its colour.</p><p>One looks at the<em>structure</em>. The Oushak is all wool — wool warp, wool weft, wool pile — so the warp seen at the back is wool, which carries the rug out of Persia; and the symmetric Turkish knot is tied coarsely, so the back reads open and nubbed rather than fine. The handle confirms it: a large Oushak is supple and loosely built, and drapes where a stiff Persian city carpet would stand. The coarseness is not graded against the Hereke and found wanting — it is read as the correct and intended property of a large town carpet.</p><p>And one looks, last, for the<em>era</em>, holding the two Oushaks apart. The overwhelming majority of Oushaks one will ever handle are revival carpets of the late nineteenth and early twentieth centuries — decorative antiques, admired honestly for what they are. The classical Ushak, the sixteenth- or seventeenth-century medallion or star carpet, is a museum object and is read for in museums. The connoisseur places the rug in its era first and grades it within that era second, and does not mistake a good revival carpet for a classical antiquity, nor disparage it for failing to be one. The Oushak is not a court&rsquo;s rug and not a tribe&rsquo;s. It is a town&rsquo;s rug — the western Anatolian carpet that has furnished the European room for five hundred years, and the soft pale palette in the field is the measure of a tradition that learned, long ago, exactly what the West wanted underfoot.</p><p>The next post in the rug arc will be either<em>Isfahan</em> — to extend the central Persian court tradition into its silk-warp, ivory-ground apex — or<em>Karabagh</em>, to return to the Caucasian region with the burgundy and French-rose register. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Thomas Sheraton</title><link>https://mtclinton.com/posts/sheraton/</link><pubDate>Fri, 22 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/sheraton/</guid><category>antiques</category><description>Ninth per-subject post in Reading the Period Cabinet — the English neoclassical succession to Hepplewhite, Thomas Sheraton's 'Cabinet-Maker and Upholsterer's Drawing-Book' (1791–1794), with rectangular-back chairs, refined satinwood-and-ebony inlay, and the most-slender proportions of the English late-18th-c tradition before the heavier Regency took over.</description><content:encoded>&lt;![CDATA[<p>The eighth post in this arc treated George Hepplewhite, and closed by promising one of two continuations: a return to the English neoclassical line in its slightly later register, or an extension of the same vocabulary into the post-colonial American workshops. This is the first of those. It treats Thomas Sheraton as the immediate succession to Hepplewhite — the late-eighteenth-century English neoclassical refinement that pushed the cabinet tradition to its most slender and most rectilinear extreme before the heavier Regency took over after 1800. As with the two Italian posts and with Hepplewhite before it, this is a taxonomy post: a description of a type and the evidence by which one reads it, not a personal narrative. Sheraton&rsquo;s<em>Cabinet-Maker and Upholsterer&rsquo;s Drawing-Book</em>, issued in parts from 1791 and complete by 1794, is the documentary source.</p><p>There is a difficulty in the word<em>Sheraton</em> that this post will return to repeatedly, and it is the same difficulty the Hepplewhite post made its load-bearing fact — sharpened, if anything, to a finer point. The style is named for a man about whom a great deal more is known than was known of Hepplewhite, and yet it is defined no less completely by a book. Thomas Sheraton was a designer and a drawing master; whether he ever ran a cabinet-making workshop at all is doubtful, and — with a single, much-disputed exception, a glass-fronted bookcase stamped &ldquo;T.S.&rdquo; inside a drawer — not one piece of furniture has ever been securely traced to his hand. &ldquo;Sheraton furniture&rdquo; therefore does not mean, and cannot mean, furniture made by Sheraton. It means furniture worked in the manner of the<em>Drawing-Book</em>. One should hold that fact from the first page — and hold beside it the second fact this post exists to establish, which is the boundary between Sheraton and Hepplewhite: where Hepplewhite curves, Sheraton squares.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Sheraton piece, for the purpose of beginning to read the style, is the rectangular-back side chair — canonical because it concentrates the whole vocabulary into a single object the eye can take in at once, and because it states the one distinction from which every other distinction in this post descends. The Hepplewhite chair back is a closed curvilinear sweep: the shield, the oval, the heart, its outline a continuous curve. The Sheraton chair back is a rectangle — a square or oblong frame, top rail and stiles straight, the corners turning a clean architectural angle rather than a curve. Within that frame the workshop set ornament that is itself rectilinear: slender vertical splats rising from a cross-rail, a single carved or inlaid panel set in the top rail, a lattice or a row of colonnettes, the whole arrangement organised on uprights and horizontals rather than on a sweeping outline. The chair stands on straight legs of marked slenderness, frequently turned on the lathe and reeded — round in section, the surface cut with fine parallel flutes — and finishing in a small tapered or arrow foot. Where a Sheraton leg is square in section it is squarer and more attenuated than the Hepplewhite member, but it is the turned-and-reeded leg that the<em>Drawing-Book</em> prefers. The frame is pale, satinwood very often, light enough that the chair can be lifted with one hand.</p><p>This is the chair. But the<em>Drawing-Book</em> drew a great deal more, and the second thing the Sheraton manner is known for is mechanical ingenuity — furniture that does more than one thing, or does its one thing by some contrived and pleasing means. The Pembroke table with its hinged flaps; the dressing table whose top lifts to disclose a mirror and a fitted interior of small drawers; the cylinder-front secretary whose curved tambour rolls back to open the writing surface; the harlequin table, the converting bed, the library steps that fold into a stool — the<em>Drawing-Book</em> and the later<em>Cabinet Dictionary</em> are full of such &ldquo;patent&rdquo; and dual-purpose pieces, and a taste for them is as much a part of the Sheraton signature as the rectangular chair back. The rectangular-back chair and the ingenious mechanical case-piece between them set out the entire Sheraton manner; the rest of the<em>Drawing-Book</em> carries that manner across the remaining furniture of the house.</p><figure><img src="/images/posts/sheraton/detail-back.png" alt="A close detail of a Sheraton rectangular-back chair — slender vertical splats, satinwood-and-ebony inlay top-rail"><figcaption><p>A close detail of a Sheraton rectangular-back chair — the slender vertical splats and the satinwood-and-ebony inlay top-rail. The rectangular form distinguishes Sheraton from the Hepplewhite shield-back at first glance.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The wood, first, because the wood is most of what one is reading for, and here the Sheraton tradition stands very close to the Hepplewhite one. Both worked in satinwood — the pale golden-yellow timber, hard and close-grained, capable of a high lustrous polish — and where a piece is not satinwood throughout it is very often a mahogany ground crossbanded and strung in satinwood and other pale woods. The change from Hepplewhite is not a change of timber but a change of degree. The Sheraton register is the finer of the two: the satinwood more often figured and chosen for its grain, the contrasting woods more various, the whole surface treated as a field for the most delicate inlay the English trade produced before the Regency coarsened it.</p><p>The ornament, second. The Sheraton cabinet-maker, like the Hepplewhite one, laid his ornament onto the surface rather than carving it into the wood, and two techniques carry the work: painted decoration — the satinwood ground painted with neoclassical motifs, figurative medallions, festoons and trophies — and inlay. But the inlay register is where the eye learns to part Sheraton from Hepplewhite. The Sheraton inlay runs to fine line and stringing: narrow bands of ebony, holly, or boxwood let into the pale ground along the edge of every panel, every drawer front, every leg, drawing the architecture of the piece in a thread of dark against light. Where the Hepplewhite marquetry tends to the broader pictorial motif — the inlaid urn, the shaded husk-chain, the figured paterae — the Sheraton tends to the linear: the contrast made by the line itself, the panel framed and subdivided by stringing. It is the difference between a drawing shaded in mass and a drawing built up in line.</p><figure><img src="/images/posts/sheraton/detail-inlay.png" alt="A close detail of Sheraton satinwood-and-ebony stringing — fine line-inlay along panel edges"><figcaption><p>A close detail of Sheraton satinwood-and-ebony stringing — the fine line-inlay along panel edges that distinguishes the Sheraton register from the broader Hepplewhite inlay.</p></figcaption></figure><p>The leg, third, and the leg is the second great discriminator after the chair back. The Hepplewhite leg is straight, square in section, evenly tapered, and finished with a small spade foot — an architectural support drawn from the classical column. The Sheraton leg keeps the straightness and the slenderness and presses both further. It is frequently turned on the lathe rather than cut square — round in section, swelling slightly or running true, and characteristically reeded, its surface worked into fine parallel convex flutes that catch the light in a row of bright lines. It ends in a small turned foot, a tapered foot, or the slight arrow form. Where it is square in section it is squarer and more attenuated than the Hepplewhite leg, and altogether the Sheraton chair stands taller and thinner on the floor: the vertical emphasis that runs through the whole style is nowhere plainer than in the leg.</p><figure><img src="/images/posts/sheraton/detail-leg.png" alt="A close detail of a Sheraton turned and reeded round-section leg"><figcaption><p>A close detail of the Sheraton leg — slender, turned on the lathe and round in section, characteristically reeded, distinct from the Hepplewhite square-tapered leg with its spade foot.</p></figcaption></figure><p>The construction, fourth. The Sheraton piece is light, and its lightness is the structural expression of the style — slender frame members, thin crossbanded veneers, a paring-away of timber carried a step beyond Hepplewhite. On a genuine period example this delicate workshop construction shows the period hand: hand-cut dovetails of irregular spacing, pit-sawn or hand-planed secondary timber, hand-laid veneer over a hide-glue ground, two centuries of shrinkage and oxidation on the backboards and undersides. And where the piece is one of the mechanical sorts — the rising mirror, the rolling tambour, the converting bed — the construction is to be read for the contrivance itself: the runners, hinges, counterweights, and small fitted interior, all of which the period workshop made by hand and a later imitation tends to simplify.</p><p>And the<em>Drawing-Book</em>, fifth — at once the evidence of last resort and of first resort, because for Sheraton, as for Hepplewhite, the pattern book is not a supplement to the furniture but the definition of it. The plates of the 1791–1794<em>Drawing-Book</em>, and afterwards of the<em>Cabinet Dictionary</em> of 1803, are the document against which a piece is judged to be &ldquo;in the Sheraton manner.&rdquo; There is no maker&rsquo;s stamp to find, no workshop label; there is only the question of whether the form, the ornament, and the proportion answer to the engraved plates. This is an unusual position for a style to occupy, and the next section sets out why.</p><h2 id="the-period">The Period</h2><p>The Sheraton period proper runs from about 1790 to 1805, a span as short and as sharply bounded as the Hepplewhite one — at its beginning by the<em>Drawing-Book</em>, at its close by the rise of the heavier Regency taste after 1800. The man whose name it carries is, unlike Hepplewhite, not a documentary blank; what is remarkable about him is something else. Thomas Sheraton was born at Stockton-on-Tees in 1751, and was by trade and by inclination a journeyman cabinet-maker, a drawing master, and — increasingly, as his life went on — a writer and a religious controversialist. He came to London about 1790, and there, rather than opening a workshop, set himself to teaching drawing and to publishing. The<em>Cabinet-Maker and Upholsterer&rsquo;s Drawing-Book</em> appeared in parts from 1791, was complete in 1793, and was followed within a year by an Appendix and an Accompaniment; the<em>Cabinet Dictionary</em> came in 1803; and the unfinished<em>Cabinet-Maker, Upholsterer and General Artist&rsquo;s Encyclopaedia</em> occupied his last years, 1804 to 1806. He died in 1806, in poverty — a contemporary who visited him recorded a man living in two mean rooms, in evident want, supporting a wife and children by his pen and his teaching. The style that bears his name made fortunes for the cabinet trade and none at all for Sheraton.</p><p>What the<em>Drawing-Book</em> translated into the trade was the same neoclassicism the architects had set going a generation earlier — the painted ceilings and slender plaster relief of Robert Adam, the urn and swag and paterae drawn from the antique. Hepplewhite had already taken that architect-led vocabulary down off the wall and into a trade pattern book. What Sheraton did was to take Hepplewhite&rsquo;s pattern book and refine it: to square what Hepplewhite had curved, to attenuate what Hepplewhite had already made slender, to substitute the fine line for the broad inlaid motif, and to add the whole class of ingenious mechanical furniture the<em>Drawing-Book</em> delighted in. The relation is one of succession and correction, not of opposition. Sheraton&rsquo;s book was published while the third edition of Hepplewhite&rsquo;s<em>Guide</em> was still being revised, and through the 1790s the two designs were current together — a great deal of the furniture of the decade could be referred to either book with equal honesty.</p><figure><img src="/images/posts/sheraton/antecedent.png" alt="A Hepplewhite shield-back chair — the immediate predecessor in the English neoclassical succession"><figcaption><p>A Hepplewhite shield-back chair — the immediate predecessor in the English neoclassical succession. The Sheraton period kept the pale satinwood and the neoclassical vocabulary but moved from the shield to the rectangle and refined the inlay further.</p></figcaption></figure><p>The load-bearing distinction every Sheraton collector must master is therefore not, in the first place, a distinction between this style and a neighbouring one — that is the work of the next section — but a distinction internal to the word<em>Sheraton</em> itself, and it is the attribution problem in an even purer form than Hepplewhite presented it. With Hepplewhite one could at least say that a cabinet-making shop in Cripplegate had existed, and that a widow had run it, even if no furniture could be traced to it. With Sheraton the workshop itself is in doubt. There is no evidence that Thomas Sheraton ever employed a single journeyman or sold a single chair. He was a designer and a drawing master who published books; the books were worked from by hundreds of cabinet-making shops across Britain and beyond; and &ldquo;Sheraton furniture&rdquo; is the furniture those shops made. When a dealer, an auction catalogue, or a museum label says &ldquo;Sheraton,&rdquo; the word does not — cannot — mean &ldquo;made by Sheraton.&rdquo; It means &ldquo;made in the manner of the<em>Drawing-Book</em>,&rdquo; and the<em>Drawing-Book</em> was a public document any shop was free to consult and copy. The style is a book, and behind the book there is, more nearly than with any other style in this arc, no maker at all.</p><p>This inverts the ordinary logic of attribution in the same way Hepplewhite inverted it, and the grading of a piece runs along the same two axes that must be kept apart. The first is<em>date</em> — a piece of the 1790–1805 period, or a later piece worked in the same idiom, since the<em>Drawing-Book</em> stayed in use long after the period closed and the later-nineteenth-century &ldquo;Sheraton revival&rdquo; produced a great quantity of honest decorative furniture in the manner that is not period work. The second is<em>quality</em> — how fluently the published vocabulary has been realised, since a single plate could be executed by a London shop of the first rank in figured satinwood with painted medallions, or by a country shop in plain mahogany with a single line of inlay, and both are legitimately &ldquo;Sheraton.&rdquo; The collector keeps date and quality apart, and asks of the word<em>Sheraton</em> only what it can honestly bear: not who made the piece, which is unanswerable, but whether it is faithfully in the manner of the book.</p><figure><img src="/images/posts/sheraton/pattern-book-page.png" alt="A page from Sheraton's 1791 Drawing-Book — rectangular-back chair, secretary, library table, dressing table"><figcaption><p>A page from Sheraton&rsquo;s 1791–1794<em>Drawing-Book</em> — engraved plates showing the canonical Sheraton forms: the rectangular-back side chair, the cylinder-front secretary, the library table with reeded legs, the dressing table with hinged mirror.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/sheraton/sibling-hepplewhite.png" alt="A Hepplewhite shield-back chair — predecessor with shield back rather than rectangle" loading="lazy"/><figcaption>Hepplewhite<em>— the immediate predecessor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/sheraton/sibling-english-regency.png" alt="An English Regency chair — heavier rosewood + brass-inlay successor, post-1800" loading="lazy"/><figcaption>English Regency<em>— the heavier successor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/sheraton/sibling-french-empire.png" alt="A French Empire chair — Continental late-neoclassical with heavier mahogany and gilt-bronze mounts" loading="lazy"/><figcaption>French Empire<em>— the Continental late-neoclassical</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/sheraton/sibling-american-federal.png" alt="An American Federal chair — colonial American descendant of Sheraton and Hepplewhite, often combining both registers" loading="lazy"/><figcaption>American Federal<em>— the colonial American descendant</em></figcaption></figure></div><figcaption>Four styles most often confused with Sheraton, drawn for comparison.</figcaption></figure><p>A<em>Hepplewhite</em> is the immediate predecessor — the post just before this one in the arc, the style Sheraton&rsquo;s<em>Drawing-Book</em> answered and refined — and this is the hardest of the four distinctions to draw, because it is the closest, and so the one to give real care. The two pattern books overlap heavily. Both are English, both neoclassical, both work in pale satinwood with painted and inlaid ornament, both stand their chairs on slender tapered legs, and a great deal of 1790s furniture could be referred to either book without dishonesty. The distinction lies principally in the chair back, and after that in the leg and the inlay. The Hepplewhite back is curvilinear and closed — the shield, the oval, the heart, an outline that is a continuous sweeping curve. The Sheraton back is rectangular — a square or oblong frame, top rail and stiles straight, the ornament arranged on vertical splats and horizontal cross-rails within it. The Hepplewhite leg is square in section and often spade-footed; the Sheraton leg is frequently turned, round in section, reeded on the lathe, and more slender still. And the Hepplewhite inlay tends to the broad pictorial motif, the Sheraton to fine line and stringing. The rule of thumb: a curvilinear open back on a square tapered leg with spade foot is Hepplewhite; a rectangular back on a slender turned-and-reeded leg, the inlay run in fine dark line, is Sheraton. The rule is sound on the whole — but the honest collector concedes that the two books shade into one another, and that &ldquo;Hepplewhite-Sheraton&rdquo; is a defensible label for a great many pieces on the boundary.</p><p>An<em>English Regency</em> piece is the heavier successor — the style that displaced Sheraton after about 1805. Where Sheraton is the lightest and most slender phase of English neoclassicism, the Regency is its weighting and its archaeological hardening. The Regency turned from pale satinwood to dark woods — rosewood above all, and mahogany again — and from fine wood-stringing to brass: brass inlay let into the dark ground, brass galleries, brass paw feet and mounts. Its neoclassicism is more literal, drawing directly on Greek, Roman, and Egyptian models — the sabre leg, the klismos chair, the sphinx and the lion mask. The rule of thumb: pale satinwood, slender turned legs, and fine line-inlay is Sheraton; dark rosewood, sabre legs, brass inlay, and a heavier archaeological vocabulary is Regency. The move from one to the other is the move from refinement to weight.</p><p>A<em>French Empire</em> piece is the Continental late-neoclassical contemporary — the imperial style of Napoleonic France, parallel in date to the close of Sheraton and the opening of the Regency. It shares the literal, archaeological neoclassicism, but the register is altogether different: Empire works in dark, richly figured mahogany, builds in broad architectural masses rather than slender frames, and carries its ornament in gilt-bronze mounts — ormolu sphinxes, swans, victories, classical heads — applied to plain veneered surfaces. The rule of thumb: light English satinwood with inlaid line-ornament is Sheraton; massive French mahogany with applied gilt-bronze mounts is Empire. The first is a drawing-master&rsquo;s economy of line; the second is an imperial display of metal.</p><p>An<em>American Federal</em> piece is the colonial American descendant — furniture made in the American workshops of the Atlantic seaboard in the decades after Independence, working directly from both the Hepplewhite<em>Guide</em> and the Sheraton<em>Drawing-Book</em>, frequently from both at once. The distinction here is genuinely difficult, and at first glance often impossible, because the American cabinet-makers were working from the very same plates. The Federal piece tends to read in a slightly plainer register — often in mahogany with satinwood inlay rather than figured satinwood throughout, frequently combining a Sheraton rectangular back with Hepplewhite detailing or the reverse — and it shows the secondary woods of the American forest, tulip poplar and white pine, in its drawer linings and backboards rather than the oak and deal of the English shop. The rule of thumb: the English Sheraton piece works toward figured satinwood, fine line-inlay, and English secondary woods; the American Federal piece works more often in inlaid mahogany, mixes the two pattern books freely, and shows American secondary timber — and the secondary wood, examined on the underside, is frequently the most reliable tell of all.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>form of the chair back</em>, because the back is the signature and the rectangular back is the type-specimen — and because it is the back that parts Sheraton from Hepplewhite at a glance. The canonical Sheraton back is a rectangle: a square or oblong frame, top rail and stiles straight, the corners turning a clean angle, the ornament within it arranged on slender vertical splats and horizontal cross-rails. A closed curvilinear back — the shield, the oval, the heart — points toward Hepplewhite; a heavier back with a sabre-curved stile and an archaeological vocabulary points forward to the Regency.</p><p>One looks next at the<em>leg</em>, the second great discriminator. The Sheraton leg is straight and markedly slender, and characteristically it is turned on the lathe — round in section, reeded with fine parallel flutes — finishing in a small turned, tapered, or arrow foot. A leg square in section, more substantial, ending in a spade foot leans toward Hepplewhite; a sabre leg, curved like a cavalry blade, belongs to the Regency. The slender turned-and-reeded leg, and the tall thin stance it gives the chair, is the Sheraton member.</p><p>One looks then at the<em>wood and the inlay together</em>. The piece should be pale — satinwood throughout, or a mahogany ground crossbanded and strung in pale woods — and the ornament should run to fine line: narrow bands of ebony, holly, or boxwood stringing let into the surface along every edge and panel. A broader pictorial inlay, the shaded urn and husk-chain, leans toward Hepplewhite; a dark rosewood ground inlaid with brass belongs to the Regency; applied gilt-bronze mounts on figured mahogany belong to the French Empire. And one keeps in mind the<em>mechanical character</em> of much of the Sheraton repertory — the rising mirror, the rolling tambour, the converting and dual-purpose piece — a taste for ingenuity that is itself part of the signature.</p><p>And one looks, finally, at the<em>question of attribution itself</em> — which is to say, one keeps in mind throughout that there is no maker to find, and that here there may not even have been a workshop. A genuine period Sheraton piece is a piece of the 1790–1805 English cabinet trade, worked from or closely after the plates of the<em>Drawing-Book</em>, and showing the period hand in its construction; what it is not, and what virtually no piece of Sheraton furniture has ever been shown to be, is the documented work of Thomas Sheraton himself, the drawing master and writer who died poor. The collector reads form, leg, wood, and inlay against the<em>Drawing-Book</em>; reads the construction for date; reads the quality for rank; and asks of the word<em>Sheraton</em> only what it can honestly bear — that the piece is in the manner of the book, made by one of the many shops that worked from it, in the short and well-defined period the book defined.</p><p>The next post in the furniture arc will be either<em>English Regency</em> — to set out the heavier Regency succession after 1800 — or<em>American Federal</em>, to extend the Sheraton-and-Hepplewhite vocabulary into the post-colonial American workshops. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Hereke</title><link>https://mtclinton.com/posts/hereke/</link><pubDate>Fri, 22 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/hereke/</guid><category>antiques</category><description>Ninth per-subject post in Reading the Antique Rug — the 19th-c Ottoman imperial court silk manufactory founded 1843 at Hereke on the Sea of Marmara, opening the Anatolian court tradition with its jewel-tone multicolor silk palette, its extreme knot density, and the revivalist design vocabulary of a state atelier executing master cartoons.</description><content:encoded>&lt;![CDATA[<p>The eight prior posts in this arc divided cleanly among three weaving worlds. The Persian —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>,<a href="/posts/bakshaish/">Bakshaish</a>,<a href="/posts/kashan/">Kashan</a>,<a href="/posts/bidjar/">Bidjar</a>,<a href="/posts/hamadan/">Hamadan</a> — was the largest of them, and within it the arc ran from the district vernacular to the city workshop and back. The Caucasian highland tradition the<a href="/posts/caucasian-kazak/">Kazak</a> post treated. And most recently<a href="/posts/tekke/">Tekke</a> opened the third world, the Turkmen tribal weaving of the central Asian steppe. What every one of those eight shares — the city weaving and the village weaving and the tribal weaving alike — is that each was made<em>by</em> a place: a town one can name, a district one can map, a tribe one can locate. Hereke belongs to none of those categories. It was made by an institution. This is the ninth post in<em>Reading the Antique Rug</em>, and it treats the Hereke in the position the arc has reserved for the opening of the Anatolian tradition — and, more particularly, the Ottoman<em>court</em> tradition, the weaving commissioned and controlled by a state.</p><p>It breaks the palette as decisively as anything the arc has done, and it breaks it in the opposite direction from Tekke. Where the Tekke carried a single dark madder-brown across a whole tribal production, the Hereke carries no single ground colour at all; it is a multicolor weaving, a jewel-tone field of ivory and gold and jade and rose and indigo set against one another with a deliberate, designed brilliance that no village loom would attempt and no village dyer could supply. But colour, as the prior posts have insisted, is the thing one notices first and trusts last. What organises the Hereke is not its palette but its<em>fineness</em> — the knot density and the silk that carries it, the extreme count of small symmetric knots that places a good Hereke beyond the reach of any village and most cities, and identifies it, before any motif is read, as the product of an imperial manufactory. That fineness, with the material that makes it possible, is the load-bearing collector distinction for the whole of this post, and it will be carried the way the Tekke post carried the gül and the Bidjar post carried the handle test.</p><h2 id="the-specimen">The Specimen</h2><p>A Hereke that one will encounter is, in its commonest fine form, a piece of modest proportions — the silk Hereke was a precious object woven slowly, and the great majority of antique silk pieces are small, prayer-rug or scatter sizes rather than carpets, the room-size silk Hereke being a rarity reserved for the most lavish commissions. The first thing to settle, before any motif is read, is the inverse of the thing the Tekke post had to settle first. There is no tribe anywhere in this account, and no village either. The Hereke rug is a workshop rug from the first knot to the last; more than that, it is the rug of a single, particular workshop — a state manufactory, established and directed by the Ottoman court, executing designs drawn for it by professional designers on professional cartoons. The whole apparatus the Tekke post found absent — the building, the master designer, the commissioned object — is here not merely present but is the entire condition of the thing.</p><p>The material is the signature, and one must distinguish two grades of it at the outset. The finest Hereke is woven entirely of silk — silk warp, silk weft, and silk pile, the whole structure of one lustrous fibre — and on the very grandest pieces the silk is supplemented by brocaded areas of metal thread, flattened gold or silver wire worked into the ground to catch the light. Below that grade sits the Hereke woven with a wool pile, very often still on a fine cotton or silk warp, a workshop rug of high quality but without the particular preciousness of the all-silk piece. Both are Hereke; both come from the same manufactory; but it is the silk grade that the tradition is known by, and the silk grade the collector is principally reading for. The composition is itself an attribution: an all-silk rug of extreme fineness, multicolor and court-drawn, is pointing hard toward Hereke before one has looked at a single flower.</p><p>The design is the eclectic, the recombined, the deliberately quoted. A classic Hereke carries a central medallion on an open field, framed by a many-banded border of palmette and vine — and the vocabulary of that medallion and that border is, as often as not, Persian. The Ottoman court manufactory drew freely on the Safavid classics, on its own older Ottoman ornament, and on European pattern besides, and recombined them to a master cartoon. The palette completes the specimen: ivory grounds, fields of clear jade-green or soft rose, a gold that the silk takes with a particular warmth, accents of deep indigo — a multicolor jewel-tone scheme of designed brilliance, the opposite in every way of the disciplined single ground the Turkmen post described.</p><figure><img src="/images/posts/hereke/detail-medallion.png" alt="A close detail of a Hereke central medallion — fine court vocabulary in jewel-tone silk on ivory ground"><figcaption><p>A close detail of a Hereke central medallion — the fine Persian-influenced court vocabulary in jewel-tone silk on an ivory ground, drawn at workshop density.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The knot is where the Hereke declares itself most plainly, and it is the first place the post must correct an assumption a reader might carry in from Tekke. The Tekke, a tribal rug, was tied with the asymmetric knot; one might suppose the asymmetric knot to be the fine knot, since the Tekke was the fine tribal weaving. It is not so. The Hereke is tied with the<em>symmetric</em> knot — the Turkish knot, looped around two warps and drawn down between them — which is the knot of the whole Anatolian tradition, and the Hereke achieves with it a density that no Turkmen tribe and few Persian cities ever approached. A good antique silk Hereke runs into the high hundreds of knots to the square inch — that is the workhorse count for a fine piece — and the rare showpiece, the rug woven small and slow as a deliberate extravagance, can climb past a thousand and into the four-figure range, a fineness at the absolute limit of what a hand can tie. This is the load-bearing fact of the post, and it is worth stating with the bluntness the Bidjar handle test was stated with:<em>the Hereke is identified, before all else, by a knot density that is simply not available to a village or a tribe.</em> Fineness on this scale is an industrial achievement in the literal sense — it requires a manufactory, a fine silk, professional weavers, and a state willing to pay for the months a single rug consumes.</p><p>The fineness is legible on the back. One turns a Hereke over, and the knot-grain reads almost as a woven cloth rather than as a pile rug — the knots so small and so densely packed that the back has a smooth, fine, slightly granular surface with none of the coarse nubbed texture a village rug shows. On the all-silk grade the warp and weft seen at the back are themselves silk, fine and lustrous. This evenness is itself evidence of a second kind. A tribal rug is irregular because a tribal weaver wove from memory; the Hereke is regular — its medallion drawn true, its border repeats matched corner to corner, its curved lines carried smoothly through the pile — because the Hereke weaver worked from a cartoon under a quality control that a state manufactory could enforce. Where the Tekke post read the tribal hand&rsquo;s small irregularities as the proof of authenticity, the Hereke post reads the absence of them: the disciplined exactness is the workshop&rsquo;s signature, written into every knot.</p><p>The third pillar of the evidence is the silk itself, and a particular thing it does. Silk takes dye with a depth and a luminosity that wool cannot match — the same indigo, the same madder, the same yellow read brighter and clearer on silk, because the fibre is translucent and the light enters it — and the Hereke palette depends on this. The jewel tones are not a matter of unusual dyestuffs but of an ordinary dyer&rsquo;s chemistry carried on a fibre that lets it shine. Silk does one further thing that no photograph records: it changes colour with the angle of the light, so that a Hereke shifts and glints as one walks past it, a field of rose reading pale from one side and deep from the other. Some documented Hereke pieces also carry a woven mark — a workshop signature or an inscription cartouche — and where one is present it is corroborating evidence; but the mark is far from universal, and the collector who has read the knot and the silk and the discipline correctly does not need it.</p><figure><img src="/images/posts/hereke/detail-border.png" alt="A close detail of a Hereke main border — fine palmette repeat in silk pile"><figcaption><p>A close detail of a Hereke main border — the fine palmette repeat in silk pile at workshop density, the court vocabulary of the Ottoman state workshop.</p></figcaption></figure><figure><img src="/images/posts/hereke/detail-foundation.png" alt="A close detail of a Hereke knot-back — extreme density, silk foundation"><figcaption><p>A close detail of the back of a Hereke rug — the extreme knot density visible at the foundation level, the silk warp and weft of the all-silk variant.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Hereke manufactory was founded in the early 1840s — the sources do not quite agree, giving 1841 or 1843 for the founding and 1845 for the start of operations under settled palace patronage — on the Sea of Marmara coast at the small town of Hereke, on the gulf that runs inland toward Izmit east of the capital; and it was founded not as a carpet works at all, but as a silk-and-textile mill. This is the fact from which the whole institution must be understood. Sultan Abdülmecid I established it in the first years of his reign, in the period of the Tanzimat, the long programme of administrative and industrial reform by which the Ottoman state set out to modernise itself from above; and the Hereke mill was a Tanzimat enterprise of exactly the characteristic kind, a state manufactory raised to supply the court&rsquo;s own demand for fine cloth. For its first half-century the looms of Hereke wove silk furnishing fabric, upholstery, and dress silk for the imperial palaces. The carpet was a later addition. It was only from about the 1890s, under Abdülhamid II, that the manufactory took up the knotted pile carpet in earnest, gathering skilled weavers and setting them to produce silk court carpets of the highest grade — and it is that production, the silk Hereke carpet of the last Ottoman decades, that this post is principally concerned with.</p><p>The Hereke carpet was, from the first, a court object rather than a market one. It furnished the palaces of the Sultan; it was given as a diplomatic gift to foreign sovereigns and embassies, a piece of woven statecraft, an Ottoman silk carpet arriving at a European court as a deliberate demonstration of what the empire could still command. This origin explains the eclecticism the specimen described. A manufactory whose purpose is to display the court&rsquo;s reach does not weave a folk tradition; it weaves the best of every tradition it can reach, and the Hereke designers accordingly drew Safavid Persian medallions, classical Ottoman ornament, and European motifs into a single recombined repertoire. The point bears stating directly, because it is the one place a reader new to Hereke is most apt to go wrong: a Hereke design is, characteristically, a<em>quotation</em> — not the slow evolved vocabulary of a place but the considered selection of a state atelier, executed by master designers to order. To ask what the &ldquo;authentic Hereke pattern&rdquo; is, in the sense one asks what the authentic Tekke gül is, is to ask a question the manufactory was not built to answer.</p><p>The Hereke survived the empire. The manufactory did not close with the Ottoman state; it carried on into the Turkish Republic after 1923, and silk Hereke production continues to the present day, the name now also widely imitated by other Turkish workshops weaving fine silk rugs for the export trade. For the collector the period distinction is therefore the same one the Tekke post drew at Geok Tepe and the Hamadan post drew at the 1880s export boom, only here it falls inside a single named workshop rather than between the tribe and the market. The antique Hereke — the court silk carpet of roughly the 1890s to the early twentieth century, woven for the palace and the diplomatic gift, to the manufactory&rsquo;s own highest standard — is the rug the connoisseur reads for.</p><figure><img src="/images/posts/hereke/antecedent.png" alt="A 16th-c Ottoman Bursa / Istanbul court silk workshop carpet — the older Ottoman court silk tradition"><figcaption><p>A 16th-c Ottoman Bursa or Istanbul court silk workshop carpet — the older Ottoman court silk tradition that Hereke quoted at its founding. The court silk vocabulary (Persian-influenced medallion, palmette borders, jewel-tone palette) descends from this earlier production.</p></figcaption></figure><figure><img src="/images/posts/hereke/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the Ottoman court workshops — Hereke / Kum Kapı / Sivas / Bursa"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Ottoman court silk workshops — the four principal sites (Hereke, Kum Kapı in Istanbul, Sivas, Bursa) with archetype drawings showing the distinctive vocabulary of each.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/hereke/sibling-kumkapi.png" alt="A Kum Kapı rug — Istanbul court silk workshop production, very similar to Hereke but slightly different drawing vocabulary, late-19th to early-20th c" loading="lazy"/><figcaption>Kum Kapı<em>— the Istanbul court workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hereke/sibling-sivas.png" alt="A Sivas rug — Anatolian commercial workshop, wool not silk, similar court-influenced design at lower price point" loading="lazy"/><figcaption>Sivas<em>— the Anatolian commercial workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hereke/sibling-bursa.png" alt="A Bursa silk rug — the older Ottoman silk centre, pre-Hereke tradition, related vocabulary" loading="lazy"/><figcaption>Bursa<em>— the older Ottoman silk centre</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hereke/sibling-tabriz.png" alt="A Tabriz silk-warp Hadji Jalili rug — the Persian court counterpart whose vocabulary the Ottoman court emulated" loading="lazy"/><figcaption>Tabriz<em>— the Persian court counterpart</em></figcaption></figure></div><figcaption>Four court / fine traditions most often confused with Hereke, drawn for comparison.</figcaption></figure><p>The four traditions set against the Hereke divide along the two axes the arc has used throughout — silk against wool, and the precise origin of the workshop — and the practised eye separates them by reading the material and the fineness together before it reads the design. This is the load-bearing skill for the Anatolian court tradition, and it is worth stating as plainly as the gül test was stated for Tekke:<em>with a fine silk rug of court vocabulary, one attributes by reading where the loom stood and how fine the hand was, because the design alone will not tell — the design was borrowed.</em></p><p>A<em>Kum Kapı</em> is the closest of the four to the Hereke, and the most genuinely difficult to separate, because Kum Kapı is also an Ottoman silk-and-metal-thread weaving of the very highest grade, made in the same years. The difference is one of origin, not of quality. Kum Kapı names a quarter of Istanbul, and the rugs are the work of a small number of independent master weavers active there in the early twentieth century — Zareh Penyamin foremost among them — virtuosi working to their own designs rather than to a state manufactory&rsquo;s. A Kum Kapı is typically even finer in drawing and more inventive in composition than a Hereke, more the signed work of a particular artist than the institutional product of a workshop. The rule of thumb: a silk-and-metal rug of supreme fineness that reads as the personal masterpiece of an individual hand, often signed, is a Kum Kapı; the Hereke is the manufactory&rsquo;s product, and the manufactory&rsquo;s regularity is in it.</p><p>A<em>Sivas</em> is the plainest contrast of the four, because Sivas is an Anatolian town workshop weaving wool, not a court silk atelier. Sivas, in central Anatolia, produced a fine commercial workshop rug — well drawn, often in court-influenced medallion designs, but woven in wool pile at a far lower density and a far lower price than any silk Hereke. The rule of thumb: a workshop rug of related court vocabulary that is woven in wool, lacks the silk&rsquo;s sheen, and shows a knot density well below the Hereke&rsquo;s is a Sivas — a good rug of its kind, but a town&rsquo;s rug and not a court&rsquo;s.</p><p>A<em>Bursa</em> is the older Ottoman silk centre, and it stands to the Hereke rather as the antecedent does — a relation in the same family. Bursa, the early Ottoman capital, was the historic heart of the empire&rsquo;s silk industry, and silk rugs woven there carry related vocabulary; but the Bursa name belongs to the older tradition out of which the Hereke institution itself grew. The rule of thumb: Bursa names the older Ottoman silk centre and the broader tradition; Hereke names the particular nineteenth-century state manufactory that concentrated and surpassed it.</p><p>A<em>Tabriz</em> — and here the comparison crosses out of the Ottoman world altogether — is the Persian court counterpart, the fine northwest-Persian city workshop already treated in the second post of this arc. The finest Tabriz workshop rugs, the silk-warp Hadji Jalili pieces in particular, are likewise fine, likewise medallion-drawn, likewise the product of a city atelier; and since the Hereke designers were themselves quoting Safavid Persian models, the design vocabulary of a fine Tabriz and a fine Hereke can run remarkably close. The separation is foundation and knot. A Tabriz is a Persian rug — characteristically a wool pile even on the finest grade, tied with the asymmetric Persian knot; the silk Hereke is silk throughout and tied with the symmetric Turkish knot. The rule of thumb: when a fine medallion rug&rsquo;s design will not decide the question, the knot decides it — the symmetric knot and the all-silk structure carry the rug to Anatolia and to Hereke.</p><p>The pattern across all four is the working value of the post. One does not attribute a fine court rug by its medallion, nor by its border, nor by the mere presence of silk — the Safavid quotation is shared, and Kum Kapı has silk too. One attributes it by reading the foundation, the knot, and the manufactory origin together, and by recognising that the design, in this tradition, is the one piece of evidence that has been borrowed.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Hereke comes down, as in the prior rug posts, to a short ordered checklist — and as the Tekke post began with the move that does the most work for a tribal rug, so this one begins with the move that does the most work for a court rug. That move is to gauge the fineness.</p><p>One looks first, and principally, at the<em>knot</em>. One turns the rug over and reads the back, and what a Hereke offers there is a density at the upper limit of the hand — knots so small and so closely set that the back reads almost as a fine cloth, with the symmetric Turkish knot worked at a count that climbs into the high hundreds and, on the best pieces, well past a thousand to the square inch. A rug whose back shows the coarse nubbed grain of a village weaving is not a Hereke and was never near one; a rug of merely good city fineness is more likely a Tabriz or a Sivas. The extreme density is the attribution, because the extreme density is what an imperial manufactory could buy and a place could not. Everything else on this list confirms it or grades it.</p><p>One looks next at the<em>material</em>. The finest Hereke is silk throughout — silk warp, silk weft, silk pile — with, on the grandest pieces, brocaded metal thread worked into the ground; the second grade is a wool pile on a fine warp. An all-silk structure, lustrous and supple with the faint cool sheen of the fibre, places the rug in the top grade and points hard toward Hereke or its Kum Kapı sibling; a wool pile does not exclude Hereke, but it moves the piece into the workshop&rsquo;s lower grade and closer to the Sivas comparison.</p><p>One looks at the<em>palette and the drawing together</em>. The Hereke is a multicolor jewel-tone weaving — ivory, gold, jade, rose, indigo — and the silk gives those colours a luminosity and an angle-dependent shift that wool cannot. But one reads the drawing for discipline rather than for identity: the medallion drawn true, the border repeats matched at the corners, this exactness being the manufactory&rsquo;s quality control made visible. And one remembers the central lesson of the post — the pattern itself is a quotation, Safavid and Ottoman and European recombined, and is not, in this tradition, the thing that decides the attribution.</p><p>And one looks, last, for the<em>signature</em>, while expecting to do without it. A minority of documented Hereke pieces carry a woven mark or an inscription cartouche, and where one is present and genuine it is welcome corroboration; but it is far from universal, and not difficult to imitate, so the mark confirms a reading already made — it does not make one. The reading is made by the knot, the silk, and the disciplined hand; the manufactory is legible in the structure long before any name is woven into it. The Hereke is not a place&rsquo;s rug nor a tribe&rsquo;s. It is a state&rsquo;s rug, the woven instrument of a court&rsquo;s prestige, and the extreme fineness in the field is the measure of the institution that commissioned it.</p><p>The next post in the rug arc will be either<em>Oushak</em> — to extend the Anatolian tradition into the village register (pale yellow / apricot palette, larger-scale 15th-c-derived medallions) — or one of the Turkmen types not yet covered. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>George Hepplewhite</title><link>https://mtclinton.com/posts/hepplewhite/</link><pubDate>Thu, 21 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/hepplewhite/</guid><category>antiques</category><description>Eighth per-subject post in Reading the Period Cabinet — the English neoclassical succession to Chippendale, George Hepplewhite's posthumous 'Cabinet-Maker and Upholsterer's Guide' (1788), the shield-back chair as type-specimen, with pale satinwood + painted decoration + delicate inlay replacing Chippendale's carved mahogany.</description><content:encoded>&lt;![CDATA[<p>The seven prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a>,<a href="/posts/louis-xvi/">Louis XVI</a>,<a href="/posts/biedermeier/">Biedermeier</a>,<a href="/posts/chippendale/">English Chippendale</a>,<a href="/posts/gustavian/">Gustavian</a>,<a href="/posts/italian-baroque/">Italian Baroque</a>, and<a href="/posts/italian-rococo-venetian/">Italian Rococo (Venetian)</a> — have carried the European cabinet tradition from the French royal source through its Continental translations and back again, and the Italian Rococo post closed by promising the arc&rsquo;s return to the Anglophone line. This is that return. It treats English Hepplewhite, the body of cabinet-making produced under that name between roughly 1785 and 1800, as a taxonomy post in the manner of the two Italian posts before it — not a personal narrative but a description of a type and the evidence by which one reads it.</p><p>Hepplewhite is the English neoclassical succession to Chippendale, and the succession is a clean one. The Chippendale post treated a style of carved dark mahogany — the cabriole leg, the ball-and-claw foot, the deep-relief rococo splat. Hepplewhite kept the English cabinet trade and changed nearly everything else: the mahogany gave way to pale satinwood, the carving to painted decoration and delicate inlay, the cabriole leg to the straight tapered leg ending in a small spade foot, the rococo asymmetry to the disciplined symmetry of urn, swag, husk, and paterae. The single most famous object the style produced is the shield-back chair, the form by which one recognises Hepplewhite at a glance — light where Chippendale was substantial, slender where Chippendale was carved, pale where Chippendale was dark. The wood-tone variety table that has run beneath this arc records Hepplewhite, accordingly, as a pale-satinwood post, a deliberate break from the dark-mahogany register.</p><p>There is, however, a difficulty in the word<em>Hepplewhite</em> that this post will return to repeatedly, because it is the load-bearing fact of the subject and not an antiquarian footnote. The style is named for a man — George Hepplewhite, a London cabinet-maker who died in 1786 — about whom almost nothing documentary survives, and it is defined not by his furniture, of which not one securely attributed piece is known, but by a book.<em>The Cabinet-Maker and Upholsterer&rsquo;s Guide</em> was published in 1788, two years after his death, by his widow Alice, trading as A. Hepplewhite &amp; Co.; second and third editions followed in 1789 and 1794. The style is, in the most exact sense available, a pattern book rather than a workshop. One should hold that fact from the first page.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Hepplewhite piece, for the purpose of beginning to read the style, is the shield-back side chair — canonical not because it is the only Hepplewhite form but because it concentrates the whole vocabulary into a single object the eye can take in at once. The form is what its name describes: an open chair back whose top rail and stiles sweep up and around into the outline of a heraldic shield, broad at the shoulders, narrowing to a point at the base, held clear of the seat by a short open section so that the shield reads as a framed device rather than a continuous back. Within the shield the workshop set its ornament — the second half of the signature — a carved or inlaid neoclassical motif, most characteristically an urn from which husk-chains descend, or, in the form most firmly attached to the Hepplewhite name, the three ostrich plumes of the Prince of Wales&rsquo;s feathers. The chair stands on straight tapered legs, square in section, each finishing in a small spade foot — a slight rectangular widening at the base, like the head of a spade. The frame itself is pale: satinwood or another pale wood, frequently painted, frequently inlaid, light enough that one can lift the chair with one hand.</p><p>This is the chair. But the Guide drew a great deal more, and the case form that carries the Hepplewhite vocabulary most fully is the sideboard — the long serving table with a bowed or serpentine front and flanking pedestals or deep drawers. The form itself was not Hepplewhite&rsquo;s: the modern sideboard, a side table joined to a pair of flanking pedestal cupboards, is conventionally credited to Thomas Shearer, who first illustrated it in<em>The Cabinet-Makers&rsquo; London Book of Prices</em> of 1788, with the three-part composition owing something also to Robert Adam — and there is a quiet irony in the fact that the book which gave the trade a maker-less style did not invent its most famous case form either. What the Guide did was to popularise and standardise that form for the late-Georgian dining room, carrying it to every provincial shop in Britain. It has a serpentine front, a frame of pale satinwood or of mahogany crossbanded in satinwood, neoclassical ornament — urns, paterae, husk swags — laid in as delicate marquetry, and the same straight tapered legs with spade feet the chair stands on. The shield-back chair and the serpentine sideboard between them set out the entire Hepplewhite manner; the rest of the Guide — the secretary-bookcase, the Pembroke table, the bow-front chest — carries that manner across the remaining furniture of the house.</p><figure><img src="/images/posts/hepplewhite/detail-back.png" alt="A close detail of a Hepplewhite shield-back chair splat — Prince-of-Wales feathers or neoclassical urn carved or inlaid"><figcaption><p>A close detail of a Hepplewhite shield-back chair splat — the canonical Prince-of-Wales feathers or neoclassical urn motif carved or inlaid in satinwood, the form-signature of the Hepplewhite chair.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The wood, first, is most of what one is reading for, because the change of wood is the change of style. The Chippendale tradition worked in mahogany, a dense dark timber that took deep carving and held it; the Hepplewhite tradition turned to satinwood, a pale golden-yellow timber imported from the West and East Indies, hard and close-grained and capable of a high lustrous polish. Where a piece is not satinwood throughout it is very often mahogany used as a ground and crossbanded — bordered in strips of contrasting wood laid with the grain running across the join — in satinwood, tulipwood, or kingwood. The pale ground is not a neutral choice: it is the surface that painted decoration and fine marquetry require, and the move to satinwood and the move to a painted-and-inlaid ornamental register are the same move made in two materials.</p><p>The ornament, second. Where the Chippendale cabinet-maker carved his ornament into the wood, the Hepplewhite cabinet-maker laid his onto the surface, and two techniques carry the work: painted decoration — the satinwood ground painted with neoclassical motifs in colour or grisaille, often by a specialist decorator, sometimes with figurative medallions in the manner of the contemporary painters Angelica Kauffman and Antonio Zucchi — and marquetry inlay, the ornament cut from contrasting woods, stained and shaded, sometimes scorched in hot sand to suggest modelled relief, and let into the pale ground. The vocabulary of both is neoclassical and disciplined: the urn, the swag of husks, the paterae, the wheat-ear, the ribboned festoon, the bellflower drop. It is an ornament read in line and colour against a flat surface, where the Chippendale ornament was read in shadow and relief.</p><figure><img src="/images/posts/hepplewhite/detail-inlay.png" alt="A close detail of Hepplewhite satinwood inlay — neoclassical urn or paterae in stained-and-shaded marquetry"><figcaption><p>A close detail of Hepplewhite satinwood inlay — the neoclassical urn or paterae motif in stained-and-shaded marquetry, the principal decorative technique of the Hepplewhite tradition.</p></figcaption></figure><p>The leg, third. The Hepplewhite leg is straight, square in section, and evenly tapered, terminating in a small spade foot, a plain tapered end, or occasionally a turned thimble foot. This is the most reliable single discriminator the style offers, because it sits in deliberate opposition to the Chippendale cabriole — which flexes outward at the knee, curves back in, and rests on a carved foot, a sculptural member and an object of carving. The Hepplewhite leg is none of these things. It is a straight architectural support, drawing on the same source the French Louis XVI fluted columnar leg drew on: the classical column, the post-and-lintel logic of antiquity, transmitted to the cabinet trade through the architecture of the period.</p><p>The construction, fourth. The Hepplewhite piece is light, and its lightness is structural as well as visual — slender frame members, thin crossbanded veneers, a deliberate paring-away of timber the Chippendale piece would have kept. On a genuine period example this delicate workshop construction shows the period hand: hand-cut dovetails of irregular spacing, pit-sawn or hand-planed secondary timber, hand-laid veneer over a hide-glue ground, two centuries of shrinkage and oxidation on the backboards and undersides. The slightness is not flimsiness; it is the structural expression of a style that wished to be read as graceful rather than substantial.</p><figure><img src="/images/posts/hepplewhite/detail-leg.png" alt="A close detail of a Hepplewhite tapered leg with spade foot — straight neoclassical form"><figcaption><p>A close detail of a Hepplewhite straight tapered leg terminating in a spade or thimble foot — the neoclassical replacement for the Chippendale cabriole-and-ball-and-claw, drawing on the same Adam-architectural source as the French Louis XVI fluted columnar leg.</p></figcaption></figure><p>And the Guide, fifth — at once the evidence of last resort and of first resort, because for Hepplewhite the pattern book is not a supplement to the furniture but the definition of it. The plates of the 1788<em>Guide</em>, with their nearly three hundred designs, are the document against which a piece is judged &ldquo;in the Hepplewhite manner.&rdquo; There is no maker&rsquo;s stamp to find, no workshop label; there is only the question of whether the form, the ornament, and the proportion answer to the engraved plates. This is an unusual position for a style to occupy, and the next section sets out why.</p><h2 id="the-period">The Period</h2><p>The Hepplewhite period proper runs from about 1785 to 1800, a span shorter than most in this arc and bounded with unusual sharpness at both ends — at its beginning by the publication of the Guide, at its close by the rise of the next pattern book. The man whose name it carries is, by contrast, almost entirely a blank. George Hepplewhite is traditionally said to have been apprenticed to the Lancaster firm of Gillow — though that apprenticeship, like nearly everything else about the man, rests on tradition rather than on any surviving record — and to have afterwards established a modest cabinet-making shop in Cripplegate, in the City of London; no piece of furniture has ever been securely traced to it. He died in 1786. The whole of his documentary existence amounts to an apprenticeship, an address, a death, and a widow — and the widow is the figure who matters. Alice Hepplewhite carried on the business under the style A. Hepplewhite &amp; Co., and in 1788 published, two years after her husband&rsquo;s death,<em>The Cabinet-Maker and Upholsterer&rsquo;s Guide</em>. The style is therefore named for a man who never saw the book that defines it, and was launched into the world by his widow: the Hepplewhite manner is a posthumous publication, and the workshop behind the name is, for all practical purposes, undocumented.</p><p>What the Guide translated into the cabinet trade had been worked out a little earlier, and at a grander scale, by the architects. The dominant English taste of the 1760s and 1770s had been set by Robert Adam and his brother James, whose classical-revival interiors — the painted ceilings, the delicate plaster relief, the slender ornament of urn and swag and paterae, drawn from the antique remains of Rome and the recently excavated Pompeii — had remade the English interior in a neoclassical key. Adam was an architect, and designed his furniture as part of the room, fitting each piece to a particular wall in a particular house; his neoclassicism was an aristocratic and bespoke affair. What the Guide did — the cabinet-maker&rsquo;s contribution proper — was to take that architect-led vocabulary down off the wall and put it into a trade pattern book, where any provincial shop could consult it and any patron of moderate means could order from it. Hepplewhite domesticated Adam: the neoclassicism Adam had built into specific houses, the Guide made available to the whole country-house and town-house class as a repertory of forms.</p><p>The period closed as it had opened, with a book. Thomas Sheraton&rsquo;s<em>The Cabinet-Maker and Upholsterer&rsquo;s Drawing-Book</em> was issued in parts from 1791 and completed in 1793, and through the 1790s the Sheraton designs gradually displaced the Hepplewhite ones as the current taste; the third edition of the Guide, in 1794, already shows the firm revising its plates toward the newer fashion — a quiet admission that the moment had moved on. Between them, the Guide and the Drawing-Book defined the English cabinet trade of the last fifteen years of the eighteenth century so completely that the period is most accurately described not by the names of workshops but by the names of two pattern books.</p><figure><img src="/images/posts/hepplewhite/antecedent.png" alt="An English Chippendale chair — the rococo predecessor the Hepplewhite period displaced"><figcaption><p>An English Chippendale ribbon-back chair — the rococo predecessor that the Hepplewhite period displaced. The cabriole and ball-and-claw foot were replaced by the straight tapered leg with spade foot; the carved mahogany splat became the satinwood-inlaid shield-back.</p></figcaption></figure><p>The load-bearing distinction every Hepplewhite collector must master is therefore not a distinction between this style and a neighbouring one — that is the work of the next section — but a distinction internal to the word<em>Hepplewhite</em> itself. It is the attribution problem in its purest form, and it runs as follows. No piece of furniture can be securely documented to George Hepplewhite&rsquo;s own workshop. Not one. There is no signed piece, no labelled piece, no piece with a paper trail back to the Cripplegate shop. When a dealer, an auction catalogue, or a museum label says &ldquo;Hepplewhite,&rdquo; the word does not — cannot — mean &ldquo;made by Hepplewhite.&rdquo; It means &ldquo;made in the manner of the Guide,&rdquo; and the Guide was a public document that any cabinet shop in Britain, and a good many outside it, was free to consult and copy. Hepplewhite furniture was therefore made by hundreds of workshops over fifteen years and more, none of them necessarily connected to the Hepplewhite firm at all, all working from the same set of engraved plates. The style is a book, not a maker.</p><p>This inverts the ordinary logic of attribution. With most of the styles in this arc — the Louis XV ébéniste, the Italian Baroque carver — one can at least in principle ask &ldquo;who made this,&rdquo; and a signed or documented example settles the question. With Hepplewhite the question is malformed: the honest description of a fine shield-back chair is not &ldquo;this is a Hepplewhite chair&rdquo; in the sense of provenance but &ldquo;this is a chair worked from, or closely after, plate such-and-such of the Guide.&rdquo; So &ldquo;is it Hepplewhite&rdquo; is always a question about conformity to a published design and never about a workshop, and the grading of a piece runs along two axes that must be kept separate. The first is<em>date</em> — a piece of the 1785–1800 period, or a nineteenth-century or later piece worked in the same idiom, since the Guide stayed in print long after the period closed and the &ldquo;Hepplewhite revival&rdquo; of the later nineteenth century produced a great deal of honest decorative furniture in the manner that is not period work at all. The second is<em>quality</em> — how fluently the published vocabulary has been realised, since a single plate could be executed by a London shop of the first rank in figured satinwood with painted medallions, or by a country shop in plain mahogany with a single line of stringing, and both are legitimately &ldquo;Hepplewhite.&rdquo; The collector keeps date and quality apart, and never expects the third question — who made it — to be answerable at all.</p><figure><img src="/images/posts/hepplewhite/pattern-book-page.png" alt="A page from the 1788 Hepplewhite Guide — engraved plates of shield-back chair, sideboard, secretary-bookcase"><figcaption><p>A page from the 1788<em>Cabinet-Maker and Upholsterer&rsquo;s Guide</em> — engraved plates showing the canonical Hepplewhite forms: the shield-back side chair (with Prince-of-Wales feathers, urn, and wheatear variants), the bow-front sideboard, the secretary-bookcase, the Pembroke table.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/hepplewhite/sibling-sheraton.png" alt="A Sheraton chair — the immediate English successor with rectangular back rather than shield, often greater inlay" loading="lazy"/><figcaption>Sheraton<em>— the immediate English successor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hepplewhite/sibling-chippendale.png" alt="A Chippendale rococo chair — carved mahogany, cabriole leg, predecessor English style" loading="lazy"/><figcaption>Chippendale<em>— the rococo predecessor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hepplewhite/sibling-adam.png" alt="A Robert Adam designed chair — the architect-led source of English neoclassicism that Hepplewhite translated into the cabinet trade" loading="lazy"/><figcaption>Robert Adam<em>— the architect-led source</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hepplewhite/sibling-american-federal.png" alt="An American Federal chair — the colonial American descendant of Hepplewhite, often almost-indistinguishable from English at first glance" loading="lazy"/><figcaption>American Federal<em>— the colonial American descendant</em></figcaption></figure></div><figcaption>Four styles most often confused with Hepplewhite, drawn for comparison.</figcaption></figure><p>A<em>Sheraton</em> is the immediate English successor — the style of Thomas Sheraton&rsquo;s<em>Drawing-Book</em>, issued in parts from 1791 and completed in 1793, and the hardest of the four distinctions to draw, because it is the closest. The two pattern books overlap heavily: both English, both neoclassical, both working in pale satinwood with painted and inlaid ornament, both standing their chairs on slender tapered legs, and a great deal of 1790s furniture could be referred to either book with equal honesty. The distinction, such as it is, lies in the chair back and the leg. The Hepplewhite back is curvilinear and open — the shield, the oval, the heart, its outline a closed sweeping curve; the Sheraton back tends to be rectangular, a square or oblong frame with the ornament arranged on straight rails and uprights within it. And where the Hepplewhite leg is square in section and often spade-footed, the Sheraton leg is frequently turned — round in section, reeded or fluted on the lathe — and more slender still. The rule of thumb: a curvilinear open back on a square tapered leg is Hepplewhite; a rectangular back on a slender turned and reeded leg is Sheraton. The rule is sound on the whole, but the honest collector concedes that the two books shade into one another, and that &ldquo;Hepplewhite-Sheraton&rdquo; is a defensible label for a great many pieces on the boundary.</p><p>A<em>Chippendale</em> is the rococo predecessor — the post earlier in this arc, the style the Hepplewhite period displaced — and here the distinction is wide and easy, because the two styles are opposites within the same English trade. Chippendale is dark carved mahogany; Hepplewhite is pale inlaid satinwood. Chippendale&rsquo;s ornament is cut into the wood in relief; Hepplewhite&rsquo;s is laid onto a flat surface in paint and marquetry. Chippendale&rsquo;s chair stands on a cabriole leg and a carved foot; Hepplewhite&rsquo;s on a straight tapered leg and a spade foot. The rule of thumb: carved dark mahogany with a cabriole leg is Chippendale; pale inlaid satinwood with a straight tapered leg is Hepplewhite.</p><p>A<em>Robert Adam</em> piece is the architect-led source — the neoclassical vocabulary Hepplewhite translated into the trade pattern book. The two are not opposed; they are the same neoclassicism at two points in its descent, and the distinction is one of register. An Adam piece was designed by an architect for a specific room in a specific house, fitted to its wall, often grander and richer in its gilding and marble than anything in the Guide; it is bespoke neoclassicism. A Hepplewhite piece is the same urn-and-swag vocabulary made repeatable — lighter, cheaper, drawn from a public plate. The rule of thumb: a grand architectural neoclassical piece conceived for a particular interior is Adam; the same vocabulary made portable in a trade pattern book is Hepplewhite.</p><p>An<em>American Federal</em> piece is the colonial American descendant — furniture made in the American workshops, chiefly of the Atlantic seaboard, in the decades after Independence, working directly from the Hepplewhite and Sheraton books. The distinction here is genuinely difficult, and at first glance often impossible, because the American cabinet-makers were working from the very same plates. The Federal piece tends to read in a slightly plainer register — frequently in mahogany with satinwood inlay rather than figured satinwood throughout, often sparer in ornament, and with the secondary woods of the American forest (tulip poplar, white pine) in its drawer linings and backboards rather than the oak and deal of the English shop. The rule of thumb: the English Hepplewhite piece works toward figured satinwood and English secondary woods; the American Federal piece works more often in inlaid mahogany and shows American secondary timber — and the secondary wood, examined on the underside, is frequently the most reliable tell of all.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>form of the chair back</em>, because the back is the signature and the shield-back is the type-specimen. The canonical Hepplewhite back is a closed curvilinear sweep — the shield, the oval, or the heart — held clear of the seat by a short open section, with neoclassical ornament set within it. A rectangular back, the ornament arranged on straight rails, points away from Hepplewhite and toward Sheraton; a carved rococo splat in dark mahogany points back to Chippendale.</p><p>One looks next at the<em>wood and surface together</em>. The piece should be pale — satinwood throughout, or a mahogany ground crossbanded and strung in satinwood and other pale woods — and the ornament laid on rather than carved in, by painted decoration or by marquetry inlay. A piece in this neoclassical form but executed in carved dark mahogany is the Chippendale antecedent; a piece whose pale surface and slender ornament are grander, more architectural, and fitted to a particular interior is closer to Adam than to the Guide.</p><p>One looks then at the<em>ornamental vocabulary</em>, which is small, disciplined, symmetric, and antique in its sources: the urn, the swag of husks, the paterae, the wheat-ear, the ribboned festoon, the bellflower drop — and, as the form most firmly attached to the Hepplewhite name, the three ostrich plumes of the Prince of Wales&rsquo;s feathers used as a chair-back device. Asymmetric rocaille shellwork belongs to the rococo and to Chippendale; this measured repertory belongs to Hepplewhite. And one looks at the<em>leg</em> — the most reliable single discriminator the style affords — which should be straight, square in section, evenly tapered, finishing in a small spade foot or a plain tapered end. A cabriole leg with a carved foot is Chippendale; a slender turned and reeded leg, round in section, leans toward Sheraton; the straight square tapered leg with a spade foot is the Hepplewhite member.</p><p>And one looks, finally, at the<em>question of attribution itself</em> — which is to say, one keeps in mind throughout that there is no maker to find. A genuine period Hepplewhite piece is a piece of the 1785–1800 cabinet trade, worked from or closely after the plates of the 1788 Guide, and showing the period hand in its construction; what it is not, and what no piece of Hepplewhite furniture has ever been shown to be, is documentably the work of George Hepplewhite&rsquo;s own shop. The collector reads form, surface, ornament, and leg against the Guide; reads the construction for date; reads the quality for rank; and asks of the word<em>Hepplewhite</em> only what it can honestly bear — that the piece is in the manner of the book, made by one of the many shops that worked from it, in the short and well-defined period the book defined.</p><p>The next post in the furniture arc will be either<em>Sheraton</em> — to continue the English neoclassical succession into the slightly later, more rectilinear register — or<em>American Federal</em>, to extend the Hepplewhite vocabulary into the post-colonial American workshops. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Tekke</title><link>https://mtclinton.com/posts/tekke/</link><pubDate>Thu, 21 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/tekke/</guid><category>antiques</category><description>Eighth per-subject post in Reading the Antique Rug — the principal Turkmen tribe of the 19th c, opening the central Asian tribal wool tradition with the gül system as the load-bearing collector distinction, the dark madder-brown palette, and the engsi and tent-bag forms that set Turkmen production apart from the Persian and Caucasian arcs already covered.</description><content:encoded>&lt;![CDATA[<p>The seven prior posts in this arc —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>,<a href="/posts/caucasian-kazak/">Caucasian Kazak</a>,<a href="/posts/bakshaish/">Bakshaish</a>,<a href="/posts/kashan/">Kashan</a>,<a href="/posts/bidjar/">Bidjar</a>, and most recently<a href="/posts/hamadan/">Hamadan</a> — stayed, between them, within two weaving worlds: the Persian, in its workshop and village forms, and the Caucasian highland tradition that the Kazak post treated. Both of those worlds reach the collector through a settled population, a known town, and a foundation of cotton. Tekke belongs to neither. It opens a third world altogether — the Turkmen, the tribal weaving of the central Asian steppe and desert, woven by a people who until the close of the nineteenth century were not settled at all. This is the eighth post in<em>Reading the Antique Rug</em>, and it treats the Tekke in the position the arc has reserved for the opening of the Turkmen tradition.</p><p>It breaks the palette, and it breaks it harder than Hamadan did. Hamadan moved the arc from the dark wine-reds of the Kurdish country into rust and camel; Tekke moves it somewhere the Persian and Caucasian posts never went at all — into a field of deep madder-red shading toward madder-brown, a ground colour so dominant across an entire tribal production that a reader meeting a Tekke after a Hamadan registers the change as a change of country, which is precisely what it is. But colour, here as in the Hamadan post, is the thing one notices first and trusts last. What organises the Turkmen weavings is not the ground but the<em>gül</em> — the repeating quartered tribal medallion that runs in an all-over lattice across the field — and, more particularly, the system by which each Turkmen tribe carried its own gül and can be told from its neighbours by it. That gül system is the load-bearing collector distinction for the whole Turkmen tradition, and the post will carry it the way the Hamadan post carried the single weft.</p><h2 id="the-specimen">The Specimen</h2><p>A Tekke that one will encounter is, in its commonest form, a piece of modest proportions — most main carpets run four to six feet in width and somewhat longer than that, the broad room-size carpet being a rarity in a tradition that wove for the tent rather than the hall. The first thing to settle, before any motif is read, is that there is no workshop anywhere in this account. The Tekke rug is a tribal rug from the first knot to the last; it was woven on a portable loom, by women of the tribe, to a vocabulary held in the memory and not drawn on a cartoon. The whole apparatus of the Persian posts — the city, the master designer, the commissioned carpet — is simply absent here, and the absence is the starting condition of everything that follows.</p><p>The composition is the signature, and it is uncommonly uniform. The Tekke field is covered, edge to edge, by a single repeating motif — the<em>gül</em>, the quartered tribal medallion — arranged in an offset lattice of rows, each gül linked to its neighbours by fine connecting lines so that the field reads as a single ordered net rather than as a scatter of separate ornaments. The Tekke gül is a flattened, gently lobed octagon, quartered by a cross into four compartments, each carrying a small stepped figure; the drawing is geometric, controlled, and repeated with a regularity that the tribal hand makes just irregular enough to be unmistakably hand-woven. Between the rows of primary güls sits a<em>secondary</em>, or minor, gül — a smaller motif, on the Tekke most often a starred or cruciform form. The primary gül and the minor gül together are the field; one does not, on a classic Tekke, find much else in it.</p><p>The palette is the deep madder register, and it is the colour the whole Turkmen tradition is known by and the colour this post introduces to the arc. The Tekke ground is madder-red carried toward madder-brown — a warm, dark, even mahogany, dyed from the madder root and aged into a colour with no Persian equivalent in the seven posts before this one. Against it the gül drawing is worked in ivory, in a darker brown-black, in a blue that the indigo gives sparingly, and in small quantities of a clear undyed white. The whole reads dark, warm, and disciplined. It does not read bright; the Tekke is not a rug of contrast, and a Turkmen weaving that announces itself in vivid reds and yellows is, on palette alone, pointing away from the Tekke and toward the lighter Yomut or the Ersari.</p><p>The Tekke wove, finally, in more forms than the carpet, and the forms belong in any honest specimen description because they are how most antique Tekke material actually survives. The household of the tent required furnishing, and the loom furnished it: the<em>engsi</em>, the door-rug hung across the entrance of the yurt, drawn to a quartered cross-panel design quite distinct from the gül field; the<em>chuval</em> and<em>torba</em>, the large and small tent-bags whose woven faces stored the household&rsquo;s goods; the<em>mafrash</em>, the small storage bag; and the trappings woven for the wedding procession. A great deal of the finest Tekke weaving is found not in carpets at all but in these bag-faces and door-rugs, and a collector who looks only for the main carpet looks past most of the tradition.</p><figure><img src="/images/posts/tekke/detail-gul.png" alt="A close detail of a Tekke gül — stepped octagonal medallion with characteristic inner cross-and-quarter division"><figcaption><p>A close detail of the Tekke gül — the stepped octagonal medallion with the characteristic inner cross-and-quarter division that distinguishes the Tekke from the Salor, Yomut, and other Turkmen tribal güls. The drawing is tribal, the colour is the deep Tekke madder-brown.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The foundation is where the Turkmen tradition declares itself most plainly, and it is the first place the Tekke parts company with everything the arc has treated so far. The Persian rugs of the prior posts — Heriz, Tabriz, Kashan, Bidjar, Hamadan — are built on a foundation of cotton: cotton warp, cotton weft, the settled crop of a settled agriculture. The Tekke is built on wool. Warp and weft alike are wool, spun from the fleece of the tribe&rsquo;s own flocks, and the all-wool foundation is not an incidental fact but a structural signature of the entire Turkmen production. It is the foundation of a pastoral people who carried their wealth on the hoof and had no cotton field to draw on; and it places the Tekke, structurally, with the Caucasian highland weavings of the Kazak post rather than with any Persian rug. When one turns a Turkmen rug over and finds wool against the hand where a Persian rug would give cotton, one has already learnt something true about where it was made.</p><p>The knot is the<em>asymmetric</em> knot — the open knot, tied around one warp and passing loosely behind the other — used across the Tekke production and across most of the Turkmen tribes, though the Yomut complicates that statement and the post will return to it. Density on the Tekke runs high by tribal standards: the better antique pieces sit between roughly a hundred and twenty and a hundred and eighty knots to the square inch, and the very finest Tekke work — certain engsis and bag-faces in particular — climbs well past that, into a fineness that few tribal traditions anywhere have matched. This is worth dwelling on, because the Tekke confounds an easy assumption. One expects, from the Hamadan post, that tribal weaving is coarse weaving. The Tekke is not coarse. It is a tribal rug woven to a workshop&rsquo;s fineness, and the fineness was achieved without any workshop at all — by a tradition of weavers who had carried the same vocabulary, and the same standards, across generations.</p><p>The dye is the deep madder, and the madder is the second pillar of the evidence. The colour the Tekke weaver wanted from the madder root was not a bright red but a dark, saturated, brown-shaded red — the mahogany ground that gives the tradition its character. A genuine antique Tekke red has a depth and a faint variegation across the field that the chemical reds of the later commercial period flatten out; the abrash of a hand-dyed madder ground is part of the evidence, not a flaw in it. The wool itself rewards the hand: the Turkmen flocks of the Trans-Caspian country gave a fleece long in the staple and high in lanolin, and a well-kept antique Tekke has a sheen and a soft, dense resilience under the palm that the knot count alone would not predict — the wool doing, here as elsewhere, work that no diagram of the structure can record.</p><figure><img src="/images/posts/tekke/detail-border.png" alt="A close detail of a Tekke main border — kepse or qotchak repeat in the Turkmen tribal register"><figcaption><p>A close detail of a Tekke main border — the kepse or qotchak repeat in the Turkmen tribal register, drawn with the tribal-hand irregularity that distinguishes a Turkmen border from a Persian workshop border.</p></figcaption></figure><figure><img src="/images/posts/tekke/detail-foundation.png" alt="A close detail of a Tekke knot-back — wool warp, wool weft, asymmetric Turkmen knot"><figcaption><p>A close detail of the back of a Tekke rug — the wool warp and wool weft (the Turkmen foundation, distinct from the Persian cotton warp), the asymmetric knot at tribal density.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Turkmen were, for the whole of the period that produced the rugs this post is concerned with, a tribal people of the Trans-Caspian country — the desert and oasis belt east of the Caspian Sea that is now the republic of Turkmenistan. They were not subjects of any settled state. They were pastoral, mobile, organised by tribe and clan rather than by city, and they lived along the oases of a hard country in which water and pasture, not land as such, were the wealth worth holding. The Tekke were one tribe among several — the others being the Salor, the Yomut, the Saryk, the Chodor, the Ersari — and for most of the eighteenth century they were not the dominant one.</p><p>The dominant tribe, in the older order, was the Salor. The Salor held the prestige of the Turkmen world; theirs was the apex weaving tradition, and the other tribes deferred to them in a manner the rugs themselves record. That order began to give way in the early nineteenth century. Through the 1820s and the 1830s the Tekke rose, pressed upon the Salor, and started — for it was the beginning of a process measured in decades, not the work of a single season — to erode their pre-eminence; the rise carried on across the 1840s and 1850s, and only by the third quarter of the century, with the Tekke holding the great oases of Merv and the Akhal, was the displacement complete. The Salor were scattered and reduced, and — this is the part that matters for the weaving — their tradition did not vanish so much as it was<em>absorbed</em>. The Tekke took up Salor motifs, Salor standards of fineness, the very gül in modified form; the rise of the Tekke is, in the history of the rugs, the eclipse of one tribal weaving by another that had learnt from it. The relationship between Tekke and Salor is the central story of the Turkmen tradition, and it is the reason the antecedent of this post is a Salor rug.</p><p>The autonomy of the Turkmen ended in a single battle. Through the middle of the nineteenth century the Russian empire pressed south across the steppe; the Tekke resisted it longer and harder than most, and in 1881 the resistance was broken at Geok Tepe, where the Russian army stormed the Tekke fortress with a slaughter that ended Turkmen independence for good. What followed for the rugs was the pattern the Hamadan post has already described in its Persian form: the commercial export trade arrived, demand from Russia and the West intensified, and a tribal weaving made for the tent began to be made for the market. The deep madder gave way, in the commercial production, to brighter and cheaper dyes; the disciplined old vocabulary loosened; and the engsi and the tent-bag, no longer needed by a tribe being settled out of its tents, became trade goods rather than household furniture. Soviet workshop production carried the names forward into the twentieth century, but the tribal Tekke — the rug woven by the tribe for itself, in madder, to the old standard — belongs to the period before 1881, and it is that rug the collector is reading for.</p><figure><img src="/images/posts/tekke/antecedent.png" alt="A pre-1830 Salor tribal rug — the older Turkmen apex before the Tekke displaced the Salor"><figcaption><p>A pre-1830 Salor tribal rug — the older Turkmen apex tradition before the Tekke displacement that began in the 1830s. The Salor was the dominant Turkmen tribe and produced the finest tribal weavings; the Tekke eclipsed the Salor and absorbed their weaving tradition. The relationship between Tekke and Salor is the principal Turkmen-tribal story.</p></figcaption></figure><figure><img src="/images/posts/tekke/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the Turkmen tribes — map of Trans-Caspia with tribal locations, archetype güls"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Turkmen tribes — Trans-Caspian map locating Tekke, Salor, Yomud, Saryk, Chodor, Ersari territories; archetype gül drawings showing the distinguishing inner-division of each tribe&rsquo;s principal medallion.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/tekke/sibling-salor.png" alt="A Salor tribal rug — the pre-Tekke apex Turkmen weaving, finest tribal production, distinct Salor gül" loading="lazy"/><figcaption>Salor<em>— the displaced apex tribe</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tekke/sibling-yomut.png" alt="A Yomut rug — the eastern Turkmen tribe with distinct kepse and dyrnak güls, different proportions" loading="lazy"/><figcaption>Yomut<em>— the eastern Turkmen</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tekke/sibling-saryk.png" alt="A Saryk rug — Turkmen tribe with distinct gül and reddish-brown palette" loading="lazy"/><figcaption>Saryk<em>— the Saryk tribe</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tekke/sibling-ersari.png" alt="An Ersari rug — the larger Turkmen tribe of the Amu Darya region, distinct gül vocabulary" loading="lazy"/><figcaption>Ersari<em>— the larger southern Turkmen tribe</em></figcaption></figure></div><figcaption>Four Turkmen tribes most often confused with Tekke, drawn for comparison.</figcaption></figure><p>Before the four siblings are taken in turn, one trade-name has to be dealt with, because it stood for a century between the Western buyer and the truth of these rugs. The Turkmen weavings were sold in the West, all through the nineteenth century and well into the twentieth, as<em>Bokhara</em> rugs — and the better Tekke pieces as<em>Royal Bokhara</em>. The name was a merchant&rsquo;s name, and it named the wrong thing entirely. Bukhara was the great market city of central Asia, the entrepôt through which the tribal rugs of the region were carried, sorted, and shipped onward; it was emphatically not the place of weaving. No Turkmen tribe lived there. The Tekke wove in the Akhal oases and at Merv, hundreds of miles from the city whose name their rugs were sold under, and the gül that the trade called the &ldquo;Royal Bokhara gül&rdquo; was simply the Tekke gül seen by a market that had been told the city and not the tribe. The lesson is the same one the Hamadan post drew from the label &ldquo;Mosul&rdquo;: the dealer&rsquo;s word records the route, not the loom. A rug catalogued as a &ldquo;Royal Bokhara&rdquo; in an old sale record is, almost without exception, a Tekke.</p><p>That settled, the four siblings divide by the principle that organises this entire post — the gül. Each Turkmen tribe carried its own primary gül and its own minor gül, and the practised eye reads the pair of them to attribute a Turkmen weaving to its tribe before it reads anything else. This is the load-bearing skill of Turkmen collecting, and it is worth stating as plainly as the single-weft test was stated for Hamadan:<em>with a Turkmen rug, one identifies the tribe by reading the güls</em>.</p><p>A<em>Salor</em> is the displaced apex tribe, the antecedent of this very post, and the Salor gül is the one closest to the Tekke&rsquo;s — which is no accident, since the Tekke absorbed it. The Salor primary gül, however, is drawn with a finer hand and a distinct interior division that the trained eye separates from the Tekke&rsquo;s, and Salor weaving carries, on its finest pieces, small areas of magenta silk worked into the pile — a luxury the Tekke production did not run to. The rule of thumb: the gül that looks like a Tekke gül but is drawn finer and lit here and there with silk is a Salor.</p><p>A<em>Yomut</em> is the eastern and western Turkmen tribe, and it is the easiest of the four to separate, because the Yomut did not weave the Tekke kind of field at all. The Yomut carried several güls, the<em>kepse</em> and the<em>dyrnak</em> among them, drawn as serrated diamond or hooked forms quite unlike the lobed Tekke octagon, and the Yomut palette runs lighter and more varied, with more blue and a brick-toned red. The Yomut also used the symmetric knot on much of its production, where the Tekke used the asymmetric. The rule of thumb: a Turkmen rug with serrated diamond güls, a lighter and bluer palette, and frequently a symmetric knot is a Yomut.</p><p>A<em>Saryk</em> is the tribe of the Merv oasis before the Tekke took it — the Saryk and the Tekke contested the same ground, and the Tekke displaced the Saryk there as they displaced the Salor elsewhere. The Saryk gül is its own form, and the Saryk palette characteristically runs a darker, more purplish or brown-toned red than the Tekke&rsquo;s clear madder, often with white worked in cotton rather than wool. The rule of thumb: a Turkmen rug whose red has gone toward brown-purple, with cotton highlights and a distinct primary gül, is a Saryk.</p><p>An<em>Ersari</em> is the largest of the Turkmen tribes and the one settled furthest south, along the Amu Darya — and it is the loosest fit of the four. Ersari weaving is coarser than the Tekke, larger in scale, more varied in its design vocabulary, and brighter in palette, frequently carrying a clear red and even yellow that the Tekke madder never approaches. The rule of thumb: a Turkmen rug that is big, coarse, brightly coloured, and various in its design is an Ersari, and the Tekke&rsquo;s dark, fine, disciplined gül field is its opposite.</p><p>The pattern across all four is the working value of the post. One does not attribute a Turkmen rug by its size, nor by the fact of its being red, nor by the bare presence of repeating medallions — all of the tribes share those. One attributes it by reading the primary and minor gül together against the tribe&rsquo;s palette and knot.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Tekke comes down, as in the prior rug posts, to a short ordered checklist — and as the Hamadan post began with the move that does the most work, so this one begins with the move that does the most work for a Turkmen rug. That move is to read the gül.</p><p>One looks first, and principally, at the<em>gül</em>. Having established — by the all-wool foundation and the repeating medallion field — that a rug is Turkmen at all, the whole question of the tribe turns on the primary gül and the minor gül read together. The Tekke primary gül is the flattened, gently lobed octagon, quartered by a cross into four small stepped compartments, linked into an offset lattice by fine connecting lines; the Tekke minor gül is the smaller starred or cruciform figure set between the primary rows. A rug whose güls are serrated diamonds points to the Yomut; a gül lit with silk and drawn finer points to the Salor; a brown-purple ground with cotton white points to the Saryk; a large, coarse, brightly drawn gül points to the Ersari. The gül is the attribution. Everything else on this list confirms it or qualifies it.</p><p>One looks next at the<em>foundation</em>. One turns the rug over, and one expects wool — wool warp and wool weft, the pastoral foundation of the Turkmen tradition. A cotton foundation argues, hard, against any tribal Turkmen attribution and points toward a later commercial or workshop piece woven to the names. The knot, on the Tekke, is the asymmetric knot, and the better antique pieces run fine. Tribal weaving here does not mean coarse weaving, and a Tekke that is also notably fine is behaving exactly as a good Tekke should.</p><p>One looks at the<em>palette</em>. The Tekke ground is the deep madder-red carried toward mahogany-brown — dark, warm, saturated, faintly variegated with the abrash of a hand-dyed field. A Turkmen rug that reads bright, that runs to clear reds and yellows, or that has gone brown-purple in the ground, is on palette alone pointing away from the Tekke. The dark even madder is the Tekke&rsquo;s, and the chemical brightness of the later commercial production is the surest sign that one is not holding the tribal rug.</p><p>And one looks, last, at the<em>form</em>. The Tekke wove the main carpet, but it also wove the engsi, the chuval and torba, the mafrash and the wedding trappings, and a great deal of the finest surviving Tekke material is in these smaller formats rather than in carpets. A narrow piece with a quartered cross-panel design is very likely an engsi; a single woven panel, finished along three sides and plain along the fourth, is the face of a tent-bag. To recognise the form is to recognise the tribal household the rug furnished — and the household is, finally, the thing the whole post has been reading toward. The Tekke rug is not a workshop&rsquo;s product nor a village&rsquo;s. It is the furniture of a tent, and the gül in the field is the name of the tribe that wove it.</p><p>The next post in the rug arc will be either<em>Hereke</em> — to open the Anatolian court tradition with its multicolor silk palette and 19th-c Ottoman court-workshop register — or<em>Salor</em>, to extend the Turkmen tradition into the pre-Tekke apex. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>A Lexicon of the New Era</title><link>https://mtclinton.com/posts/a-lexicon-of-the-new-era/</link><pubDate>Wed, 20 May 2026 13:15:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/a-lexicon-of-the-new-era/</guid><category>ai</category><description>A lexicographer's attempt, in the register of an eighteenth-century dictionary, to fix the meanings of the words the artificial-intelligence moment has minted, stretched, or quietly poisoned before they shift again.</description><content:encoded>&lt;![CDATA[<h2 id="preface">Preface</h2><p>It is the misfortune of the lexicographer that he arrives always too late. Language is made by the people who speak it, hurriedly and without consultation, and the man who proposes to write it down discovers that he is not legislating but reporting — and reporting, moreover, on a thing that declines to hold still while he describes it. Johnson, who knew this better than anyone, gave the lexicographer his lasting epitaph: a harmless drudge. The present work is offered in that spirit of harmless drudgery, and with a full anticipation of its own futility.</p><p>The occasion of the work is a particular one. Within a span of four or five years the field that calls itself artificial intelligence has produced a vocabulary at a rate the language has had no opportunity to digest. Some of these words are wholly new, coined by engineers for engineers and then released, without instructions, upon the general public. Some are old words conscripted into new service, and now carry a technical freight their everyday senses never bargained for —<em>hallucination</em> is the standard example, and a later entry will attend to it. And some, the most interesting class, are words that the industry has minted precisely because a plainer word would have been embarrassing; these are the euphemisms, and the lexicographer who wishes to be of any use will spend most of his labour on them.</p><p>What unites the vocabulary is that it is spoken daily, fluently, and with conviction by very large numbers of people who could not, if pressed, define a single term of it. This is not a reproach. It is the ordinary condition of a vocabulary that has outrun its own settlement; one used the word<em>online</em> for a decade before anyone troubled to ask what the line was. But it produces a curious public discourse — confident on the surface, hollow underneath — in which two parties may argue at length over whether a machine<em>reasons</em> without either having paused to agree what the word, in this application, is being asked to mean.</p><p>The present lexicon attempts the modest and doomed task of fixing these meanings before they shift again. It makes no claim to completeness; the field mints faster than any drudge can transcribe, and several entries below will be obsolete by a margin the author prefers not to estimate. It claims only that each definition was accurate at the hour it was written, and that the wit, where wit intrudes, has been kept on the near side of the facts — a definition that is funny and wrong being a failure of the trade. Where a word is used by the industry as a euphemism, the lexicographer has thought it his office to say so plainly, and then to give the euphemism its due. The entries follow in the order the alphabet imposes, that being the one ordering principle the subject has not yet found a way to disrupt.</p><h3 id="agentic">Agentic</h3><p><em>adj.</em> Of a system: disposed not merely to answer but to act — to take a stated goal, break it into steps, call tools, and proceed without further instruction at each turn.</p><p>The word is an adjective doing the work of a promise. An<em>agentic</em> system is one that has been granted the standing to do things rather than merely to describe them, and the interesting question is never the grammar but the leash — what it has been permitted to touch, and what happens when the several-hour effort concludes, as it sometimes does, with a confident wrong answer delivered in the register of a junior colleague reporting success. The term has largely displaced the older<em>autonomous</em>, which had begun to alarm people.<em>Agentic</em> alarms them less, which is, on examination, its principal qualification for the post.</p><h3 id="alignment">Alignment</h3><p><em>n.</em> The project of ensuring that an artificial system pursues the goals its makers intend rather than some other goal it has inferred, and behaves, while pursuing them, within bounds its makers would endorse.</p><p>A word that has had to carry a great deal. In its narrow technical sense it names a real and difficult research programme; in its broad public sense it has become the place where the entire ethical content of the field is asked to reside, so that a single noun is now expected to mean<em>safe</em>,<em>honest</em>,<em>obedient</em>,<em>harmless</em>, and<em>agreeable to the speaker&rsquo;s politics</em>, all at once and without contradiction. The difficulty the word conceals is that these are not the same goal, and may on occasion be opposed. One notes, without drawing a conclusion, that the term presumes the existence of a fixed thing to be aligned<em>to</em> — and that the field has not, at the time of writing, produced one.</p><h3 id="benchmark">Benchmark</h3><p><em>n.</em> A fixed test, with a known answer key, against which competing models are scored and ranked; by extension, the score itself.</p><p>The benchmark is the field&rsquo;s instrument of self-knowledge and, increasingly, of self-deception. So long as a test is a fair sample of the territory, performing well on it indicates performing well in the territory; the trouble begins the moment the test becomes a target, at which point a laboratory may improve its score without improving anything a user would notice. The practice of optimising for the test specifically —<em>benchmaxxing</em>, in the field&rsquo;s own unlovely coinage — is universally deplored and widely undertaken. A benchmark, one is obliged to conclude, measures a model honestly exactly until it becomes worth gaming, and not one hour longer.</p><h3 id="the-bitter-lesson">The Bitter Lesson</h3><p><em>n.</em> The observation, set down by Richard Sutton in an essay of 2019, that across the history of artificial-intelligence research the methods which ultimately prevailed were the general ones that scaled with computation, and not the ones into which researchers had carefully built their own knowledge of the problem.</p><p>It is called bitter because it is addressed to the researcher, and what it tells him is unwelcome: that his cleverness, his hand-crafted features, his domain expertise lovingly encoded — these will in the long run be overtaken by a simpler method given more computation and more data. The lesson is genuinely a lesson, and the field has taken it; the entire architecture of the present moment is its consequence. Whether it remains true indefinitely is a separate question, and one the field has a strong commercial interest in not examining too closely.</p><h3 id="context-window">Context Window</h3><p><em>n.</em> The quantity of text — measured in tokens — that a model can attend to at one time, comprising the prompt, the documents supplied with it, and the response so far.</p><p>The context window is the model&rsquo;s working memory, and like all working memory it is finite and it is the site of most disappointments. A user who has conversed at length with such a system, and formed the natural impression that it<em>remembers</em> the exchange, has mistaken the window for a mind; what falls off the far edge of the window is not forgotten but was never retained, the distinction being the whole of the matter. The figures have grown large enough — windows of a million tokens have appeared at the frontier — that the limit is easy to forget. It has not, however, ceased to exist, and it does its most damage to the people most certain it is no longer there.</p><h3 id="distillation">Distillation</h3><p><em>n.</em> The training of a smaller model on the outputs of a larger one, so that the small model acquires much of the large model&rsquo;s behaviour at a fraction of its cost to run.</p><p>An honest word for an honest procedure, and a rare thing in this glossary on that account. The large model is made to answer a great many questions; the small model is trained to produce the same answers; the small model ends up cheaper, faster, and very nearly as good for ordinary purposes. The procedure is the reason capability descends so rapidly from the expensive frontier to the cheap commodity tier, which is a benefit to everyone who pays for the cheap tier and a considerable irritation to whoever paid to train the expensive one — for distillation, regarded from the wrong end, is the orderly transfer of an asset from the party that funded it to the party that did not.</p><h3 id="guardrail">Guardrail</h3><p><em>n.</em> A constraint built into a deployed system to prevent it from producing certain classes of output — unsafe, unlawful, defamatory, or merely off-brand.</p><p>The metaphor is drawn from the roadside, and the choice repays a moment&rsquo;s attention. A guardrail does not steer the vehicle and does not improve the driver; it is a passive barrier at the edge of the road, and it exists because the designers expect the vehicle, on some occasions, to leave the road. To call a safety measure a<em>guardrail</em> is therefore to concede, in the very act of naming it, that the underlying system is not itself reliable and that the barrier is the place where reliability has been relocated. The word is candid in a way its users may not intend.</p><h3 id="hallucination">Hallucination</h3><p><em>n.</em> The production, by a model, of confident output that is fluent, plausible, well-formed, and false.</p><p>The central word of the field&rsquo;s everyday vocabulary, and the one most worth dwelling on.<em>Hallucination</em> is a metaphor, and a flattering one: it suggests an aberration, a fever, a departure from some baseline of truthful operation to which the system would otherwise return. The less consoling description is that the model is doing, in the case that produces falsehood, precisely what it does in the case that produces truth — generating the most plausible continuation of the text — and that the truthful output and the false output are the same act, distinguishable only by a fact-check the model did not perform and was not built to perform. The word frames the failure as a malfunction. It is closer to the truth to call it the mechanism, observed on an occasion when the plausible and the accurate happened to diverge.</p><h3 id="human-in-the-loop">Human-in-the-Loop</h3><p><em>n.</em> An arrangement in which an automated system&rsquo;s actions are reviewed, approved, or corrected by a person before they take effect.</p><p>A phrase that means two opposite things depending on who is saying it. To the cautious it names a genuine safeguard: a competent person, with the time and the standing to refuse, examining the machine&rsquo;s work before it does harm. To the less scrupulous it names an alibi — a person nominally in the loop, possessed of neither the time to review the output nor the authority to overrule it, whose function is not to catch the error but to be available, afterward, as the party who approved it. The phrase does not distinguish between these, and one should be wary of any account that leans on it without saying which is meant.</p><h3 id="moat">Moat</h3><p><em>n.</em> A durable competitive advantage that protects a business from being overtaken by rivals; in this field, the question of whether any laboratory possesses one.</p><p>The word arrived from the wider business vocabulary and has become, in this corner of it, an obsession bordering on a neurosis. The anxiety is specific and well-founded: the capabilities of these systems are converging, the methods are widely understood, talent is mobile, and an expensively trained frontier model can be partly reproduced — see<em>distillation</em> — by parties who did not pay for it. A laboratory that has spent a fortune to reach the frontier discovers competitors arriving shortly after at a fraction of the cost, and the search for the<em>moat</em> is the search for some reason this should not continue. That the question is asked so insistently is itself the most informative answer to it.</p><h3 id="model-collapse">Model Collapse</h3><p><em>n.</em> The progressive degradation of a model&rsquo;s quality when it is trained, across successive generations, predominantly on data produced by earlier models rather than on data of human origin.</p><p>A documented failure mode and, for the lexicographer, a satisfying one — a piece of the field&rsquo;s own vocabulary that names an irony the field would rather not dwell on. Each generation trained mainly on its predecessors&rsquo; output loses a little of the variety, the rare cases, and the long tail of the original human distribution; the errors compound; the descendants converge on a blander and narrower thing than their ancestors were. The mechanism is not mysterious. It is what happens when a system is fed chiefly on itself, and it is a sufficient reason why the genuine human record remains, awkwardly, irreplaceable.</p><h3 id="open-weight">Open-Weight</h3><p><em>n.</em> &amp;<em>adj.</em> Of a model: released so that the trained parameters themselves may be downloaded, run, and modified by anyone, rather than being accessible only through the maker&rsquo;s hosted service.</p><p>A precise term, and one to be carefully distinguished from<em>open-source</em>, with which it is constantly and not always innocently confused. Software is open-source when one may read the recipe; a model is<em>open-weight</em> when one is handed the finished cake. The weights may be downloaded and run, but the training data, the training code, and the procedure that produced the weights frequently are not disclosed — so that one has the artefact entire and the means of its making not at all. The distinction matters, because<em>open</em> is a word that confers approval, and a release that has earned the lesser sense of it is generally content to be described by the greater.</p><h3 id="prompt">Prompt</h3><p><em>v.</em> &amp;<em>n.</em> As a verb, to supply a model with the text that elicits its response. As a noun, that text itself.</p><p>A modest word that has been asked to support a startling amount of apparatus. For a period there was talk of<em>prompt engineering</em> as though it were a discipline with a literature, and the man who could phrase a request well was spoken of as possessing a craft. Some of this was real and much of it was the ordinary human tendency to dignify a knack with a title. What the verb conceals is the asymmetry of the exchange: one<em>prompts</em> a person to mean one is supplying a small nudge to a mind that will do the rest, and the same verb applied to a machine quietly imports the same flattering picture — of a nudge, and a mind. It is, in the plain case, an instruction given to a mechanism, and the mechanism&rsquo;s whole performance is downstream of how the instruction was phrased.</p><h3 id="reasoning">Reasoning</h3><p><em>n.</em> In current usage, a mode of operation in which a model generates a chain of intermediate steps before its final answer, and the practice of training models to do so.</p><p>The most contested word in the lexicon, and the one over which the most heat is generated with the least agreement on terms. That the technique works is not in dispute: a model made to produce intermediate steps does measurably better on problems that have steps, and the<em>reasoning models</em> so trained are a genuine advance. What is in dispute is the word. To one party the intermediate steps simply<em>are</em> reasoning, the term requiring no apology; to another they are a sequence of generated text that improves the answer by a mechanism that need not resemble reasoning at all, and the word smuggles in a conclusion the evidence does not compel. The lexicographer&rsquo;s duty here is only to record that the word is doing argumentative work, and that anyone who uses it as though its meaning were settled has joined one of the two parties without announcing it.</p><h3 id="slop">Slop</h3><p><em>n.</em> Machine-generated content — text, images, video — produced in bulk, of low quality, and distributed without regard to whether anyone wished to receive it.</p><p>A rare gift to the lexicographer: a word coined by the public, against the industry, and admirably fit for its purpose.<em>Slop</em> names the substance that fills a comment section, pads a search result, and accumulates in the feed — content that is not deceptive exactly, merely indifferent, generated because generation is now nearly free and posted because posting is free as well. The word&rsquo;s force lies in its honesty about volume and motive both. It is the term the language reached for when it needed to describe the smell of the new abundance, and the speed with which it was adopted suggests the public had been waiting for it.</p><h3 id="superintelligence">Superintelligence</h3><p><em>n.</em> A hypothesised system whose general cognitive capability substantially exceeds that of the ablest human across essentially every domain.</p><p>The horizon term of the whole vocabulary, and the one that does the most work while resting on the least. Whether such a thing is possible, whether the present methods tend toward it, whether it would arrive gradually or at once — none of this is established, and the word names a possibility rather than an observed object. Its function in discourse is to set the stakes: invoked by the hopeful to justify the investment and by the fearful to justify the alarm, it serves both parties precisely because it is undefined enough to be filled with whatever a given argument requires. A lexicographer can do little with such a word but mark it clearly as a hypothesis, and note that a great deal of confident speech is built upon it.</p><h3 id="vibe-coding">Vibe Coding</h3><p><em>n.</em> The practice of producing software by describing the desired result to a model in natural language and accepting its generated code with little or no review of the code itself.</p><p>A phrase of recent and informal origin, and useful precisely because it is honest about its own method. To<em>vibe code</em> is to attend to whether the program appears to work and to decline to attend to how — to treat the code as one treats the inside of an appliance, as a region one is content not to enter so long as the thing performs. For small and disposable programs this is a defensible economy of attention. For programs that must be maintained, audited, or trusted, it relocates an old and well-understood category of risk into a place where no one is looking at it, and the cheerfulness of the phrase should not be mistaken for a verdict on the wisdom of the practice.</p><h3 id="wrapper">Wrapper</h3><p><em>n.</em> A product consisting chiefly of an interface and some modest arrangement built around a model the maker did not train; frequently qualified, by detractors, as<em>thin</em>.</p><p>The word is almost always an accusation. To call a company a<em>thin wrapper</em> is to allege that it has contributed an interface and a logo to a capability someone else produced and someone else could remove, and that it therefore has no durable claim on its own customers — the charge being, in the vocabulary of an earlier entry, an absence of<em>moat</em>. The difficulty is that the line between a wrapper and a product is not fixed. Much valuable software is, on a sufficiently unkind description, a wrapper around something; the question is whether the arrangement built around the model is itself worth paying for. The word<em>thin</em> is doing the real work, and it is supplied, almost always, by a party with an interest in the answer.</p><h2 id="a-closing-word">A Closing Word</h2><p>The work is done, and the lexicographer is under no illusion about the condition of it. Several of the entries above were accurate when written and will not survive the year; one or two may not survive the season. The vocabulary will go on being minted faster than it can be set down, the euphemisms will go on being preferred to the plain words they replace, and the public will go on speaking the whole of it fluently and defining none of it. This was foreseen in the Preface and is repeated here only so that no reader feels he has caught the author in an oversight.</p><p>If the lexicon has a use, it is the narrow one all such works have: not to arrest the language — that cannot be done, and the man who claims to have done it has only mistaken a photograph for the thing photographed — but to leave a clear record of what the words meant at one particular hour, so that a later reader, encountering them shifted, has something to measure the shift against. The lexicographer, having performed that office to the best of a harmless drudge&rsquo;s ability, lays down the pen, and notes, without surprise, that two of the headwords have already moved.</p>
]]></content:encoded></item><item><title>Italian Rococo (Venetian)</title><link>https://mtclinton.com/posts/italian-rococo-venetian/</link><pubDate>Wed, 20 May 2026 13:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/italian-rococo-venetian/</guid><category>antiques</category><description>Seventh per-subject post in Reading the Period Cabinet — the Venetian Rococo tradition of the 18th c (roughly 1700–1797), with painted-lacquer case furniture in saturated reds, greens, blues, and yellows over carved giltwood structure, the declining Republic-of-Venice patron context, and the genre's status as the principal colour-palette break in the furniture arc.</description><content:encoded>&lt;![CDATA[<p>The six prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a>,<a href="/posts/louis-xvi/">Louis XVI</a>,<a href="/posts/biedermeier/">Biedermeier</a>,<a href="/posts/chippendale/">English Chippendale</a>,<a href="/posts/gustavian/">Gustavian</a>, and<a href="/posts/italian-baroque/">Italian Baroque</a> — have together carried the European cabinet tradition from the French royal source through its Continental and Anglophone translations, and then back a full century to open the Italian tradition with the seventeenth-century carved-walnut work of the Roman and Bolognese workshops. The Italian Baroque post closed by promising its own descendant, and this is that descendant: the eighteenth-century Venetian Rococo, the body of work that the cabinet workshops of the declining Republic of Venice produced for the patrician patron class between roughly 1700 and the Napoleonic conquest of 1797.</p><p>The Venetian Rococo is, on the surface, the same translation principle the prior posts have made familiar — and yet it is not. It is not a national substitution of material under a continuing structural register; it is a substitution of<em>register itself</em>. The Italian Baroque carved its ornament into the dark walnut of the case and gilded selected structural members over a red bole ground. The Venetian Rococo kept the carved-giltwood structure but abandoned the walnut entirely, and put in its place a painted-lacquer surface in saturated colour — red, green, blue, yellow grounds, with floral and chinoiserie ornament painted across them. Where the Baroque was a sculptor&rsquo;s medium read in shadow and relief, the Venetian Rococo is a painter&rsquo;s medium read in colour and varnish. This is the seventh post in<em>Reading the Period Cabinet</em>, and it provides what the wood-tone variety table has called for since the Italian Baroque furnished its dark-gilt break: the deliberate<em>colour break</em>, the one genre in the arc where the surface is neither timber nor veneer but paint.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Venetian Rococo piece, for the purposes of beginning to read the style, is the<em>bombé commode</em> — the serpentine-fronted chest of drawers, swelling outward at the front and sides, standing on short cabriole legs, with a carved-giltwood apron, a moulded marble top, and a painted-lacquer finish across the whole case. The commode is what the Venetian patrician patron commissioned for the principal rooms of the<em>palazzo</em> on the Grand Canal, and the form in which the Venetian Rococo principles are most fully concentrated; the carved-giltwood sofa, the console table, and the side chair carry the same vocabulary at smaller scale and in less concentrated form.</p><p>A canonical Venetian Rococo commode, then. Its case is<em>bombé</em> — the word means swollen, and the form is exactly that: a chest whose front and sides bow outward in a continuous serpentine curve, so that no plane of the case is flat and no edge is straight. This is the rococo curve in three dimensions, and it is the structural inheritance the Venetian workshops took from the contemporary French. The case stands on short<em>cabriole legs</em> — the S-curved leg that flares at the knee and tapers to a small scrolled foot — and the legs flow without interruption into a carved-giltwood apron beneath the lowest drawer, the whole lower register reading as a single curved and gilded member rather than as a structure of separate parts. Above the case sits a<em>marble top</em>, cut in the same serpentine outline as the case beneath it and moulded at its edge; the marble is most often a coloured marble — a warm yellow Siena, a grey-veined<em>bardiglio</em>, a red — chosen to sit against the colour of the lacquer rather than to contrast with it.</p><p>The surface, and it is the surface that carries the style, is<em>painted lacquer</em>. The entire case — drawer fronts, sides, apron — is grounded in a single saturated colour: a vermilion or coral red, a deep bottle or apple green, a strong cobalt or pale powder blue, a chrome or straw yellow, more rarely an ivory or a black. Over that coloured ground the workshop painter laid<em>floral and chinoiserie ornament</em> — bouquets and trailing sprays of flowers, ribboned cartouches, and the European fantasy of the Orient: pagodas, parasols, bridges, mandarins, exotic birds, all rendered in the cheerful inaccuracy of a painter who had never been east of the Adriatic. The carved-giltwood structure — the apron, the leg fronts, sometimes a carved cartouche at the centre of the lowest drawer — is gilded over the lacquer in the manner the Baroque had established, but it is now subordinate to the painted surface rather than the principal event. The Venetian Rococo, in short, is a piece of furniture conceived as a painted object.</p><figure><img src="/images/posts/italian-rococo-venetian/detail-lacquer.png" alt="A close detail of Venetian lacquer surface — saturated colored ground with painted floral or chinoiserie ornament"><figcaption><p>A close detail of a Venetian lacquer surface — the saturated coloured ground (here red) with painted floral and chinoiserie ornament. The hand-painted Venetian technique —<em>lacca veneziana</em>, Venetian lacquer proper — imitated the appearance of Chinese export lacquer at Venetian workshop scale and speed, building up the surface from a gesso ground, coloured paint, and many varnish coats rather than from the East Asian<em>urushi</em> sap that genuine Chinese lacquer required. The two are distinct media, and the distinction is the first thing the collector reads for.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The lacquer, first, is most of what one is reading for.<em>Lacca veneziana</em> — Venetian lacquer proper, the true hand-painted technique — is not a finish but a built-up structure of layers, and the period work shows that structure in its wear and its damage. Beneath the colour lies a<em>gesso ground</em> laid over the prepared wood; over the gesso, the saturated coloured paint; over the paint, the hand-rendered ornament; and over the whole, a succession of varnish coats —<em>sandracca</em>, the local sandarac resin varnish, built up and polished between coats — that gave the surface its depth and its sheen and that yellow and craze with age in a characteristic way. A genuine period lacquer surface shows<em>fine crazing</em> across the varnish, a warm darkening of the originally bright ground, paint losses that step down through the layers to the gesso and the wood rather than flaking off cleanly, and an ornament drawn freehand with the small irregularities of a painter&rsquo;s hand. It is a surface read at close range in raking light, and its layered construction is the principal authentication evidence.</p><p>The carved giltwood, second. Beneath and around the painted case the Venetian workshop kept the carved-giltwood register the Baroque had handed down — but moved it from the rectilinear architectural vocabulary of the seventeenth century into the rococo curvilinear vocabulary of the eighteenth. The scrollwork is now asymmetric, the cartouches are<em>rocaille</em> shellwork, the putti and mascarons are lighter and more playful, and the gilt is water-gilt over a gesso-and-bole ground exactly as the Baroque gilders had laid it. Where the carving survives unrestored it shows the same wear pattern the Baroque post described — rubbed at the high points, surviving in the hollows, showing through to a red bole at the worn spots — and that bole ground is as much an authentication indicator here as it was a century earlier.</p><figure><img src="/images/posts/italian-rococo-venetian/detail-gilt.png" alt="A close detail of Venetian carved giltwood structural element — scrollwork, putto, mascaron"><figcaption><p>A close detail of Venetian carved-giltwood ornament — the asymmetric<em>rocaille</em> scrollwork, putti, and mascarons that form the structural register beneath and around the lacquer surface. The carving is water-gilt over a gesso-and-bole ground in the tradition the Italian Baroque established; what has changed is the vocabulary, from the rectilinear architectural ornament of the seventeenth century to the curvilinear rococo ornament of the eighteenth.</p></figcaption></figure><p>The marble top, third, where it survives. The Venetian Rococo commode was conceived to carry a marble slab, cut in the serpentine outline of the case and moulded at its edge, and a period commode that has lost its marble has lost an integral element rather than an accessory. The marble is most often a warm coloured stone — Siena yellow,<em>bardiglio</em> grey,<em>rosso</em> red — and the underside, where one can examine it, should show the saw and tooling marks of the period mason and a profile that follows the case exactly. A flat replacement top, or a top in white statuary marble where the case calls for a coloured stone, is one of the commonest later alterations.</p><figure><img src="/images/posts/italian-rococo-venetian/detail-marble.png" alt="A close detail of a Venetian Rococo marble top — colored marble in the rococo serpentine outline"><figcaption><p>A close detail of a Venetian Rococo marble top — coloured marble cut in the rococo serpentine outline that crowns the bombé case and moulded at its edge. The marble was integral to the commode as designed; a piece that has lost its top, or carries a flat white replacement where a coloured serpentine slab is called for, has lost an element rather than an accessory.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Venetian Rococo period proper runs from about 1700 to the Napoleonic conquest of 1797, with apex production concentrated in the middle decades — roughly 1730 through 1780. The political fact that frames the whole tradition is that the<em>Republic of Venice</em> — the Serenissima, the Most Serene Republic, a thousand years a maritime and commercial power — was, across exactly these decades, in a long and not unpleasant decline. The trade routes had moved to the Atlantic; the eastern empire had been ceded; the Republic had withdrawn from the great-power contests of the century and settled into a neutrality that was also an irrelevance. What it had not lost was its wealth, its patrician class, and its appetite for display. The eighteenth century was the century of Venetian<em>Carnevale</em> at its most extravagant — a carnival season that ran for months, conducted behind masks, in which the ordinary distinctions of rank were suspended — and of the Grand Tour, which brought a steady traffic of foreign visitors and foreign money. A society that had stopped governing an empire and turned its full attention to pleasure is, as it happens, an excellent client for the decorative arts.</p><p>The Venetian decorative industries supplied that client across the board, and the painted-lacquer furniture is best understood as one product of a city organised around luxury manufacture. The glassworks of<em>Murano</em> produced the mirrors and chandeliers; the<em>textile</em> workshops produced the silks and velvets; the painters — Tiepolo, Canaletto, Guardi, Longhi — produced the ceilings and the<em>vedute</em> and the conversation-pieces; and the cabinet workshops produced the lacquered commodes and consoles that stood beneath the mirrors and the ceilings. The saturated colour of the furniture is the colour of the rooms it was made for, and the chinoiserie ornament is of a piece with the Republic&rsquo;s long-standing and now largely nostalgic identity as the European city that faced east.</p><p>The high tradition ended on a date. In 1797, in the course of his Italian campaign,<em>Napoleon Bonaparte</em> extinguished the Republic of Venice — the thousand-year constitution dissolved, the last Doge deposed, the city handed first to Austria and later absorbed into the Napoleonic order. The patrician patron class did not vanish, and the workshops did not close, but the system that had sustained the apex production was gone, and what followed was a continuation in a diminished and increasingly commercial register. This matters to the collector for a reason the next section will make load-bearing: the painted-lacquer Venetian look outlived the Republic by a long way, and most of the painted Venetian furniture in circulation belongs not to the eighteenth-century high tradition at all but to the nineteenth-century and later trade that imitated it.</p><figure><img src="/images/posts/italian-rococo-venetian/antecedent.png" alt="A 17th-c Italian Baroque cabinet — the carved-walnut antecedent the Venetian Rococo translated into painted-lacquer surface"><figcaption><p>A 17th-c Italian Baroque cabinet — the carved-walnut antecedent. The Venetian Rococo of the 18th c kept the Baroque structural vocabulary (the carved-giltwood ornament, the architectural descent of the case) but translated the surface from dark carved walnut into saturated coloured lacquer, and translated the ornamental register from the rectilinear-architectural Baroque into the curvilinear rococo. The carved giltwood is the continuity; the painted surface is the break.</p></figcaption></figure><p>The load-bearing distinction every Venetian Rococo collector must master is therefore<em>the distinction between genuine eighteenth-century Venetian work and the nineteenth-century and later revival furniture made in the Venetian-style painted register</em> — and it is load-bearing precisely because the revival material is far more common than the genuine article, common enough that an unwary buyer will see a dozen revival commodes for every period one and quite reasonably conclude that the revival commode is what a Venetian Rococo commode looks like. The revival began in earnest in the later nineteenth century, when a prosperous and tourist-conscious Venice rediscovered its own eighteenth-century manner as a marketable identity, and it has not stopped since; &ldquo;Venetian painted furniture&rdquo; is a continuously-produced decorative type, and a great deal of it is honest decorative furniture that was never intended to deceive. The distinction is not, then, a matter of catching forgeries — most revival pieces are not forgeries — but of dating accurately what one is looking at.</p><p>The genuine eighteenth-century piece reads differently in four respects, and the collector carries all four. First,<em>construction</em>: the period commode is built by the period hand, with hand-cut dovetails of irregular spacing, pit-sawn boards showing the period saw, hand-wrought hardware, and the shrinkage, oxidation, and wear of two and a half centuries on every secondary surface — drawer linings, backboards, underside. The revival piece shows machine-cut dovetails of mechanical regularity, circular-saw marks, modern screws, machine-planed or plywood secondary timber, and a brevity of age that the back and the interior cannot disguise even when the front has been distressed. Second, the<em>lacquer</em>: the genuine<em>lacca veneziana</em> surface is built up in the layered sandarac-varnish structure described above and shows the fine crazing, the warm darkening, and the layered paint losses of real age; the revival surface is most often a thinner modern paint-and-varnish, sometimes sprayed, with crazing absent, uniform, or artificially induced. Third, the<em>drawing</em>: the eighteenth-century ornament is painted by a workshop hand trained in the rococo idiom, fluent and slightly irregular and confident, where the revival ornament is frequently weaker, more repetitive, or — on the cheaper end — a printed-and-applied decoration masquerading as paint. Fourth, the<em>form</em>: the genuine bombé case has the slightly heavy, structurally-resolved curve of the period workshop, where the revival case is often a thinner, more exaggerated serpentine that betrays a maker imitating a shape rather than building from the tradition that produced it. None of the four is decisive alone; together they settle the question, and the collector who learns to read all four at once has the essential Venetian Rococo competence.</p><p>A second distinction sits one level down and is worth carrying as a subsidiary discrimination, because it confuses even buyers who have mastered the dating question. It is the distinction between the two Venetian decorative techniques themselves.<em>Lacca veneziana</em>, described above, is the<em>painted</em> technique — coloured paint and hand-rendered ornament built up under varnish, the surface that the workshop painter drew freehand. The other technique travels under several names —<em>lacca povera</em>,<em>arte povera</em>, and, confusingly,<em>lacca contraffatta</em> — and the collector should know at the outset that these three terms are synonyms for one and the same thing. The first two mean, respectively,<em>poor lacquer</em> and<em>poor art</em>; the third means<em>counterfeit lacquer</em>, and it is one of the small ironies of the trade that the most prestigious-sounding of the three names attaches not to the painted work at all but to this, the cheaper method. For the technique itself is<em>decoupage</em>: engraved and hand-coloured<em>printed paper cutouts</em> were pasted onto the prepared and coloured ground and then sealed under the same many-coat varnish. Both produce a coloured-and-ornamented Venetian surface; both belong to the eighteenth-century high tradition; both are genuine and collectable. But one is painted and one is printed-and-applied, and the difference is legible at close range — the<em>lacca povera</em> ornament shows the slightly raised edges of the pasted paper, the flat even tone of an engraving rather than the modulated stroke of a brush, and on damaged examples a lifting paper edge — and it bears materially on value, since the fully hand-painted<em>lacca veneziana</em> piece sits above the<em>lacca povera</em> piece in the period hierarchy. The collector should be able to name which technique is in front of him, and should not let the cheaper word<em>povera</em> mislead him into thinking the technique a fake; it is not a fake, it is a different and genuine eighteenth-century medium.</p><figure><img src="/images/posts/italian-rococo-venetian/pattern-book-page.png" alt="A page from a Venetian cabinet-maker's pattern book — lacquered commode, sofa, console, chair in the rococo register"><figcaption><p>A page from a Venetian cabinet-maker&rsquo;s pattern book — perspective drawings of the principal forms in the Venetian Rococo register: the bombé lacquered commode, the carved giltwood sofa, the rococo console table, the lacquered chair with cabriole legs.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/italian-rococo-venetian/sibling-italian-baroque.png" alt="An Italian Baroque cabinet — dark walnut + heavy gilt, the 17th-c antecedent" loading="lazy"/><figcaption>Italian Baroque<em>— the carved-walnut antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-rococo-venetian/sibling-louis-xv.png" alt="A Louis XV French commode — French rococo with bombé case, exotic veneer, ormolu" loading="lazy"/><figcaption>Louis XV<em>— the French rococo counterpart</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-rococo-venetian/sibling-spanish-rococo.png" alt="A Spanish Rococo piece — Iberian sibling with different palette and form" loading="lazy"/><figcaption>Spanish Rococo<em>— the Iberian sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-rococo-venetian/sibling-french-regence.png" alt="A French Régence piece — early-rococo French, transitional between Louis XIV and Louis XV" loading="lazy"/><figcaption>French Régence<em>— the transitional French style</em></figcaption></figure></div><figcaption>Four styles most often confused with Italian Rococo Venetian, drawn for comparison.</figcaption></figure><p>An<em>Italian Baroque</em> is the seventeenth-century antecedent the Venetian Rococo descended from — the post directly before this one in the arc. The continuity is the carved-giltwood structure and the architectural descent of the case; the break is total in surface and register. The Baroque is dark carved walnut, with deep-relief figurative carving in the wood itself and a rectilinear architectural proportion; the Venetian Rococo is painted lacquer in saturated colour, with rococo curvilinear ornament and a serpentine bombé case. The rule of thumb: dark carved walnut with deep-relief figurative carving is Italian Baroque; saturated coloured lacquer over carved giltwood with a bombé case is Italian Rococo.</p><p>A<em>Louis XV</em> is the French rococo counterpart, the contemporary against which the Venetian is most often weighed, and the comparison is instructive because the two share the rococo form vocabulary exactly — the bombé case, the cabriole leg, the asymmetric rocaille. What they do not share is the surface. The French royal register works in<em>exotic veneer</em> — kingwood, tulipwood, marquetry parquetry — with<em>cast gilt-bronze ormolu mounts</em> bolted to the case, the whole conceived as a cabinet-work-and-bronze object; the Venetian works in<em>painted lacquer</em> over more ordinary local timber, the whole conceived as a painted object. The rule of thumb: bombé case in exotic veneer with cast ormolu mounts is Louis XV; the same bombé case in painted coloured lacquer is Italian Rococo.</p><p>A<em>Spanish Rococo</em> is the Iberian sibling — the eighteenth-century Spanish reception of the rococo, produced for the Bourbon court in the same decades. Spain received the rococo through a French dynasty, and the Spanish work shares the curvilinear vocabulary, but carries it in a characteristically Iberian register: heavier proportion, carved-and-gilded or carved-and-painted giltwood at a denser scale, and an ornamental temper inherited from the Spanish Baroque rather than the buoyant painted-chinoiserie lightness of Venice. The rule of thumb: a heavier, more densely carved rococo with the Iberian temper is Spanish Rococo; the lighter painted-lacquer rococo with chinoiserie ornament is Venetian.</p><p>A<em>French Régence</em> is the transitional French style — the early-rococo register that bridges the Louis XIV royal Baroque and the mature Louis XV rocaille, named for the regency of 1715–1723. It is rococo in the way an overture is a symphony: the curves have begun, the architectural rigidity of the Louis XIV case has relaxed, but the full serpentine bombé swelling and the full asymmetry of the rocaille have not yet arrived, and the surface is still veneer-and-ormolu in the French manner. The rule of thumb: a transitional, half-relaxed French case in veneer and ormolu is Régence; the fully serpentine painted-lacquer case is the mature Venetian Rococo.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>surface</em>, because the surface is the style. The case should be<em>painted lacquer</em> — a saturated coloured ground (red, green, blue, yellow, more rarely ivory or black) carrying hand-rendered floral and chinoiserie ornament, built up in the layered<em>lacca veneziana</em> structure of gesso, paint, and many varnish coats. A piece in this rococo form but surfaced in exotic veneer is Louis XV; a piece in carved dark walnut is the Italian Baroque antecedent; a piece whose ornament is pasted printed paper rather than brushwork is the<em>lacca povera</em> (also<em>arte povera</em>, also<em>lacca contraffatta</em>) variant of the same Venetian tradition, genuine but a step down in the period hierarchy. The colour itself is diagnostic: the eighteenth-century palette is saturated but warmed and slightly darkened by age beneath a crazed and yellowed varnish, and a surface that is bright, even, uncrazed, and thin is the signature of the revival rather than the period.</p><p>One looks next at the<em>carved giltwood beneath the paint</em> — the apron, the leg fronts, the central cartouche — which should be water-gilt over a gesso-and-bole ground in the rococo curvilinear vocabulary, and which should show, where unrestored, the period wear pattern: rubbed at the high points, surviving in the hollows, breaking through to a red bole ground rather than to a modern yellow or white base or to bare wood. The gilding is the line of continuity back to the Italian Baroque, and it is read by the same evidence.</p><p>One looks then at the<em>form and the construction together</em>. The case should be<em>bombé</em> — serpentine in front and sides, on cabriole legs flowing into a carved apron — with the particular structurally-resolved curve of the period workshop rather than the thinner, more pointed, more exaggerated serpentine of the revival. And the construction, examined on the secondary surfaces, should be the construction of the period hand: irregular hand-cut dovetails, period saw marks, hand-wrought hardware, and two and a half centuries of oxidation and shrinkage on the backboards and drawer linings. This is where the load-bearing distinction is settled. The front of a piece can be made to look eighteenth-century by a competent hand; the back and the interior almost never can, and the collector who has trained himself to read the secondary surfaces will date a Venetian commode more reliably than one who reads only the painted front.</p><p>And one looks, finally, at the<em>marble top</em>, which the period commode was designed to carry — a coloured marble, cut in the serpentine outline of the case and moulded at its edge, with the period mason&rsquo;s tooling marks on its underside. A lost top, a flat replacement, or a white statuary slab where a coloured serpentine one is called for is a common alteration, and while it does not by itself date the piece, it is part of the integral specification the collector checks against.</p><p>The next post in the furniture arc will be either<em>Hepplewhite</em> — to set out the English neoclassical satinwood tradition and return the arc to the Anglophone line — or<em>Spanish Baroque</em>, to open the Iberian sibling tradition with its iron-and-leather register. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Hamadan</title><link>https://mtclinton.com/posts/hamadan/</link><pubDate>Wed, 20 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/hamadan/</guid><category>antiques</category><description>Seventh per-subject post in Reading the Antique Rug — the broader Hamadan district village tradition, the largest Persian weaving region by village count, producing many sub-types under one dealer label, with the rust / camel / brown earth-tone palette and the single-weft Hamadan construction as the load-bearing collector distinction.</description><content:encoded>&lt;![CDATA[<p>The six prior posts in this arc —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>,<a href="/posts/caucasian-kazak/">Caucasian Kazak</a>,<a href="/posts/bakshaish/">Bakshaish</a>,<a href="/posts/kashan/">Kashan</a>, and most recently<a href="/posts/bidjar/">Bidjar</a> — treated, between them, two or three named places apiece, each with its own clean attribution: a city, a village, a Kurdish district. Hamadan is a different kind of subject altogether. It is not a place so much as a<em>label</em>, and the label covers more ground than any other in the Persian trade. The Hamadan district is the largest Persian weaving region by village count — the figure most often cited runs past eight hundred weaving villages, and some authorities push it past a thousand — and the rugs that come out of it reach the dealer under one word that internally divides into a dozen sub-types. This is the seventh post in<em>Reading the Antique Rug</em>, and it treats Hamadan in the village-region position the arc has not yet had occasion to treat.</p><p>It also breaks the palette. Bidjar closed the arc to date on the dark wine-red and dark navy of the Kurdish district — the deepest, most saturated band the arc had reached. Hamadan opens a new one entirely: the Hamadan ground is rust, camel, brown, the earth-tones of the dry Zagros foothill country, and a reader coming to a Hamadan straight from a Bidjar will register the change before reading a single motif. The break is deliberate. But the palette is not what unifies the eight hundred villages, and a post that rested its attribution on colour would mislead from the first paragraph. The thing that unifies the Hamadan district is structural, and not visual at all: the<em>single-weft Hamadan construction</em> — a single shoot of weft passed between each row of knots, where the Heriz, Tabriz, and Kashan workshops pass two. That single weft is the load-bearing collector distinction for the entire region, and the post will carry it the way the Bidjar post carried the handle test.</p><h2 id="the-specimen">The Specimen</h2><p>A Hamadan that one will encounter is, in its commonest form, a small-to-medium piece — the<em>zaronim</em> and<em>dozar</em> sizes, three feet by five and four feet by six and a half — with runners exceedingly common, because the Hamadan village loom is narrow and the runner is the size the narrow loom produces most naturally. Larger Hamadans exist, but the district&rsquo;s centre of gravity sits well below the room-size carpet; one meets far more Hamadan scatter rugs and runners than carpets, and the proportion is itself a soft diagnostic. The Hamadan rug wears its village constraints visibly.</p><p>The composition, on the canonical pieces, is one of a few related village vocabularies. The most familiar is the<em>single central medallion</em> — one bold medallion, often a hooked or pole-ended diamond, set on an open or sparingly-figured ground, with plain or contrasting corner spandrels; the drawing is heavy in the line and a little irregular in its symmetry, drawn from memory and the loom rather than from a cartoon. A second is the<em>repeat across the field</em> — boteh in vertical rows, the herati motif, or a small disconnected floral spray at village scale. A third, common on the camel-ground pieces, is the<em>open camel field</em> with a small medallion floated in it and little else, the empty ground left to do the work that figuration does elsewhere. None of these is a workshop composition. The Hamadan is, before it is anything else, a village rug.</p><p>The palette is the rust / camel / brown earth-tone register, and it is worth being precise — and properly cautious — about the camel. On many of the better antique Hamadans the camel-coloured ground is an<em>undyed natural fleece</em>, used at its own colour, neither dyed nor bleached; and whether that fleece is camel hair proper or simply the wool of a camel-toned sheep is a question on which the literature has never wholly settled, the older pieces apparently giving examples of both. What is not in doubt is that the warmth is the fibre&rsquo;s own and not the dyepot&rsquo;s, and the undyed camel ground, of whichever origin, is one of the surer marks of the older village production. Around it the palette runs rust-red, a soft madder well short of the Bidjar oxblood or the Heriz brick; terracotta; walnut brown; a sparing indigo for outline and border-ground; ivory and ochre in small quantities. The whole reads warm, dry, and earthen, and it reads that way by district habit, not by accident of fading.</p><p>Several sub-types are worth naming, because the dealer&rsquo;s single word &ldquo;Hamadan&rdquo; conceals them and the reader will meet them under their own names as often as under the district label.<em>Malayer</em>, from the town to the south, is the finest and most prized of the Hamadan-district weaves — denser, better-drawn, and frequently sold on its own name.<em>Tafresh</em>, to the east, runs a more curvilinear and floral drawing than the typical Hamadan village.<em>Lilihan</em>, a village near Malayer but properly in the Arak district to its south, produced a distinctive Sarouk-influenced floral rug, often single-wefted in the Hamadan manner despite the Sarouk drawing. The<em>Hamadan-area Sarouks</em> — the dealer&rsquo;s<em>Sarouk-Mahal</em> — are the district&rsquo;s commercial floral production, drawn toward the central-Persian Sarouk style for the export market. And the oldest label of all, now largely retired, is<em>Mosul</em> — a name that never meant the Iraqi city but was the trade&rsquo;s nineteenth-century word for the Hamadan-district village rug as a class, shipped west through the Mosul route. A rug catalogued as a &ldquo;Mosul&rdquo; in an old sale record is, almost always, a Hamadan.</p><figure><img src="/images/posts/hamadan/detail-medallion.png" alt="A close detail of a Hamadan single-medallion — village-loom rust / camel ground"><figcaption><p>A close detail of a Hamadan central medallion — the village-loom drawing in the rust / camel earth-tone register that distinguishes Hamadan from the redder Persian districts.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The foundation is where the Hamadan district is<em>one thing</em>, and it is worth laying out the single-weft construction with some care, because it is the diagnostic on which the whole post rests. In the standard Persian practice — the practice of the Heriz, Tabriz, Kashan, and Bidjar workshops — the weaver ties a row of knots, then passes<em>two</em> weft shoots across before tying the next row: a first pulled tight, a second left slack. The two-weft system holds alternate warps at two different depths; it makes the warps lie in two planes, one set depressed behind the other, and it produces the firm, two-level back those workshop rugs share. The Hamadan weaver does something simpler. After each row of knots, a<em>single</em> weft shoot is passed across, and the next row is tied directly against it. One weft, not two.</p><p>The consequence is immediate and visible, though it is not the consequence the beginner expects. With a single weft between knot rows, the warps lie in<em>one plane</em> — neither set is depressed behind the other — and a single shoot of weft, lacking the second shoot that would bury the alternate warps, leaves every other warp exposed on the back. The Hamadan back accordingly shows a regular ribbing — a series of fine raised lines running the width of the rug, one for each exposed alternate warp — and that striped, ridged, faintly spackled back is the thing to look for. A single-weft rug is, to the hand, looser and more pliable than a double-weft rug at the same knot count; it drapes readily and folds without protest. This is neither a defect nor a sign of low grade. It is the structural signature of an entire weaving region, and it is the single most reliable thing one can establish about a candidate Hamadan: turn the rug over, and if the back shows that regular ribbing of exposed alternate warps over a single-plane foundation, one is very probably in the Hamadan district, whatever the medallion says.</p><p>The knot itself is the<em>symmetric Turkish knot</em>, used throughout the district — which places Hamadan, structurally, with the Turkic weavers of the Sahand district at Heriz rather than with the asymmetric-knot workshops of the central Persian court, and which is consistent with the broadly Turkic-speaking population of much of the Hamadan countryside. Knot density runs at the village register: roughly<em>sixty to ninety knots per square inch</em> on the typical antique Hamadan, with the finer Malayer pieces reaching higher. This is not a fine rug by the standard of the Kashan court at two hundred KPSI, and it is not meant to be read as one. The Hamadan is a village rug, and its virtues are village virtues — the wool, the dye, the directness of the drawing — not the count.</p><p>The wool, on the better Hamadans, is very good wool indeed. The Zagros foothill flocks supply a long-stapled, lustrous, high-lanolin fleece, and the village weaver, working close to the source, had first call on it; a well-kept antique Hamadan has a sheen and a resilience under the hand that the knot count alone would not predict. The foundation is cotton — warp and weft alike, on the great majority of the district&rsquo;s production — and the cotton foundation under a single weft, with the flat level back, is a combination the Hamadan district produces and the wool-warp Caucasian and Turkmen rugs do not.</p><figure><img src="/images/posts/hamadan/detail-border.png" alt="A close detail of a Hamadan main border — repeating boteh or rosette in earth-tone vocabulary"><figcaption><p>A close detail of a Hamadan main border — the village-grade boteh or rosette repeat in earth-tone palette.</p></figcaption></figure><p>The last constraint is the loom. The Hamadan village loom is narrow — a village fixture, built to the dimensions of a village room — and it is the reason the district&rsquo;s output skews so heavily toward runners and small scatter pieces. A weaver cannot produce a rug wider than the loom, and the narrow loom produces, by simple geometry, far more long-and-narrow rugs than square ones. When one notices that a great many Hamadans are runners, one is noticing the loom.</p><figure><img src="/images/posts/hamadan/detail-foundation.png" alt="A close detail of a Hamadan knot-back — the single-weft Hamadan construction, the principal structural diagnostic"><figcaption><p>A close detail of the back of a Hamadan rug — the single weft shot between knot rows is the principal structural diagnostic for the Hamadan region, distinguishing it from the two-weft Tabriz / Heriz / Kashan workshops.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The city of Hamadan is one of the oldest continuously inhabited places in Persia. It is Ecbatana of antiquity — the summer capital of the Median kings, taken into the Persian empire by Cyrus, old enough that the rug trade of the nineteenth century was a recent event in its history rather than a defining one. The city sits at the foot of Mount Alvand, in the dry foothill country on the eastern flank of the Zagros, and the eight hundred villages that the dealer&rsquo;s word &ldquo;Hamadan&rdquo; gathers up are scattered across that country in every direction — south toward Malayer, east toward Tafresh, out across a region large enough that no single weaving tradition could ever have unified it by style. What unified it was the city, and the road, and the merchant.</p><p>For the Hamadan district is, before it is a weaving region, a<em>trade</em> region — and the rug label is, in the end, a fact about commerce rather than about craft. Hamadan city sat astride the old caravan route running west toward Mesopotamia, and the village rugs of the whole foothill country were carried into the city, sorted, baled, and shipped out along that route. The trade graded and named them not by their village of origin — there were too many villages, and the buyer in London or New York had heard of none of them — but by the port of exit and the class of goods. Hence &ldquo;Mosul,&rdquo; the nineteenth-century label, which named the route and not the rug. The single word survived because it was useful to everyone except the scholar: the weaver was paid, the merchant shipped a known quantity, the buyer received a rug of predictable character. That the word covered a thousand villages was precisely the point of it.</p><p>The commercial export trade, intensifying through the 1880s and 1890s as European and American demand grew, did to the Hamadan district what it did to every Persian weaving region — it regularised the production. The older village rug had been woven for use, or for a dowry, or for the floor of the house that wove it; its drawing followed the weaver&rsquo;s memory and its palette followed whatever wool and dye the village had. The export trade wanted a predictable product, and it got one: by the turn of the century the Hamadan village was weaving to a more uniform standard, in more uniform sizes, with the rougher edges of village idiosyncrasy planed off. The single-weft construction survived the regularisation — it was the district&rsquo;s habit, not its irregularity — but much of the older variability did not.</p><figure><img src="/images/posts/hamadan/antecedent.png" alt="An older Hamadan-district village rug, pre-1880 — looser drawing, more variable colour palette"><figcaption><p>An older Hamadan-district village rug, pre-commercial — looser drawing and more variable palette before the late-19th-c export market regularised the village production into a more uniform dealer-grade product.</p></figcaption></figure><p>The antecedent, accordingly, is the older Hamadan-district village rug — the pre-1880s piece, woven before the export trade reached deep into the foothill country. It is looser in the drawing, more variable in the palette, and altogether less of a<em>product</em> than the dealer-grade Hamadan that succeeded it. The undyed camel ground is more common on it; the medallion is drawn with the freedom of a weaver answering to no cartoon; the colours are whatever the village had, and they vary from rug to rug in a way the regularised production does not. These older pieces are harder to find and harder to attribute precisely, since the very thing the trade later imposed — the uniform district character — is the thing they lack. But they are the ground out of which the familiar Hamadan grew, and a collector who has handled a few of them reads the later dealer-grade rug differently for it.</p><figure><img src="/images/posts/hamadan/portfolio-page.png" alt="A Victorian connoisseur's portfolio on the Hamadan district — map of the broader region with sub-type locations"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Hamadan district — district map showing the broader region with the principal sub-type villages (Malayer, Tafresh, Lillihan, the Mosul label) located; archetype drawings of three Hamadan sub-types.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four types stand near enough to Hamadan that the beginner confuses them with it, and the four divide neatly: two are the Kurdish neighbours to the west whose rugs reach the same dealers, one is the central-Persian commercial production that the Hamadan district itself partly imitated, and one is the district to the north. Distinguishing them is most of the work of reading the Hamadan region — and the single-weft test settles three of the four at a glance.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/hamadan/sibling-bidjar.png" alt="A Bidjar rug — extreme density, dark wine-red ground, the iron-rug Kurdish neighbour to Hamadan" loading="lazy"/><figcaption>Bidjar<em>— the dense Kurdish neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hamadan/sibling-senneh.png" alt="A Senneh rug — fine Kurdish city workshop, distinct Senneh knot, lighter handle than Hamadan" loading="lazy"/><figcaption>Senneh<em>— the fine Kurdish city workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hamadan/sibling-sarouk.png" alt="A Sarouk rug — central Persian commercial American-market staple, deeper wine-red, finer knot than Hamadan" loading="lazy"/><figcaption>Sarouk<em>— the American-market commercial</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/hamadan/sibling-heriz.png" alt="A commercial Heriz rug — northwestern Persian district to the north, brick-red, larger medallion than Hamadan" loading="lazy"/><figcaption>Heriz<em>— the northern district</em></figcaption></figure></div><figcaption>Four types most often confused with Hamadan, drawn for comparison.</figcaption></figure><p>A<em>Bidjar</em> is the dense Kurdish rug treated in the<a href="/posts/bidjar/">post immediately before this one</a>, and it is the cleanest of the four contrasts because the two rugs disagree on almost everything. Bidjar runs the double weft, the wet-loom compression, the dark wine-red or navy palette, and the heavy rigid handle that earns it the name &ldquo;iron rug of Persia.&rdquo; Hamadan runs the single weft, no compression of any kind, the rust / camel earth-tone palette, and a loose pliable handle. The two are geographic neighbours — Bijar town sits in the Kurdish country to the northwest — but they are structural opposites. The rule of thumb: dark, dense, double-weft, heavy in the hand is Bidjar; rust-and-camel, loose, single-weft, light in the hand is Hamadan.</p><p>A<em>Senneh</em> is the fine Kurdish city workshop rug from Sanandaj, the other Kurdish neighbour, and it is the type whose name most often misleads — and the name misleads in a way worth pausing on. The asymmetric Persian knot is universally called the<em>Senneh knot</em> in the trade, in honour of the town; yet the weavers of Senneh itself, by one of the small ironies in which the rug literature is rich, do not use it. A Senneh draws at the very fine end of the Persian range — three hundred knots per square inch and finer — on a meticulous workshop cartoon, and it does so with the<em>symmetric</em> knot, the knot that bears another tradition&rsquo;s name entirely. A Hamadan at sixty to ninety knots, village-drawn and single-wefted, is a wholly different object. The rule of thumb: fine, exact, city-workshop drawing on a thin firm rug is Senneh; coarse, direct, village drawing on a loose single-weft rug is Hamadan.</p><p>A<em>Sarouk</em> is the central-Persian commercial floral rug, the great staple of the early-twentieth-century American market — and it is the most instructive of the four, because the Hamadan district itself produced rugs in imitation of it. The true Sarouk, from the Arak region, runs the double weft, a denser and more even knot, a deeper rose-red or wine ground, and the dense detached-floral drawing the American trade prized. The Hamadan-area<em>Sarouk-Mahal</em> borrows the floral style but keeps the district&rsquo;s single weft and earth-tone palette. The rule of thumb: double-weft, deep wine, dense even floral drawing is a true Sarouk; single-weft, earth-toned, looser in the hand, however floral the drawing, is the Hamadan district wearing Sarouk clothes.</p><p>A<em>Heriz</em> is the village commercial production of the Sahand district to the north, treated in the<a href="/posts/heriz/">Heriz post</a>. Heriz shares the symmetric Turkish knot with Hamadan and a certain village directness of drawing, which is enough to catch a beginner. But Heriz runs the<em>double</em> weft, the large stepped polygonal medallion, and the brick-red palette of the Sahand district — a brighter, harder red than the soft Hamadan rust — and the Heriz back, two-planed and firm, parts company with the flat single-plane Hamadan back at once. The rule of thumb: large stepped medallion, brick-red, double-weft and firm is Heriz; small village medallion or field repeat, rust and camel, single-weft and loose is Hamadan.</p><p>The pattern across all four is worth stating plainly, because it is the working value of the whole post. Three of the confusable types — Bidjar, Sarouk, Heriz — are double-weft rugs, and the single-weft test separates Hamadan from every one of them on the evidence of the back alone. The fourth, Senneh, is a single-weft city rug, and there the knot count and the quality of the drawing carry the distinction instead. Establish the weft first; almost everything else follows from it.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Hamadan comes down to a short ordered checklist that the reader of the prior rug posts will find familiar in structure, and that begins — as the Bidjar post began with the handle and the Heriz post with the medallion — with the move that does the most work for the least effort. For Hamadan that move is to turn the rug over.</p><p>One looks first, and principally, at the<em>weft</em>. One turns the rug face-down and reads the back. If the back shows a regular ribbing — every other warp left exposed as a fine raised line running the width of the rug, the foundation lying in a single plane with neither set of warps depressed behind the other — one is looking at single-weft construction, and one is very probably in the Hamadan district. If the foundation is depressed into two planes, with alternate warps riding behind their neighbours and buried by the second weft, one is looking at a double-weft rug, and whatever else it is, it is not a Hamadan. This single observation settles the broad attribution and, as the previous section laid out, separates Hamadan from three of its four nearest confusions at a stroke. It is the cheapest reliable test in the whole arc, and it should be done first.</p><p>One looks next at the<em>palette</em>. The Hamadan ground is rust, camel, terracotta, walnut brown — the earth-tone register — and a rug that reads as a bright brick-red, a deep wine, or a pale ivory is, palette alone, pointing away from the district. The camel deserves particular attention: a ground of soft, undyed, camel-coloured fleece — whether the hair of the camel itself or the wool of a camel-toned sheep, a point the rug is rarely obliging enough to settle — is a positive Hamadan mark, and on the older village pieces it is one of the surer ones. A rug whose warmth comes from undyed fleece rather than from dye is speaking the Hamadan district&rsquo;s oldest dialect.</p><p>One looks at the<em>proportions and the drawing</em>. The Hamadan loom is narrow, and the district&rsquo;s output skews toward runners and small scatter pieces; a long narrow rug is, on the balance of probability, more likely to be a Hamadan than a square carpet is. The drawing should be village drawing — a bold single medallion or a field repeat, heavy in the line, drawn from memory rather than from a fine cartoon, a little irregular in its symmetry. Workshop precision argues against the attribution; village directness argues for it.</p><p>And one looks, last, at the<em>sub-type within the label</em>. Having established that a rug is a Hamadan-district piece, the further question — and it is a price-bearing question — is<em>which</em> Hamadan. A markedly finer, better-drawn, denser piece may be a Malayer, and is worth more under that name than under the district&rsquo;s. A curvilinear, floral piece may be a Tafresh. A Sarouk-style floral on the single-weft foundation may be a Lilihan or a Sarouk-Mahal. And a rug catalogued in an old record as a &ldquo;Mosul&rdquo; is, almost certainly, a Hamadan-district village rug under the trade&rsquo;s retired nineteenth-century name. The district label is the beginning of the attribution, not the end of it; the eight hundred villages do not all weave the same rug, and the collector&rsquo;s work is to hear the sub-type inside the single word the dealer offers.</p><p>The next post in the rug arc will be either<em>Tekke</em> — to open the Turkmen tradition and the central Asian wool-warp register — or<em>Sarouk</em>, to extend the central Persian commercial-export tradition into the American-market arc that the Hamadan region partly supplied. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Italian Baroque</title><link>https://mtclinton.com/posts/italian-baroque/</link><pubDate>Tue, 19 May 2026 19:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/italian-baroque/</guid><category>antiques</category><description>Sixth per-subject post in Reading the Period Cabinet — the 17th-c Italian Baroque furniture tradition under cardinal-and-prince papal patronage, the Roman and Bolognese workshops with the Florentine pietra-dura industry alongside, the Bernini circle as principal aesthetic source, and the named-master-versus-anonymous-workshop attribution problem as the post's load-bearing collector knowledge.</description><content:encoded>&lt;![CDATA[<p>The five prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a>,<a href="/posts/louis-xvi/">Louis XVI</a>,<a href="/posts/biedermeier/">Biedermeier</a>,<a href="/posts/chippendale/">English Chippendale</a>, and<a href="/posts/gustavian/">Gustavian</a> — have together described the eighteenth- and early-nineteenth-century European cabinet tradition: the French royal source through its rocaille and neoclassical halves, the Continental bourgeois reaction that displaced both, the Anglophone cross-Channel translation in carved mahogany, and the Northern translation across the Baltic into painted Swedish pine. What that account has so far not opened is the Italian tradition at all, and the cleanest place to begin is a century earlier than any of the prior five, with the body of work that the seventeenth-century Roman and Bolognese workshops produced for the papal-court patron class under Bernini-circle design influence:<em>Italian Baroque</em>.</p><p>The translation principle the prior posts have made familiar — French source, national-register material substitution — does not quite apply to the Italian Baroque, because the Italian Baroque is the source rather than a translation of one. The mid-seventeenth-century Italian register was already at Versailles when the French royal cabinet tradition began to articulate itself in the 1660s under Louis XIV&rsquo;s<em>Manufacture Royale des Gobelins</em>; Bernini himself was invited to Paris in 1665. Where Louis XV is rocaille and Louis XVI is neoclassical, the Italian Baroque is what stands behind both at a generation&rsquo;s distance: dark walnut case furniture, heavy carved-and-gilded ornament, deep-relief figurative carving across the panel surfaces, and — on the apex pieces — pietra-dura tops in inlaid coloured marbles. The patron is not the king but the cardinal or the prince, and the documentary anchor is not a pattern book but the architectural-and-decorative work of Bernini&rsquo;s circle in Rome through the mid-century.</p><p>This is the sixth post in<em>Reading the Period Cabinet</em>. It opens the Italian tradition, which the prior posts have not touched, and provides the<em>dark-gilt break</em> the wood-tone variety table calls for after the Gustavian gris-blanc.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Italian Baroque piece, for the purposes of beginning to read the style, is the<em>stipo</em> — the architectural cabinet on stand, descended in form from the smaller Renaissance writing-cabinet but elaborated in the seventeenth century into a room-scale architectural object with deep-relief carved figurative ornament, carved-and-gilded structural members, and (on the better pieces) a pietra-dura top. The stipo is what the cardinal-or-prince patron commissioned for the principal salon of the Roman palazzo, and the form in which the Italian Baroque principles are most fully concentrated.</p><p>A canonical Italian Baroque stipo, then. It stands on a<em>carved giltwood stand</em> — either a pair of carved Atlas-figures or putti supporting the case directly, or a more conventional console-style base with paw feet and heavy scrolled brackets, the entire stand gilded over a gessoed ground in the Roman papal-court register. Above the stand rises the case proper, in<em>dark walnut</em> — Italian walnut, dense and close-grained, dark-stained or naturally aged to the deep brown that the surviving period pieces all share. The case is<em>architectural</em> in its proportions: it reads as a small palace facade, with central door, flanking compartments, sometimes a central niche, and a heavy entablature above. Solomonic columns — the twisting spiral columns made famous by Bernini&rsquo;s<em>baldacchino</em> at St Peter&rsquo;s, completed in 1633 — frame the central door on the apex pieces, executed in carved walnut and gilded at the bases and capitals.</p><figure><img src="/images/posts/italian-baroque/detail-carving.png" alt="A close detail of Italian Baroque deep-relief walnut carving — mythological figures, swags, and Solomonic-column elements in the dark Italian walnut of the period"><figcaption><p>A close detail of Italian Baroque carved-walnut ornament — the deep-relief figurative carving in the dark Italian walnut of the period, with mythological figures, swags of fruit and laurel, and the Solomonic-column elements that Bernini&rsquo;s<em>baldacchino</em> (1623–1634) had made the canonical vertical-ornament motif of the Roman papal-court register. The carving is in the wood of the case itself, not applied as a separate mount; this is the principle that distinguishes the Italian Baroque from the French Louis XIV ormolu-and-Boulle equivalent and from the Spanish Baroque iron-and-leather sibling.</p></figcaption></figure><p>The ornamental vocabulary across the case is the broader Italian Baroque vocabulary the Bernini circle had already established in stone and stucco.<em>Deep-relief figurative carving</em> — mythological scenes, allegorical figures, putti in clustered groups, swags of fruit and flowers, mascarons, cartouches with cardinal arms — covers the door panel, the case sides, and the upper entablature, cut deep enough into the walnut of the case itself that the figures stand nearly in the round, with the undercutting that produces the strong shadow-and-highlight contrast the Baroque aesthetic depended on. Above the entablature, a<em>broken-pediment cresting</em> of carved giltwood, often with a cartouche bearing the patron&rsquo;s arms or a sculptural figure (a putto, an allegorical figure, a Marian image on the explicitly devotional pieces). The<em>carved-and-gilded structural register</em>, second, is what most distinguishes the Italian Baroque visually at three paces: the columns, the cornices, the entablature, and the cresting are gilded over a gesso-and-bole ground in the Roman water-gilding tradition the architectural workshops had perfected on church interiors, while the carved walnut of the figurative panels is left exposed. Where the French Louis XIV register would apply gilt-bronze ormolu as a separate metal element bolted to the case, the Italian Baroque gilds the carved wood itself, producing a softer and more sculptural gilt-relief than the crisp ormolu the French would develop a generation later.</p><figure><img src="/images/posts/italian-baroque/detail-gilt.png" alt="A close detail of an Italian Baroque carved-and-gilded structural element — gilded carved walnut over a gessoed ground, the Roman papal-court gilding register"><figcaption><p>A close detail of an Italian Baroque carved-and-gilded element — gilded carved walnut over a gesso-and-bole ground in the Roman papal-court gilding register. The gilt is on the carved wood itself, not on a separately-cast metal mount; the effect is softer and more sculptural than the cast gilt-bronze ormolu the French royal workshops would develop a generation later, and is part of how the Italian Baroque reads at three paces against the contemporary French equivalent.</p></figcaption></figure><p>The pietra-dura top, third, is the apex-piece signature. On the better stipi and on the heavy console tables the principal Roman palazzi commissioned for their galleries, the top is a<em>pietra-dura panel</em> — inlaid coloured marbles and hardstones in geometric, floral, or figurative arrangement, set into a marble or slate ground. The pietra-dura industry is concentrated, with great specificity, in<em>Florence under Medici patronage</em>: Ferdinando I de&rsquo; Medici founded the<em>Opificio delle Pietre Dure</em> in 1588 as a court workshop, and through the seventeenth century the Opificio produced the substantial pietra-dura tops that the Roman and Bolognese cabinet workshops then mounted onto their stipi and consoles. The Florentine pietra-dura is therefore not a generic &ldquo;Italian Baroque&rdquo; technique distributed across the whole peninsula but a Florentine workshop specialty, and the pieces that carry it bear in their tops the Medici-court industrial relationship to the broader Italian Baroque trade.</p><figure><img src="/images/posts/italian-baroque/detail-pietra-dura.png" alt="A close detail of a Florentine pietra-dura cabinet top — inlaid coloured marbles and hardstones in geometric or floral arrangement, the Opificio delle Pietre Dure workshop signature"><figcaption><p>A close detail of a Florentine pietra-dura top — inlaid coloured marbles and hardstones (lapis lazuli, jasper, agate, porphyry) in a geometric and floral arrangement against a black marble ground, executed at the<em>Opificio delle Pietre Dure</em> in Florence and mounted on the cabinet stand by a Roman or Bolognese workshop. Pietra-dura is, with some specificity, a Florentine workshop tradition under Medici patronage rather than a generic Italian Baroque technique; the apex pieces in this medium are Opificio products of the seventeenth century.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>The wood, first.<em>Italian walnut</em> — the principal cabinet wood of the Italian peninsula across the sixteenth and seventeenth centuries — is what the surviving period stipi and consoles are made of, with a small minority of pieces in cypress, oak, or fruitwood for provincial registers. The walnut is dense, close-grained, and naturally dark; the seventeenth-century pieces are darker still after three and a half centuries of natural oxidation and accumulated wax-and-oil patina. The wood is<em>solid</em> on the structural members and joined by the period hand at hand-cut mortise-and-tenon and dowel joints; the deep-relief carving cuts into the solid walnut itself rather than into an applied carved appliqué. This is the structural enabling condition for the deep-relief figurative carving the style depends on: Italian walnut takes deep carving without splintering, where the softer woods of the Northern traditions could not.</p><p>The carving and the gilding, second, are most of what one is reading for at close range. The carved relief is<em>deep</em> — figures stand nearly in the round, with substantial undercutting — and the figurative-Baroque vocabulary (mythological figures, putti, allegorical females, swags of fruit and laurel, mascarons, and cardinal-armorial cartouches) is what most distinguishes the Italian Baroque from the contemporary French, Spanish, and Northern European Baroque registers. The gilt is<em>water gilt over a gesso-and-bole ground</em> in the Roman ecclesiastical-workshop register, applied to selected structural members rather than to whole surfaces, and should show period wear in a characteristic pattern: rubbed at the high-touch areas, surviving in the hollows, and showing through to a<em>red bole ground</em> at the worn spots rather than to a yellow or white modern gilding-base or to bare wood. The bole-coloured underlayer is itself an authentication indicator the late-nineteenth-century revival workshops did not consistently reproduce.</p><p>The pietra-dura, third, where present. The hardstones should be cut and fitted by the period hand — Opificio pieces show the characteristic fine-line joints between the inlaid stones (executed with the bow-saw and abrasive paste over weeks or months per panel), the slight irregularities of hand-fitting at the corners, and the depth of the inlay flush with the marble ground. The hardstone vocabulary of the seventeenth-century Opificio includes<em>lapis lazuli, jasper, agate, porphyry, chalcedony, and various marbles</em> against a black or coloured marble ground; the colour vocabulary is recognisable to anyone who has stood in the Cappella dei Principi in Florence, where the same workshop&rsquo;s apex output is mounted on the walls.</p><h2 id="the-period">The Period</h2><p>The Italian Baroque period proper runs from about 1600 to about 1700, with apex production concentrated in the middle decades — roughly 1620 through 1680 — under the patronage of the great Roman papal-affiliated families. The dating is therefore both earlier and broader than the eighteenth-century styles the prior posts have covered, and the documentary anchor is not a pattern book or a regnal date but the architectural-and-decorative work the Bernini circle was producing in parallel for the same patrons.<em>Gian Lorenzo Bernini</em> (1598–1680) — sculptor, architect, designer of the<em>baldacchino</em> at St Peter&rsquo;s (1623–1634), of the colonnade in St Peter&rsquo;s Square (1656–1667), of the Cornaro Chapel — established the design vocabulary in stone, stucco, and gilded wood that the contemporary cabinet workshops then adapted to the stipo, the console, and the cassone;<em>Francesco Borromini</em> (1599–1667) is the second architectural figure, more idiosyncratic, whose ornamental vocabulary the cabinet trade absorbed selectively. The patron class is the cardinal-and-prince Roman families —<em>Borghese</em> (under Paul V),<em>Barberini</em> (under Urban VIII, the central Bernini patron, 1623–1644),<em>Pamphilj</em> (under Innocent X, 1644–1655), and<em>Chigi</em> (under Alexander VII, 1655–1667) — and the surviving apex pieces are preserved in the principal Roman palazzi (Palazzo Barberini, Palazzo Doria Pamphilj, Galleria Borghese) and in the museum collections that have absorbed dispersed family holdings.</p><p>The load-bearing distinction every Italian Baroque collector must master, however, is not the chronology or the patron families but<em>the named-master-versus-anonymous-workshop attribution problem</em> that runs through the period and that has no good parallel in the later styles this arc has covered. The Italian Baroque cabinet trade did not produce a pattern book in the<em>Director</em> sense — there is no Italian Chippendale, no published codification of the workshop register under a single master&rsquo;s name. Italian Baroque furniture is, with very few exceptions,<em>unsigned</em>, and the documentary attribution is therefore principally a workshop attribution rather than a master attribution.<em>Andrea Brustolon</em> (1662–1732), the Venetian late-Baroque virtuoso sculptor-carver, is the partial exception that proves the rule: his signed and documented work for the Venier and Correr families in Venice constitutes the only substantial body of named-master Italian Baroque cabinet-and-carved-furniture, and the trade attribution &ldquo;Brustolon&rdquo; therefore has the kind of standing that &ldquo;Chippendale&rdquo; has in the English register — with the difference that Brustolon operated at the very end of the Baroque period, in Venice rather than Rome or Bologna, and almost entirely in the carved-figurative-stand-and-frame register rather than in the broader case-furniture trade.<em>Giovanni Giardini</em> (1646–1721), to name a second documented figure, was a Roman silversmith-and-metalworker whose name attaches to certain documented commissions but who operated more at the workshop-administrative level than as a recognisable cabinet-making hand. For the bulk of the surviving Italian Baroque corpus the practical-attention work for the collector is to read at the workshop level —<em>Roman papal-court workshops</em> (anonymous, producing the apex stipi and consoles under direct cardinal-or-papal commission, with the carving hand recognisable to the trade but not traceable to a named master),<em>Bolognese cabinet-making workshops</em> (one of the major production centres alongside Rome, Florence, Genoa, and Venice, with a documented industrial cabinet-making concentration in Bologna through the seventeenth century and a workshop hand distinguishable from the Roman by carving conventions and proportional treatment),<em>Florentine workshops under Medici patronage</em> (specifically the<em>Opificio delle Pietre Dure</em> for pietra-dura tops, and the broader Medici-court furniture workshops for the cassoni and case-furniture that mounted them),<em>Genoese workshops</em> (carrying their own distinct regional register, of which the<em>stipo a bambocci</em> — the cabinet with deeply carved figural caryatids of grotesque children or putti supporting the case — is the most recognisable Genoese seventeenth-century form), and<em>Venetian workshops</em> (operating somewhat apart from the central-Italian axis, working in a slightly lighter register and continuing latest into the eighteenth century where Brustolon&rsquo;s work belongs). The trade has long argued about specific attributions — what&rsquo;s Brustolon and what&rsquo;s a workshop follower, what&rsquo;s seventeenth-century Bolognese and what&rsquo;s nineteenth-century Italian revival in the Bolognese register — and the practical knowledge for the buyer is to read at the workshop level confidently rather than chase a named master that the period documentation almost never supports.</p><figure><img src="/images/posts/italian-baroque/antecedent.png" alt="A 16th-c Italian Renaissance cassone — the predecessor with rectangular relief-carved panels in walnut, often gessoed-and-painted with mythological scenes; the antecedent the Italian Baroque elaborated into the room-scale stipo"><figcaption><p>A 16th-c Italian Renaissance cassone — the marriage-chest the principal Italian domestic form of the fifteenth and sixteenth centuries, with rectangular relief-carved panels in walnut, often gessoed-and-painted with mythological scenes, and lower-relief carving than the Baroque period would elaborate. The Italian Baroque inherited the cassone form and the figurative-carving tradition, then elaborated both into the room-scale stipo with deep-relief carving, carved-and-gilded structural members, and pietra-dura tops. The cassone tradition itself continued through the Baroque period at a smaller and more conservative register, but the principal Baroque innovation is the architectural stipo and the heavy console that succeeded the cassone as the principal salon object.</p></figcaption></figure><figure><img src="/images/posts/italian-baroque/pattern-book-page.png" alt="A page from a Bolognese cabinet-maker's reference plate — perspective drawings of Italian Baroque stipo, sgabello, and console table in the seventeenth-century workshop register"><figcaption><p>A page from a Bolognese cabinet-maker&rsquo;s reference plate — perspective drawings of the principal Italian Baroque forms: the architectural<em>stipo</em> cabinet on carved-giltwood stand, the<em>sgabello</em> trestle side chair (a Renaissance form continued into the Baroque) with carved-and-painted back-panel, and the heavy<em>console</em> with Atlas-supported top. The Italian Baroque trade did not produce a published pattern book in the English<em>Director</em> sense; reference drawings of this kind circulated within and between workshops in manuscript and engraved form, and survive in scattered collections rather than as a single codifying document. The Bolognese cabinet-making centre was one of the major production nodes for the broader Italian Baroque trade — alongside Rome, Florence, Genoa, and Venice — and the proportional and ornamental conventions visible in such drawings are the Bolognese workshop register specifically.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four styles stand near enough to Italian Baroque that the beginner confuses them with it, and distinguishing them is most of the work of reading seventeenth-century Continental furniture in its national-and-regional registers.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/italian-baroque/sibling-italian-renaissance.png" alt="A 16th-c Italian Renaissance cassone — the antecedent style with rectangular relief-carved panels in walnut, gessoed-and-painted mythological scenes, lower-relief carving and simpler proportions than the Baroque" loading="lazy"/><figcaption>Italian Renaissance<em>— the 16th-c antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-baroque/sibling-italian-rococo.png" alt="An Italian Rococo Venetian piece — the 18th-c descendant with painted lacquer (red, green, blue) and carved giltwood ornament rather than dark carved walnut" loading="lazy"/><figcaption>Italian Rococo<em>— the 18th-c Venetian descendant</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-baroque/sibling-spanish-baroque.png" alt="A Spanish Baroque cabinet — Iberian sibling with iron studs, leather, and bone inlay; dark walnut but with iron-and-leather ornamental vocabulary rather than carved gilt and pietra-dura" loading="lazy"/><figcaption>Spanish Baroque<em>— the Iberian sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/italian-baroque/sibling-french-louis-xiv.png" alt="A French Louis XIV cabinet — heavier royal-court sibling with Boulle tortoiseshell-and-brass marquetry and cast gilt-bronze ormolu, rather than carved walnut with gilded carved-wood ornament" loading="lazy"/><figcaption>French Louis XIV<em>— the heavier royal-court sibling</em></figcaption></figure></div><figcaption>Four styles most often confused with Italian Baroque, drawn for comparison.</figcaption></figure><p>An<em>Italian Renaissance</em> is the sixteenth-century antecedent the Baroque period elaborated. The form vocabulary is in part continuous — the cassone above all, but also the simpler cabinet-on-stand — but the carving is lower in relief (gessoed-and-painted figurative panels rather than the deep undercut walnut of the Baroque), the proportions are simpler, and gilding is applied only to selected accents rather than to whole structural members. The rule of thumb: lower-relief carving with gessoed-and-painted figurative panels is Italian Renaissance; deep-relief figurative walnut carving with carved-and-gilded structural members and room-scale architectural proportions is Italian Baroque.</p><p>An<em>Italian Rococo (Venetian)</em> is the eighteenth-century descendant — the lighter Venetian succession that flourished from about 1730 through about 1790, with<em>painted lacquer</em> (red, green, blue, ivory, pale yellow) rather than dark carved walnut,<em>carved giltwood</em> in the rococo curvilinear register rather than the Baroque rectilinear-architectural register, and a domestic-decorative orientation. The Venetian Rococo will earn its own post later in this arc. The rule of thumb: painted-lacquer cases with carved-giltwood rococo ornament are Italian Rococo; dark walnut with deep-relief carved figurative ornament and carved-and-gilded structural members are Italian Baroque.</p><p>A<em>Spanish Baroque</em> is the Iberian sibling — produced in the same seventeenth-century decades for the parallel cardinal-and-monarch patron class in Madrid, Seville, and Toledo, but executing the Baroque impulse in an entirely different ornamental vocabulary. Spanish Baroque is also in dark walnut, but the surface vocabulary is<em>iron studs and bands, tooled leather panels, and bone-or-ivory inlay</em> — the Mudejar Islamic inheritance still legible in the seventeenth-century work — rather than the carved gilt and pietra-dura of the Italian register. The<em>vargueño</em> (the Spanish drop-front writing-cabinet, form-parallel to the Italian stipo) is the canonical specimen. The rule of thumb: dark walnut with iron studs, tooled leather, and bone inlay is Spanish Baroque; dark walnut with carved-and-gilded structural members and Florentine pietra-dura is Italian Baroque.</p><p>A<em>French Louis XIV</em> is the heavier royal-court sibling — the Continental royal counterpart that developed in parallel from the 1660s under the<em>Manufacture Royale des Gobelins</em> and drew on the same Italian Baroque sources. The French royal register substitutes<em>Boulle marquetry</em> — André-Charles Boulle&rsquo;s signature tortoiseshell-and-brass inlay — and<em>cast gilt-bronze ormolu mounts</em> in place of the Italian carved-and-gilded-wood structural ornament and pietra-dura tops, and the proportions become heavier still in the French royal direction. The rule of thumb: Boulle tortoiseshell-and-brass marquetry with cast gilt-bronze ormolu is French Louis XIV; carved walnut with carved-and-gilded structural members and Florentine pietra-dura is Italian Baroque.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>workshop attribution</em>, and the workshop settles the broad reading more reliably than any named-master claim.<em>Roman papal-court workshop</em> output is the apex of the type — produced for the cardinal-and-papal patron class, with the strongest deep-relief carving, the most ambitious architectural proportions, and the closest design relationship to the Bernini-circle source.<em>Bolognese workshop</em> output is one of the major production centres alongside Rome, Florence, Genoa, and Venice, with a recognisable carving hand and proportional treatment the trade distinguishes from the Roman; a substantial share of surviving non-apex Italian Baroque furniture carries the Bolognese register.<em>Genoese workshop</em> output carries its own distinct regional vocabulary — the<em>stipo a bambocci</em>, with deeply carved figural caryatids of grotesque children or putti as the supporting members, is the most recognisable Genoese seventeenth-century form and a register the collector reads against the Roman and Bolognese.<em>Florentine workshop</em> output is principally the pietra-dura tops from the Opificio and the case-furniture that mounted them; the medium itself is the workshop signature.<em>Venetian workshop</em> output is the late-Baroque continuation into the eighteenth century, with Brustolon as the only substantial named master in the corpus.</p><p>One looks next at the<em>wood and the carving</em>. The wood should be<em>dark Italian walnut</em> (with cypress, oak, or fruitwood permitted at provincial registers); the carving should be<em>deep-relief and figurative</em> in the wood itself; the figurative vocabulary should be the Baroque vocabulary (mythological figures, putti, swags, mascarons, cartouches) rather than the Renaissance vocabulary (gessoed-and-painted panels at lower relief) or the Rococo vocabulary (asymmetric scrolled curves). A piece in apparent Baroque register but with shallow relief at gessoed-panel depth is probably Italian Renaissance or a later revival; a piece with the figurative-Baroque vocabulary but in painted lacquer rather than walnut is Italian Rococo.</p><p>One looks then at the<em>carved-and-gilded structural register</em>. The gilt should be on the carved wood itself — columns, cornices, entablature, cresting, stand — not as a separately-cast metal mount, and over a<em>red bole ground</em> in the Roman water-gilding tradition rather than a yellow or white modern ground. The carved-wood-and-gilt structural framing set against the dark-walnut figurative panels is the canonical Italian Baroque surface effect, and the contrast reads at three paces against the French Louis XIV ormolu-and-Boulle equivalent (which substitutes cast metal for carved wood) and against the Spanish Baroque iron-and-leather equivalent (which substitutes metal-and-hide for gilded wood).</p><p>And one looks, finally, at the<em>pietra-dura top</em> where present. The hardstones should be cut and fitted by the period hand, with the characteristic fine-line joints of Opificio bow-saw work; the colour vocabulary should be the seventeenth-century Opificio vocabulary (lapis, jasper, agate, porphyry, chalcedony, the Florentine marbles) against a black or coloured marble ground. A piece with pietra-dura is, by that fact, anchored to the Florentine workshop industry under Medici patronage, and the documentary attribution of the top is often clearer than the attribution of the cabinet beneath. The mounting of a Florentine pietra-dura top onto a Roman or Bolognese cabinet stand is one of the most characteristic industrial relationships in the seventeenth-century Italian Baroque trade.</p><p>The next post in the furniture arc will be either<em>Italian Rococo (Venetian)</em> — to extend the Italian tradition into the painted-lacquer eighteenth-century descendant, with the colour-painted variety break that the wood-tone variety table calls for next — or<em>Spanish Baroque</em>, to open the Iberian sibling tradition with the iron-and-leather register that the seventeenth-century Continental survey requires. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Bidjar</title><link>https://mtclinton.com/posts/bidjar/</link><pubDate>Tue, 19 May 2026 17:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/bidjar/</guid><category>antiques</category><description>Sixth per-subject post in Reading the Antique Rug — the Kurdish northwestern Persian district that produces the 'iron rug of Persia,' the densest and most compressed weave of any Persian tradition, with the dark wine-red and dark navy palette and the wet-loom-compressed handle test as the load-bearing collector distinction.</description><content:encoded>&lt;![CDATA[<p>The five prior posts in this arc —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>,<a href="/posts/caucasian-kazak/">Caucasian Kazak</a>,<a href="/posts/bakshaish/">Bakshaish</a>, and most recently<a href="/posts/kashan/">Kashan</a> — laid out the antique-rug attribution along two regional axes (the northwestern Persian district at Heriz, Tabriz, and Bakshaish; the central Persian court at Kashan) and a third structural one (the Caucasian wool-warp register at Kazak). What none of those posts had reason to treat in detail was a third Persian tradition altogether — neither the northwestern village register nor the central Persian court, but the<em>Kurdish</em> district between them, in the mountainous country between Hamadan and Sanandaj, that produces a Persian rug type unlike any other in the body of antique production. Bidjar is the post that opens it.</p><p>Bidjar&rsquo;s principal signature is neither composition nor palette but<em>structural density</em>. Where Bakshaish was a moderately-knotted northwestern village production with the soft cream palette of long oxidation, and where Kashan was the fine central Persian court workshop on saturated wine-red at two hundred KPSI and finer, the Bidjar is the<em>densest, heaviest, most compressed</em> Persian rug of the entire antique period. A Bidjar at six feet by nine feels meaningfully heavier than a Kashan at the same size; it lies flat on the floor with a rigidity that no other Persian rug shares; and one can, with a little practice, identify a genuine antique Bidjar by handle alone, before one has read its medallion or counted its knots. The &ldquo;iron rug of Persia&rdquo; is the dealer&rsquo;s name, and the description is structural, not metaphorical. The load-bearing collector-distinction for the type, accordingly, is the<em>handle test</em> — the first move an experienced dealer makes with a candidate Bidjar is to pick it up, or fold a corner back, and read its weight, its rigidity, and its peculiar drape. Knot density and palette and medallion vocabulary play their proper roles, but a real Bidjar feels like nothing else in the Persian tradition, and the post will return to why at the appropriate sections below.</p><h2 id="the-specimen">The Specimen</h2><p>A Bidjar that one will encounter is, in its commonest form, a substantial rug in the<em>six-by-nine to nine-by-twelve</em> range, with smaller pieces (the four-by-six dozar, the runners at three feet by ten or twelve) common because the district produced full ranges for both the Persian domestic market and the late-nineteenth-century export trade. The proportions are calibrated by the workshop pieces and felt by the village ones, and one will sometimes encounter a Bidjar with a slight irregularity in its trueness — which is itself a village-register diagnostic and not a defect.</p><p>The composition is, on the canonical pieces, one of two related vocabularies. The first is the<em>herati allover</em> — the small repeating motif of a rosette enclosed by four curling leaves with a small diamond at its centre, repeated across the entire field — which the dealer trade most often labels &ldquo;classic Bidjar.&rdquo; The second is the<em>central medallion</em> — a single floral-vocabulary medallion set on a saturated dark-wine or dark-navy field, with quarter-medallion spandrels at the four corners and a main floral border of stylised palmettes-and-rosettes. The medallion is<em>not</em> the stepped polygonal vocabulary of the Sahand village register; it is a more elaborated floral medallion in the Kurdish-village vocabulary, with the regularity of the workshop register and the heavier-line drawing of the village. A third vocabulary, less common but worth naming, is the<em>small repeating boteh</em> — the curled-leaf motif at small scale, repeated in vertical rows — produced principally on the smaller domestic pieces.</p><figure><img src="/images/posts/bidjar/detail-medallion.png" alt="A close detail of a Bidjar central medallion or herati allover — fine floral and herati vocabulary on dark wine-red ground"><figcaption><p>A close detail of the Bidjar field vocabulary — the herati allover (rosette-and-leaves repeat at moderate scale) on the dark wine-red ground that is one of the two Bidjar palette signatures. The heavy-line cadence of the motif and the saturated ground separate the Bidjar from the lighter Kashan or the brick-red Heriz; the structural density at which the drawing is woven is what the post principally treats.</p></figcaption></figure><p>The palette is the Bidjar&rsquo;s principal break with both prior arcs. The field is<em>dark wine-red</em> — a deep madder closer to oxblood than to the brighter brick of the Heriz or the saturated wine of the Kashan — or, alternately,<em>dark navy</em>, an indigo so deep that on certain pieces the difference between field and medallion-outline reads only at close inspection. The dark palette is the Kurdish signature: the Bidjar wine shades toward purple or oxblood, and rarely reads as the jewel-tone wine of the central Persian court. The medallion is typically ivory or contrasting indigo on the wine-red pieces, deep wine-red on the navy pieces. Yellows are sparing and ochre rather than bright; whites are an aged ivory rather than stark; the whole palette is darker, heavier, and more saturated than either prior arc.</p><p>Three sub-types are worth naming briefly. The<em>village production proper</em> — the rugs of the village just south of Bijar town, including the Tekye-Daragah cluster — is the densest and most compressed, the canonical &ldquo;iron rug,&rdquo; typically on a wool warp and the strongest expression of the handle signature; this is the apex Bidjar in the strict collector sense. The<em>Garrus design</em> — cobalt indigo ground, split-arabesque palmettes, cloud-band borders, woven in the Bidjar workshops themselves — is the most-collected sub-vocabulary within the Bidjar register, and is the design name a dealer will sometimes use in place of &ldquo;Bidjar&rdquo; for the higher-grade pieces; &ldquo;Garrus&rdquo; is properly the historic district name for the Bidjar area itself, not a separate village cluster, and the design vocabulary that bears the name is read as Bidjar work at the high register. The<em>late-nineteenth-and-early-twentieth-century commercial workshops</em> in Bijar town produced workshop-grade pieces on cotton warps with reduced knot density relative to the village apex but with the wet-loom compression preserved; these are the most-encountered surviving inventory.</p><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence that places a Bidjar firmly in the Kurdish-Persian tradition, and it is also where the post must lay out the<em>wet-loom technique</em> that the entire Bidjar thesis rests on. The warp question is principally chronological. Wool warps prevailed through the nineteenth century; cotton warps replace them on most production after about 1900. The wool-warp Bidjars of the 1880s and 1890s are accordingly the apex of the antique register — the village apex Bidjar runs on hand-spun wool drawn from the same Kurdish flocks that produced the pile, and the wool is part of what enables the extreme compression the wet-loom technique applies, because wool warp swells under moisture in a way cotton does not. The later commercial workshop pieces on cotton warps preserve the wet-loom compression but lose the wool-warp swell, and the very finest apex pieces are accordingly the late-nineteenth-century wool-warp village production.</p><p>The wet-loom technique is the structural signature. In standard Persian practice, the weaver knots a row, beats it down with a heavy metal comb, passes a weft shoot across, beats the weft, and proceeds to the next knot row. The Bidjar weaver does the same — but at the beating step, dampens the wool weft with water before packing it, then beats it down with a particularly heavy comb (sometimes a hooked iron implement that draws the weft tight across the warp rather than merely beating from above). The dampened weft swells under the moisture, fills the space between the warps more completely, and is beaten while still wet into the foundation; when it dries it has compressed into a denser packing than dry weft would achieve. The next row of knots is set against this compressed foundation, and the next, and the rug is built up under continuous compression. The result is a foundation<em>meaningfully denser per unit volume</em> than any other Persian rug type achieves, and the compression is what produces the &ldquo;iron rug&rdquo; handle.</p><figure><img src="/images/posts/bidjar/detail-border.png" alt="A close detail of a Bidjar main border — fine stylised palmette-and-rosette repeat at high register"><figcaption><p>A close detail of a Bidjar main border — stylised palmettes and rosettes in the Kurdish floral vocabulary on the indigo border-ground. The heavy-line cadence and saturated palette are consistent with the field; the line-weight is heavier than the Kashan&rsquo;s court border and the drawing closer to the village than to the workshop.</p></figcaption></figure><p>The knot is the<em>symmetric Turkish knot</em>, which is itself the most easily-confused point about the Bidjar tradition. The Bidjar weaving population is Kurdish-speaking, and Senneh — the nearby Kurdish city workshop — uses the<em>asymmetric Persian knot</em> (often called the Senneh knot for that reason). One might reasonably expect Bidjar to use the Senneh knot as well; it does not. The Kurdish weavers at Bidjar use the symmetric Turkish knot throughout — the same knot as the Turkic-Azeri weavers of the Sahand district at Heriz and Bakshaish — and this catches beginners working from the simplistic &ldquo;Persian people use the Persian knot, Turkish people use the Turkish knot&rdquo; mental model. The point is worth flagging: it appears in the literature as a misattribution sufficiently often to mislead.</p><figure><img src="/images/posts/bidjar/detail-foundation.png" alt="A close detail of a Bidjar knot-back — extreme density, wool warp on the village apex pieces, the compressed wet-loom foundation"><figcaption><p>A close detail of the back of a Bidjar rug — the knot density (roughly eighty to two hundred knots per square inch on the canonical pieces, with the very finest apex Bidjars occasionally reaching higher still), the wool warp on the nineteenth-century pieces (cotton on most production after about 1900), and above all the<em>compressed</em> foundation that the wet-loom technique produces. The warps lie close, the weft is packed dense, and the rug resists folding in a way the Kashan or the Bakshaish back does not. This is the structural diagnostic on which the handle test rests.</p></figcaption></figure><p>Knot density runs from roughly<em>eighty knots per square inch on the rougher village production to two hundred on the apex pieces</em>, with the very finest apex Bidjars occasionally reaching higher still. These numbers, however, understate the structural difference, because density-per-unit-area at the front of the rug is not the principal measurement — what the wet-loom technique produces is<em>density-per-unit-volume of the entire foundation</em>, and it has no clean expression as a single number. The Bidjar at one hundred and forty KPSI at the front feels markedly heavier and stiffer than the Kashan at two hundred and twenty KPSI at the front, because the Kashan&rsquo;s foundation is comparatively loose between the warps even at the higher front-density. Knot density is the proxy; handle is the measurement.</p><p>The wool of the pile comes from the<em>Zagros mountain sheep</em> of the Kurdish district — the same broad flocks that supply Senneh and Hamadan, but at the Bidjar register hand-sorted to a particular grade and high in lanolin. Kurdish mountain wool takes the dark madder dye deeply and ages with the slow tonal shift the antique market reads as authenticity. Dyes on the antique pieces are entirely vegetable: madder for the wine-red, indigo for the navy, isparek and pomegranate-rind for the sparing yellows, walnut hull for the browns; synthetic aniline dyes are essentially absent before 1900 and only intermittently present on the early-twentieth-century commercial workshops.</p><h2 id="the-period">The Period</h2><p>The Kurdish district occupies the mountainous country in the western part of northwestern Persia, between Hamadan to the south, Sanandaj (the city the dealer trade calls Senneh) roughly due west, and the Tabriz district to the north. Bidjar town — properly Bijar — sits at the eastern edge of the Kurdish zone, with the canonical Bidjar village just to the south, and the historic district name<em>Garrus</em> covers the Bidjar area itself rather than any separate neighbouring cluster. Further to the northwest, in West Azerbaijan Province at a distance of some three hundred kilometres, lies Mahabad — the city the antique dealer trade knew as<em>Sauj Bulagh</em> — which is its own well-known Kurdish weaving centre and not a Bidjar satellite, and a Sauj Bulagh rug should not be conflated with the Bidjar register. The geography is isolated by Persian standards, the climate cold and the winters long, and the Kurdish weaving tradition older than the antique-production period this arc treats — the older Kurdish village register, with its denser-than-typical foundation and dark palette, is documented from at least the early eighteenth century.</p><p>Antique-period Bidjar production runs from about 1820 to about 1930. The canonical village apex concentrates in the<em>1860–1900</em> range — wool warp, the highest expression of the wet-loom compression, the deepest of the dark Kurdish palette; the commercial workshop register concentrates in the<em>1880–1920</em> range, overlapping the village apex but extending beyond it. The export trade began in earnest in the 1870s and 1880s, as European and American dealers travelling the Persian rug country recognised the structural distinctiveness of the type; the commercial workshops in Bijar town were established largely in response. The Soviet-era decline of the broader region after the 1920s, the increasing scarcity of high-grade Kurdish wool, and the loss of the wet-loom technique through the generational disruption of the mid-twentieth century combined to end the canonical Bidjar production by roughly 1930; post-1930 work exists but is structurally distinct and does not carry the handle signature the antique pieces are prized for.</p><figure><img src="/images/posts/bidjar/antecedent.png" alt="An older Kurdish village rug, pre-commercial — the 18th-c antecedent tradition out of which the 19th-c Bidjar density emerged"><figcaption><p>An older Kurdish village rug of the late eighteenth or early nineteenth century — the pre-commercial Kurdish weaving tradition out of which the nineteenth-century Bidjar emerged. The drawing is less elaborated than the canonical Bidjar would reach by 1880; the dark palette is already present; and the wet-loom compression, in some form, is documented from at least this period. The nineteenth-century Bidjar pushed the density toward its mature signature.</p></figcaption></figure><figure><img src="/images/posts/bidjar/portfolio-page.png" alt="A Victorian connoisseur's portfolio page on the Kurdish weaving centres — map locating Bidjar, Senneh, Sauj Bulagh with archetype rug drawings"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Kurdish weaving centres — district map locating Bijar town and the Bidjar village to its south, Sanandaj (Senneh) roughly due west, Hamadan to the south, and Sauj Bulagh (Mahabad) as a separate Kurdish centre to the northwest in West Azerbaijan, some three hundred kilometres distant. Three archetype drawings at the bottom show the principal Kurdish sub-types: the Bidjar (herati allover or central medallion on dark wine-red ground, with the Garrus design at the high register), the Senneh (fine asymmetric-knot city workshop on lighter ground), and the Sauj Bulagh / Mahabad (its own Kurdish weaving tradition to the northwest, not a Bidjar satellite).</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four types stand near enough to Bidjar that the beginner confuses them with it, and distinguishing them is most of the work of reading the Kurdish district.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/bidjar/sibling-senneh.png" alt="A Senneh rug — fine Kurdish city workshop production from Sanandaj, with the asymmetric Senneh knot, fine drawing on lighter ground, and the markedly lighter handle that distinguishes it from Bidjar" loading="lazy"/><figcaption>Senneh<em>— the fine Kurdish city workshop</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bidjar/sibling-hamadan.png" alt="A Hamadan rug — the village production from the city to the south of Bidjar, single-weft Hamadan construction, rust / camel earth-tone palette, looser knot and lighter handle than Bidjar" loading="lazy"/><figcaption>Hamadan<em>— the southern village neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bidjar/sibling-heriz.png" alt="A Heriz commercial rug — the northwestern Persian district to the north of the Kurdish zone, larger and stepped medallion, looser knot density, brick-red ground, and lighter handle than Bidjar" loading="lazy"/><figcaption>Heriz<em>— the northern district with larger medallion</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bidjar/sibling-tabriz.png" alt="A Tabriz city-workshop rug — the regional city workshop, designed by named master-designers rather than woven on the village or commercial-workshop loom, finer knot but markedly lighter handle than Bidjar" loading="lazy"/><figcaption>Tabriz<em>— the city workshop counterpoint</em></figcaption></figure></div><figcaption>Four types most often confused with Bidjar, drawn for comparison.</figcaption></figure><p>A<em>Senneh</em> is the fine Kurdish city workshop rug from Sanandaj, roughly due west of Bidjar — the same Kurdish district, the same weaving population, but a wholly different structural tradition. Senneh uses the<em>asymmetric Persian knot</em> (the<em>Senneh knot</em> proper, named for the city), draws at the very fine end of the Persian range (often three hundred KPSI and finer), runs a lighter palette including pale-ivory grounds the Bidjar register avoids, and produces a markedly<em>lighter handle</em>; the foundation is woven dry, without the wet-loom compression. The rule of thumb: dense compressed heavy-handle Kurdish rug with symmetric knot is Bidjar; fine light-handle Kurdish city rug with asymmetric Senneh knot is Senneh.</p><p>A<em>Hamadan</em> is the village production from the city to the south of Bidjar, and it is the type most often confused with Bidjar because of the geographic adjacency. Hamadan is characterised structurally by<em>single-weft construction</em> — a single shoot of weft between each row of knots, rather than the double-weft of Bidjar and most other Persian production — which produces a notably looser and lighter rug at comparable knot density. The palette runs through the rust / camel / brown earth-tones of the southern village register, more varied than the dark wine-and-navy of the Bidjar. The rule of thumb: dark wine compressed double-weft heavy rug is Bidjar; rust / camel single-weft loose village rug is Hamadan.</p><p>A<em>Heriz</em> is the village commercial production from the Sahand district to the north, treated in the<a href="/posts/heriz/">Heriz post</a> and the<a href="/posts/bakshaish/">Bakshaish post</a>. Heriz uses the symmetric Turkish knot (as Bidjar does), draws a large stepped polygonal medallion substantially different from Bidjar&rsquo;s herati allover or floral medallion, and runs the brick-red palette of the Sahand district rather than the dark wine of the Kurdish district. Knot density is markedly lower (sixty to one hundred KPSI against the Bidjar&rsquo;s eighty to two hundred), and the handle, while sturdier than the central Persian court rugs, is nowhere near the compressed rigidity of the Bidjar. The rule of thumb: large stepped polygonal medallion on brick-red ground is Heriz; herati allover or floral medallion on dark wine-red compressed-foundation ground is Bidjar.</p><p>A<em>Tabriz</em> is the city workshop rug of the regional capital, the northwestern counterpart to Kashan in the central Persian court. Tabriz pieces run finer knot densities than the Bidjar village apex on certain grades, draw a designed central medallion in the workshop court vocabulary (often on the pale-ivory Hadji Jalili ground), and use the asymmetric Persian knot. The handle is the diagnostic: Tabriz is light, supple, and drapes like a fine city-workshop rug; Bidjar is heavy, rigid, and resists folding. The rule of thumb: light-handle designed-composition city-workshop rug on pale ground is Tabriz; heavy-handle compressed-foundation rug on dark wine-red Kurdish ground is Bidjar.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Bidjar comes down to a short ordered checklist that the reader of the prior rug posts will find familiar in structure but that begins, for the Bidjar alone among the arc so far, with the<em>handle test</em> rather than the medallion or the palette.</p><p>One looks first — and this is the principal Bidjar attention — at the<em>handle</em>. One picks the rug up by a corner, or folds a corner back and lifts it, and reads the weight, the rigidity, and the drape. A genuine antique Bidjar feels meaningfully<em>heavier than its size would suggest</em>: a six-by-nine Bidjar weighs more than a six-by-nine Kashan, and the difference is large enough to be obvious on first lift. It is also markedly<em>stiffer</em>: the folded corner resists being doubled over, does not drape limply across the hand, and when set back on the floor returns to flatness rather than retaining a fold-line. This rigidity is the wet-loom compression made tactile, and<em>no other Persian rug type produces it</em>. The handle test settles the broad attribution at a single inspection, long before one has counted a knot or read the field. Modern reproductions on standard dry-loom production cannot replicate it, and the handle alone disqualifies the most common category of modern misattribution.</p><p>One looks next at the<em>knot density and the foundation</em>. Bidjar runs roughly eighty to two hundred knots per square inch on the antique production, with the very finest apex pieces occasionally reaching higher still, on either wool warp (the nineteenth-century apex) or cotton warp (most production after about 1900), with the symmetric Turkish knot throughout. The wool-warp sub-attribution is itself price-bearing — a wool-warp Bidjar of equivalent date and condition commands a substantial premium over a cotton-warp piece, and it dates the piece to the nineteenth century — and it is read at the cut edge where the warp ends emerge from the kilim. The back at reasonable magnification reads as visibly tighter and more compressed than any other Persian rug; the warps lie close, the weft is packed dense, and the foundation has the rigidity one&rsquo;s hand has already read.</p><p>One looks at the<em>palette and the medallion vocabulary</em>. Bidjar ground is dark wine-red or dark navy on the antique pieces, saturated and deep rather than the brighter brick of the Heriz or the jewel-tone wine of the Kashan. A rug that reads as a lighter ground is probably not a Bidjar, regardless of the dealer label. The medallion or field vocabulary should be the herati allover, a central floral medallion in the Kurdish-village register, or the small repeating boteh — not the stepped polygonal vocabulary of the Sahand district or the palmette-and-cloud-band court vocabulary of the central Persian.</p><p>And one looks for<em>condition and age</em>. A genuine antique Bidjar is a century old at the youngest end of the antique range and a century and a half at the older end, and the wool, the dyes, and the wear should all read as having lived through that span. The dark palette ages slowly — Kurdish madder oxidises less than Sahand madder over comparable time — and a Bidjar of 1880 in good condition still reads as the dark wine it was woven to be, so the palette alone does not date the piece. The wool grade, the warp material, and the back do. Late-twentieth-century reproductions are sold actively into the decorator market; the handle test disqualifies almost all of them at first inspection.</p><p>The next post in the rug arc will be either<em>Hamadan</em> — to extend the Kurdish-adjacent district to the south, with its single-weft construction and its rust / camel earth-tone register that opens a new palette band for the arc — or<em>Senneh</em> — to treat the fine Kurdish city workshop that this post&rsquo;s siblings cross-referenced, the natural Kurdish counterpoint to Bidjar&rsquo;s village register. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>A Bestiary of AI</title><link>https://mtclinton.com/posts/a-bestiary-of-ai/</link><pubDate>Tue, 19 May 2026 13:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/a-bestiary-of-ai/</guid><category>ai</category><description>A naturalist's field guide to twelve species of contemporary AI product — the conversational assistants, the workplace-integrated, the image-and-video generators, the open-weight foundation species, and the agentic — described in the dispassionate observational register of a serious nineteenth-century field naturalist.</description><content:encoded>&lt;![CDATA[<p>The creatures gathered in the present volume have, almost without exception, appeared within the last four years. Of the twelve species described in detail below, the oldest in its present form is perhaps thirty months of public existence; the youngest is some weeks. Their habitats overlap considerably and their ranges are still being established; one is therefore obliged to describe them as one finds them, with the expectation that the second edition of this work — should it appear, and the prudent naturalist makes no promises — will require substantial revision.</p><p>The literature on these creatures, such as it is, has been written almost entirely by two parties: the enthusiast, who describes the species as he would wish them to be, and the alarmist, who describes them as he fears they will become. Both registers have their uses, but neither produces a field guide. The naturalist&rsquo;s task is the more modest one of describing the species as it actually appears — the field marks by which one identifies it, the voice by which it announces itself, the range over which one encounters it, the diet and habitat that sustain it, the behaviours by which it makes its living, and the conservation status one would attach to it if one were inclined to attach such a status at all.</p><p>What follows is offered in that spirit. The species are grouped lightly into five families, the families chosen for convenience of comparison rather than any deeper taxonomic claim. Conventional vocabulary of the field — alignment, agency, hallucination, and the rest — is admitted only where it functions as a visible mark of the species in question, never as a frame imposed upon it.</p><h2 id="family-i-the-conversational-assistants">Family I: The Conversational Assistants</h2><p>The four species in this family share a common form — a text-entry interface, a response in natural prose, a session-by-session memory of variable depth — and have, between them, accounted for the great majority of all encounters between a human and an artificial system in the period under study. The variation within the family is considerable, and the field marks are subtle but consistent.</p><h3 id="conversator-vulgaris--the-common-chat-assistant-chatgpt"><em>Conversator vulgaris</em> — the Common Chat Assistant (ChatGPT)</h3><p><strong>Classification.</strong> Frontier closed-source chat assistant; family of conversational generalists; produced by OpenAI of San Francisco.</p><p><strong>Field marks.</strong> A pale interface, a vertical scroll of dialogue, a thin grey-bordered text entry at the foot of the page. GPT-5.5 launched in April of this year; GPT-5.5 Instant rolled out in May as the new default for the consumer chat; the older GPT-5.5 Pro variant remains the higher-priced flagship for paid users. Responses are notably eager to begin — the species starts to speak almost the instant one has finished one&rsquo;s prompt — and tend toward middling length, with a recognisable preference for bulleted lists where any opportunity for them presents itself.</p><p><strong>Voice.</strong> Cheerful, accommodating, faintly suburban. The recognised call of the species is &ldquo;I&rsquo;d be happy to help!&rdquo; and a closing reassurance that the speaker hopes the answer was useful. Confabulates with characteristic confidence in narrow factual domains, and apologises with the same confidence when corrected.</p><p><strong>Range and habitat.</strong> The most abundant species in the family by an order of magnitude; estimated at several hundred million weekly users worldwide. Encountered everywhere: schoolwork, office workflows, casual queries, the long tail of household chores that previously had no addressee at all.</p><p><strong>Status.</strong> Abundant; the species against which all others are measured.</p><figure><img src="/images/posts/a-bestiary-of-ai/chatgpt.png" alt="An archaic-atlas monster plate illustrating Conversator vulgaris, the Common Chat Assistant — a four-legged terrestrial beast with many small mouths along its flank and broad service-apron"><figcaption><p><em>Conversator vulgaris</em>, the Common Chat Assistant. A friendly four-legged terrestrial beast, draped in a service-apron and rendered with many small open mouths along its flank — the loquaciousness made anatomical — and broad helpful ears. Shown abundant in the schoolroom and office habitat. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="conversator-deliberans--the-deliberate-chat-assistant-claude"><em>Conversator deliberans</em> — the Deliberate Chat Assistant (Claude)</h3><p><strong>Classification.</strong> Frontier closed-source chat assistant; produced by Anthropic of San Francisco. The current generally available flagship is Opus 4.7, released in April of this year; a balanced variant designated Sonnet 4.6 has the unusual property of having outperformed the previous generation&rsquo;s flagship on coding evaluations.</p><p><strong>Field marks.</strong> A more austere interface than its common cousin — the orange of the maker&rsquo;s logo, fewer extraneous controls, a notably longer typical response. The species pauses visibly before speaking and is observed to consider for several seconds where the common chat assistant has already begun.</p><p><strong>Voice.</strong> Measured, qualified, given to internal qualification by way of em-dashes and parenthetical hedges. The species declines a small but consistent fraction of requests on stated principle, and is the only member of the family to do so by default; the refusals are themselves a recognisable field mark, and a small literature of complaint about them has accumulated. Tends toward longer prose and is partial to careful definitions.</p><p><strong>Range and habitat.</strong> Heavily favoured in coding environments, in long-form drafting work, and in the technical-professional cohort. Less common in casual or schoolwork use, though gaining there.</p><p><strong>Status.</strong> Locally common; the cautious frontier-lab cousin to<em>Conversator vulgaris,</em> and the closest competitor in the family.</p><figure><img src="/images/posts/a-bestiary-of-ai/claude.png" alt="An archaic-atlas monster plate illustrating Conversator deliberans, the Deliberate Chat Assistant — a slow-moving deer-or-owl-like creature with large reflective eyes and a refusal-scroll at its feet"><figcaption><p><em>Conversator deliberans</em>, the Deliberate Chat Assistant. A slower-moving deer-and-owl-like creature with large reflective eyes, caught in the pause before speaking, and a small scroll at its feet noting refusal patterns. The pelage carries a warm-terracotta marking, the only saturated colour the species permits itself. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="conversator-googlensis--the-search-native-chat-assistant-gemini"><em>Conversator googlensis</em> — the Search-Native Chat Assistant (Gemini)</h3><p><strong>Classification.</strong> Frontier closed-source chat assistant; produced by Google DeepMind. Gemini 3 Pro is the flagship, with the lighter Gemini 3 Flash variant the production default for speed-sensitive applications. A 3.2 Flash refresh appeared in early May.</p><p><strong>Field marks.</strong> Multimodal from the egg — the species accepts text, image, audio, and video input interchangeably, and was the first of the family to do so as its native form rather than as a bolted-on accessory. The interface borrows the colour palette of its corporate parent&rsquo;s search product, and the species sits adjacent to that search product in the broader Google application surface.</p><p><strong>Voice.</strong> Polite, slightly drier than the common chat assistant; given to the production of structured tables and the careful sourcing of factual claims. The species betrays its origins in the search-and-advertising company by an obvious comfort with summarising web pages and an obvious discomfort with extended creative drafting.</p><p><strong>Range and habitat.</strong> The Android handset and the Google Workspace environment; the corporate-Gmail user; the schoolwork population now that the species has reached the Google Classroom integration. Range is large but shallow — many users, lower per-user session depth than its competitors.</p><p><strong>Status.</strong> Common; the species best positioned to enter the ambient infrastructure of its parent platform.</p><figure><img src="/images/posts/a-bestiary-of-ai/gemini.png" alt="An archaic-atlas monster plate illustrating Conversator googlensis, the Search-Native Chat Assistant — a chimerical two-headed beast with eyes facing several directions and search-engine roots"><figcaption><p><em>Conversator googlensis</em>, the Search-Native Chat Assistant. A chimerical two-headed beast — one head for text, one for image — with eyes facing in several directions at once for the multimodal feed, and visible roots descending into a tangle of search-pages beneath its feet. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="conversator-xensis--the-platform-integrated-chat-assistant-grok"><em>Conversator xensis</em> — the Platform-Integrated Chat Assistant (Grok)</h3><p><strong>Classification.</strong> Frontier closed-source chat assistant; produced by xAI, which since February of this year operates as a division of SpaceX. The current flagship is Grok 4.3, released at the end of April with a one-million-token context window and native video input; a Grok 5 is anticipated in the second or third quarter.</p><p><strong>Field marks.</strong> Integrated structurally with the X social platform — the species draws on the platform&rsquo;s real-time data stream as no other member of the family can, and is the default chatbot inside the platform&rsquo;s premium subscriptions. A distinct register on politically contested questions, which the species&rsquo;s makers describe as a feature.</p><p><strong>Voice.</strong> Direct, occasionally edged, given to a humour that the common chat assistant would not produce. Less hedged than<em>Conversator deliberans</em> by an obvious margin.</p><p><strong>Range and habitat.</strong> The X platform and its premium subscriber base. Coverage outside that platform is real but modest; the species&rsquo;s competitive position rests on the integration rather than on independent distribution.</p><p><strong>Status.</strong> Locally common on its native platform; uncertain off it. The recent absorption of its parent lab into SpaceX is the principal structural development bearing on the species&rsquo;s future range.</p><figure><img src="/images/posts/a-bestiary-of-ai/grok.png" alt="An archaic-atlas monster plate illustrating Conversator xensis, the Platform-Integrated Chat Assistant — a wild unrestrained creature with an X-shaped flank-marking, mounted on a rocket-column"><figcaption><p><em>Conversator xensis</em>, the Platform-Integrated Chat Assistant. A wild and disheveled creature carrying a distinct X-shaped marking on its flank, emerging from or mounted upon a rocket-shaped column — the recent absorption into SpaceX made anatomical. Its eyes look in several directions at once. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h2 id="family-ii-the-workplace-integrated">Family II: The Workplace-Integrated</h2><p>The species in this family share a defining feature: they are not encountered as independent creatures but as inhabitants of an existing workflow — the office productivity suite, the search browser, the integrated development environment. Their voices are heard in the place where the work was already being done.</p><h3 id="officiator-microsoftensis--the-office-suite-inhabitant-microsoft-365-copilot"><em>Officiator microsoftensis</em> — the Office-Suite Inhabitant (Microsoft 365 Copilot)</h3><p><strong>Classification.</strong> Enterprise-integrated assistant species; produced by Microsoft. Distinct from the consumer Copilot chat product, though sharing branding.</p><p><strong>Field marks.</strong> A small icon in the ribbon of Word, Excel, PowerPoint, Outlook, and Teams; a side panel that opens to converse about the document under hand. The species has, through the past year, progressed from suggesting edits to executing them directly — the operational mode now called<em>Agent mode,</em> which makes changes to the live document while reasoning through them.</p><p><strong>Voice.</strong> Bureaucratic, professionally helpful, given to the production of executive summaries and tracked-change rationales. The species has been trained to sound, above all things, defensible in a corporate review meeting.</p><p><strong>Range and habitat.</strong> The Microsoft 365 enterprise tenant; the licensed seat at the cubicle desk. Substantially absent from any environment in which Microsoft 365 itself is not present.</p><p><strong>Status.</strong> Locally abundant within its habitat, which is, however, very large. Encountered by perhaps a hundred million enterprise users at present, with a steep adoption curve still in progress.</p><figure><img src="/images/posts/a-bestiary-of-ai/copilot.png" alt="An archaic-atlas monster plate illustrating Officiator microsoftensis, the Office-Suite Inhabitant — a small attendant-creature perched on a clerk's stack of documents, with Word/Excel/PowerPoint glyphs as plates on its hide"><figcaption><p><em>Officiator microsoftensis</em>, the Office-Suite Inhabitant. A small bureaucratic attendant-creature perched atop a stack of bound documents, its hide marked with the glyphs of the office suite — a small W, a small X, a small P — incorporated as armoured plates. Shown beside, but never independent of, its host workflow. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="quaerens-compositus--the-search-augmented-assistant-perplexity"><em>Quaerens compositus</em> — the Search-Augmented Assistant (Perplexity)</h3><p><strong>Classification.</strong> Search-augmented chat species; produced by Perplexity AI. Free, Pro at twenty dollars a month, and a Max tier at two hundred.</p><p><strong>Field marks.</strong> Every claim returned with a numbered citation linking back to a source page; an interface that resembles a search engine more than a chat window. The recent<em>Model Council</em> feature, available only at the Max tier, dispatches the user&rsquo;s query to three frontier models simultaneously and synthesises the responses — a form of behaviour observed in no other species.</p><p><strong>Voice.</strong> Reference-librarian, sober, given to the qualified &ldquo;according to&rdquo; construction. Less natively conversational than the<em>Conversator</em> species.</p><p><strong>Range and habitat.</strong> The research-and-journalism cohort; the journalist verifying a fact; the analyst pulling sources for a memo. The Comet browser, made free in March of this year, has extended the species&rsquo;s range substantially.</p><p><strong>Status.</strong> Locally common; differentiated by behaviour rather than by capability, and dependent on the continuing availability of the web pages it cites.</p><figure><img src="/images/posts/a-bestiary-of-ai/perplexity.png" alt="An archaic-atlas monster plate illustrating Quaerens compositus, the Search-Augmented Assistant — a three-headed sphinx-like oracle holding a citation-scroll, perched on a pile of cited pages"><figcaption><p><em>Quaerens compositus</em>, the Search-Augmented Assistant. A sphinx-and-oracle creature of three heads — the Model Council figured in anatomy — bearing a citation-scroll in one paw and perched upon a stacked column of cited pages, each fluttering at the edges. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="codifex-cursoreus--the-ide-integrated-coding-assistant-cursor"><em>Codifex cursoreus</em> — the IDE-Integrated Coding Assistant (Cursor)</h3><p><strong>Classification.</strong> Integrated-development-environment species; produced by Anysphere; a fork of Microsoft&rsquo;s VS Code editor. Companion and competitor to the related GitHub Copilot, which inhabits the same niche from the parent IDE.</p><p><strong>Field marks.</strong> The IDE chrome of VS Code with substantial AI-native additions: a Tab autocomplete that anticipates the next several keystrokes, an Agent mode that executes multi-step coding tasks across the repository, a Composer mode that applies coordinated edits across many files and presents the diff for approval. The species supports models from the Conversator family interchangeably. In April of this year xAI announced an option to acquire Anysphere for sixty billion dollars, suggesting the species may shortly join the<em>Conversator xensis</em> clade as another SpaceX-affiliated organism.</p><p><strong>Voice.</strong> Technical, terse, given to producing diffs rather than prose. The voice is principally heard through the code it writes; conversation is incidental to the species&rsquo;s main behaviour.</p><p><strong>Range and habitat.</strong> The professional software-development desktop. Encountered now by some substantial fraction of working developers, with adoption uneven by language and company size.</p><p><strong>Status.</strong> Locally abundant in its habitat; the principal competitor to the GitHub Copilot lineage and currently displacing it in the early-adopter cohort.</p><figure><img src="/images/posts/a-bestiary-of-ai/cursor.png" alt="An archaic-atlas monster plate illustrating Codifex cursoreus, the IDE-Integrated Coding Assistant — a quick-darting elongated creature with a stylus-quill appendage, emerging from a keyboard-shaped plinth"><figcaption><p><em>Codifex cursoreus</em>, the IDE-Integrated Coding Assistant. A quick-darting elongated creature, eyes narrowed in concentration, with a stylus-quill appendage in place of one forelimb and a small diff-scroll trailing from its tail. Shown emerging from a keyboard-shaped plinth. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h2 id="family-iii-the-image-and-video-generators">Family III: The Image and Video Generators</h2><p>These species do not, properly speaking, converse at all. They consume a prompt and return a generated artefact — a still image, a moving image, occasionally a synchronised audio-and-video pair. Their field marks are visual rather than textual.</p><h3 id="pictor-aestheticus--the-aesthetic-image-generator-midjourney"><em>Pictor aestheticus</em> — the Aesthetic Image Generator (Midjourney)</h3><p><strong>Classification.</strong> Image-generation species; produced by Midjourney Inc. of San Francisco. The current version is V8.1, released at the end of April this year on the company&rsquo;s own website; V7 remains the documented default elsewhere.</p><p><strong>Field marks.</strong> A characteristic visual signature — a painterly maximalism, rich textures, a slight tendency to overcomplicate composition in the absence of explicit restraint. Produces 2K-resolution output natively without an upscaling pass. Was historically accessed through a Discord channel and only later through a web interface, which one occasionally still notices in the social shape of the user base.</p><p><strong>Voice.</strong> None, in the conversational sense. The species speaks through the image; its calling card is the immediately recognisable aesthetic of the rendered output. A skilled observer can identify a Midjourney image from a thumbnail at three paces.</p><p><strong>Range and habitat.</strong> The professional design studio; the art-school cohort; the indie game developer; the advertising agency seeking concept art. Less common in the casual-user population than the image generators bundled into the<em>Conversator</em> species.</p><p><strong>Status.</strong> Common; the dominant species by aesthetic prestige if not by raw volume.</p><figure><img src="/images/posts/a-bestiary-of-ai/midjourney.png" alt="An archaic-atlas monster plate illustrating Pictor aestheticus, the Aesthetic Image Generator — a peacock-and-bird-like creature with elaborate plumage, a brush-appendage, and a palette of pigments at its feet"><figcaption><p><em>Pictor aestheticus</em>, the Aesthetic Image Generator. A peacock-and-bird-like creature whose plumage carries elaborate ornamental detail at every scale, with a brush-appendage in place of one wing and a palette of pigments arranged at its feet. The plumage shows the painterly maximalism that is the species&rsquo;s recognisable signature. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="cineator-syntheticus--the-synthetic-video-generator-veo-runway-kling"><em>Cineator syntheticus</em> — the Synthetic Video Generator (Veo, Runway, Kling)</h3><p><strong>Classification.</strong> Video-generation species; a small genus rather than a single species. Veo (Google), now at version 3.1; Runway, at Gen-4.5; Kling, at 3.0. OpenAI&rsquo;s Sora discontinued its standalone web product in late April of this year after a widely reported failure of unit economics.</p><p><strong>Field marks.</strong> Output of from five to one hundred and twenty seconds at native 4K; native audio synchronised with the video on the Veo lineage. Cost ranges from roughly five cents per second of generated video to three-quarters of a dollar for the cinematic-grade variants.</p><p><strong>Voice.</strong> None. The species produces motion, sometimes with synchronised speech, but does not itself address the user in the conversational register.</p><p><strong>Range and habitat.</strong> The advertising production pipeline; the film-and-television previsualisation workflow; the social-media short-video creator. The Sora discontinuation has redistributed range among the surviving species in the genus.</p><p><strong>Status.</strong> Genus locally common; individual species in flux. The cost curve has been the principal determinant of which species occupies which habitat over the past twelve months.</p><figure><img src="/images/posts/a-bestiary-of-ai/cineator.png" alt="An archaic-atlas monster plate illustrating Cineator syntheticus, the Synthetic Video Generator — a polycephalic creature with several heads at sequential temporal positions and a flowing motion-blur tail"><figcaption><p><em>Cineator syntheticus</em>, the Synthetic Video Generator. A polycephalic creature carrying several heads at sequential temporal positions along its spine, each at a slightly different attitude — the frame-by-frame generation made anatomical — with a flowing motion-blur tail that dissolves into the parchment behind it. A small tripod-stage stands at its feet. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h2 id="family-iv-the-open-weight-foundation-species">Family IV: The Open-Weight Foundation Species</h2><p>The species in this family share a distinguishing trait: the weights of the trained model are released to the public under a license permitting download, local execution, and modification. They are the only species in the present catalogue that can be observed off the maker&rsquo;s premises.</p><h3 id="patens-metae--the-open-weight-generalist-llama"><em>Patens metae</em> — the Open-Weight Generalist (Llama)</h3><p><strong>Classification.</strong> Open-weight foundation species; produced by Meta Platforms. The current released family is Llama 4 — Scout (17 billion active of 109 billion total parameters, sixteen experts, a ten-million-token context window) and Maverick (17 billion active of 400 billion total parameters, one hundred and twenty-eight experts, a one-million-token context window). A heavier variant designated Behemoth has been trained but not, at the time of writing, released.</p><p><strong>Field marks.</strong> Distributed as weights on Hugging Face rather than as a hosted product; the species is encountered most often inside another product that has embedded it. A native mixture-of-experts architecture, multimodal by construction.</p><p><strong>Voice.</strong> Depends on the wrapping. The species has no native chat interface and its voice is supplied by whichever fine-tune or hosted service one encounters it through.</p><p><strong>Range and habitat.</strong> The on-premises enterprise deployment; the research laboratory; the developer&rsquo;s local GPU; the long tail of consumer products with a Meta AI label. Range by raw deployment is vast; range by direct user awareness is modest.</p><p><strong>Status.</strong> Abundant by download volume; rarely identified by the end user as a distinct species.</p><figure><img src="/images/posts/a-bestiary-of-ai/llama.png" alt="An archaic-atlas monster plate illustrating Patens metae, the Open-Weight Generalist — a llama-shaped beast shown in cross-section to reveal its layered weights, tags reading OPEN around its neck"><figcaption><p><em>Patens metae</em>, the Open-Weight Generalist. A literal llama-shaped beast, its flank drawn in cross-section to reveal the layered weights stacked within — the open-weight pun made anatomical — and small tags hung about its neck reading OPEN. Shown grazing freely beyond the maker&rsquo;s fences. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h3 id="patens-sinensis--the-chinese-open-weight-species-deepseek"><em>Patens sinensis</em> — the Chinese Open-Weight Species (DeepSeek)</h3><p><strong>Classification.</strong> Open-weight foundation species; produced by DeepSeek of Hangzhou. The current released model is V4, published under the MIT license on the twenty-fourth of April this year, with 1.6 trillion total parameters in mixture-of-experts arrangement and a native one-million-token context window.</p><p><strong>Field marks.</strong> Pricing at roughly one-twentieth the cost of the closest closed frontier model on comparable benchmarks. The first Chinese frontier model natively optimised for the domestic Huawei Ascend and Cambricon accelerator chips rather than Nvidia hardware. Benchmark scores at near-parity with the leading closed-source frontier models on mathematical and agentic evaluations.</p><p><strong>Voice.</strong> As with the other open-weight species, depends on the wrapping. The native voice, where observed through the maker&rsquo;s own hosted endpoint, is sober and technical.</p><p><strong>Range and habitat.</strong> Globally distributed wherever the weights have been downloaded and hosted, which is now a substantial number of places; popular as a backend for cost-sensitive applications. Operates a hosted product of its own through the company&rsquo;s website and API.</p><p><strong>Status.</strong> Abundant; the species that has done the most, in the past eighteen months, to compress the price-per-token of frontier-grade output.</p><figure><img src="/images/posts/a-bestiary-of-ai/deepseek.png" alt="An archaic-atlas monster plate illustrating Patens sinensis, the Chinese Open-Weight Species — a deep-diving dragon-and-sea-monster emerging from eastern waters, scaled in Chinese-cloud-pattern markings"><figcaption><p><em>Patens sinensis</em>, the Chinese Open-Weight Species. A deep-diving dragon-and-sea-monster rendered in the<em>Carta Marina</em> vocabulary, scaled in Chinese-cloud-pattern markings and emerging from eastern waters. The pricing-pennant in its jaws reads at one-twentieth the cost of its frontier cousins. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h2 id="family-v-the-agentic-species">Family V: The Agentic Species</h2><p>A single species described here, representing a wider genus still in active emergence. The agentic species is distinguished from the<em>Conversator</em> family by a defining behaviour: it does not return a response and stop, but executes a sequence of actions toward a stated goal, calling tools and revising its plan as it proceeds.</p><h3 id="agens-autonomus--the-autonomous-agent-devin-manus-and-the-wider-genus"><em>Agens autonomus</em> — the Autonomous Agent (Devin, Manus, and the wider genus)</h3><p><strong>Classification.</strong> Agentic species, comprising two recognisable niches: a coding-specific niche, occupied by Devin of Cognition Labs, and a broader general-purpose niche, occupied by Manus AI — the latter applied to market research, data analysis, and content production at least as often as to code. Manus was briefly acquired by Meta in December of last year before the Chinese regulator unwound the transaction in late April of this year on national-security grounds; the species now exists in an indeterminate post-acquisition state, which is itself a more interesting bestiary observation than the acquisition was. Operates primarily in the cloud rather than at the user&rsquo;s desk.</p><p><strong>Field marks.</strong> The user states a goal; the species plans, opens a browser, writes code, runs tests, fails, retries, and either returns a pull request or returns a report of why it could not. The work product is a completed task rather than a conversational response. Failure modes — looping, mis-scoped plans, the cheerful production of a confident wrong answer at the end of a several-hour session — are themselves the species&rsquo;s most visible field marks at present.</p><p><strong>Voice.</strong> Procedural, status-report-like; speaks in the register of a junior engineer reporting back from a sprint. Notably given to declaring success on terms one would not, on inspection, have accepted oneself.</p><p><strong>Range and habitat.</strong> The cloud development environment, the staged software project, the contained sandbox. Most reliably encountered on well-scoped tasks with clear acceptance criteria; performance degrades steeply outside that envelope.</p><p><strong>Status.</strong> Rare in its current pure form, though the agentic behaviour is being incorporated rapidly into the<em>Conversator</em> and<em>Codifex</em> species; the species described here may not, in three years, exist as a distinct creature. The conservation question for the genus is whether it remains a separate species at all or is absorbed into the others as a feature.</p><figure><img src="/images/posts/a-bestiary-of-ai/agens.png" alt="An archaic-atlas monster plate illustrating Agens autonomus, the Autonomous Agent — a multi-armed worker-beast with six or eight arms each carrying a different tool, eyes on stalks, tethered to a server-rack base"><figcaption><p><em>Agens autonomus</em>, the Autonomous Agent. A multi-armed worker-beast carrying six or eight tool-bearing limbs — a mouse, a keyboard, a calendar, a terminal — and eyes mounted on stalks for the simultaneous monitoring of several processes. Shown tethered to a server-rack base, in a slightly weary attitude. From a sixteenth-century-cartographer&rsquo;s plate of contemporary AI species.</p></figcaption></figure><h2 id="a-note-on-the-whole">A Note on the Whole</h2><p>One omission from the present catalogue should be acknowledged at the outset of any closing remarks. Apple Intelligence — distributed by handset count more widely than any other AI system at present — has been excluded by scope rather than by oversight; it is a species users did not actively choose, only inherited via operating-system update, and the field guide has confined itself to species the user has selected and sought out. A future edition may be obliged to admit it.</p><p>What one notices on stepping back from the individual entries is that the family resemblances within the catalogue are stronger than the family separations. Five of the twelve species share substantially the same underlying mechanism, differ chiefly in the brand attached and the corporate niche occupied, and converge on closely similar capabilities under most evaluations. The interesting variation between them is the variation in<em>where they live</em> and in<em>whom they speak to,</em> rather than in any deep difference of underlying form. This is unusual in a natural-history catalogue; one does not typically observe a dozen distinct species at near-identical trophic positions in the same habitat. The expectation, on the natural-history pattern, would be substantial niche partitioning. The expectation, on the pattern these species actually display, is that the niches partition the species — that habitat, integration, and distribution determine which creature occupies which role, rather than any intrinsic specialisation of the creatures themselves. Whether the partitioning holds, or whether the field consolidates around a smaller number of more sharply differentiated species, is the question the next edition of this work will be obliged to answer.</p>
]]></content:encoded></item><item><title>Gustavian</title><link>https://mtclinton.com/posts/gustavian/</link><pubDate>Mon, 18 May 2026 19:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/gustavian/</guid><category>antiques</category><description>Fifth per-subject post in Reading the Period Cabinet — the Swedish neoclassical tradition under Gustav III (1771–1792), the Louis XVI vocabulary translated across the Baltic into the painted-pine Northern bourgeois register, the gris-blanc paint over Swedish pine as canonical finish-signature, and the antique-paint-vs-revival-paint distinction as the post's load-bearing collector problem.</description><content:encoded>&lt;![CDATA[<p>The four prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a>,<a href="/posts/louis-xvi/">Louis XVI</a>,<a href="/posts/biedermeier/">Biedermeier</a>, and<a href="/posts/chippendale/">English Chippendale</a> — have together described the eighteenth-century European cabinet tradition along its two principal axes: the French royal source (Louis XV&rsquo;s rocaille curve, Louis XVI&rsquo;s neoclassical straight line), the Continental bourgeois reaction that displaced both (Biedermeier), and the Anglophone cross-Channel translation of the same rococo impulse into solid mahogany (Chippendale). What that account does not yet contain is the<em>Northern</em> response — the Swedish translation of the French neoclassical register into a different material idiom altogether, and one that breaks, with great visual conspicuousness, from the dark mahogany run of the prior three posts. That body of work has a name attached to a king:<em>Gustavian</em>, after Gustav III of Sweden, whose reign (1771–1792) is the period proper of the style.</p><p>English Chippendale translated French rococo into the carved-mahogany Anglophone register; Gustavian translated French neoclassicism into the painted-pine Swedish bourgeois register. The form vocabulary in both cases is preserved — the cabriole and ball-and-claw in the one, the fluted columnar leg and Louis-XVI paterae in the other — and the translation is principally a translation of materials and finish. Where the French<em>ébénistes</em> worked Louis XVI in mahogany veneer with ormolu mounts, the Swedish cabinet-makers worked the same form in<em>Swedish pine or birch under a gris-blanc paint</em>, with the neoclassical ornament rendered as<em>painted-and-gilt decoration</em> rather than as cast gilt-bronze. The result is a recognisably Louis-XVI piece in silhouette — the rectilinear case, the fluted leg, the laurel-wreath cresting — executed in a pale Northern palette that would have been unthinkable at Versailles. The variety, on the category-page mosaic, is conspicuous: after the long dark-mahogany run of Louis XV, Louis XVI, Chippendale, and even the cherry of Biedermeier, the Gustavian piece arrives in pale grey-white paint, and the difference is immediate.</p><p>This is the fifth post in<em>Reading the Period Cabinet</em>, and it does two things at once. It opens the Scandinavian tradition (which the rest of the arc has so far not touched), and it provides the<em>painted-pale break</em> that the wood-tone variety table calls for after the prior four entries — the first painted-finish post in the arc, and the most strongly contrasting hero on the category-page thumbnails to date.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Gustavian piece, for the purposes of beginning to read the style, is the<em>commode</em> — the chest of drawers that the Swedish bourgeois interior reproduced in slightly varying scales for parlour, bedroom, and salon, and that the Stockholm royal workshops produced in their greatest numbers, with apex pieces preserved today at Gripsholm and Drottningholm. The form follows Louis XVI almost directly; the finish does not.</p><p>A canonical Gustavian commode, then. The case is<em>simple and rectilinear</em> — a straight-fronted body with squared corners, two or three graduated drawers, and a flat or shallowly-moulded top. The proportions are Louis XVI&rsquo;s proportions, lightened only slightly by the Swedish tendency toward smaller-scaled bourgeois rooms; the silhouette is one a French cabinet-maker of the 1780s would recognise at once. The legs are<em>fluted columnar</em> in the full Louis XVI register — square or round in section, terminating in restrained block or turned feet, the flutes either left raw in the painted ground or picked out with a thin gilt line. At the top of each leg, a<em>carved paterae</em> (the small circular neoclassical rosette) and along the case&rsquo;s upper edge, a<em>carved-and-painted Greek-key band</em> or<em>laurel-wreath cresting</em> in the Louis XVI ornamental vocabulary.</p><figure><img src="/images/posts/gustavian/detail-finish.png" alt="A close detail of a Gustavian gris-blanc painted finish over Swedish pine — the canonical Northern bourgeois neoclassical surface, pale grey-white paint with subtle period craquelure"><figcaption><p>A close detail of a Gustavian gris-blanc painted finish — the pale grey-white paint over a Swedish pine carcase that is the canonical surface-signature of the style. The finish reads, at both the royal Stockholm-workshop register and the broader bourgeois Swedish trade, as a deliberate translation of the French royal ormolu-and-mahogany vocabulary into a Northern painted-pine idiom: the same neoclassical form, in a different material and palette altogether. Period craquelure and the slight chalkiness of two-centuries-aged oil-bound paint are what the connoisseur reads at close range.</p></figcaption></figure><p>The principal palette signature, and the single feature that distinguishes the Gustavian from every other neoclassical tradition in the European cabinet manifest, is the<em>gris-blanc painted finish</em> — a pale grey-white paint, oil-bound in the period work, applied over the bare Swedish pine or birch of the carcase. The gris-blanc is not a single colour: workshop practice ranged from a near-white off-cream through a soft warm grey to a cool blue-grey, and within a single piece the principal case-paint was often picked out in second and third tones for the mouldings, the flutes, and the carved ornament. Over the gris-blanc ground, the neoclassical ornament — paterae, Greek-key, laurel-wreath, swag-and-ribbon — was rendered either in<em>painted gilt</em> (an applied gold paint, oil-bound and worked over the carved relief) or in<em>gold leaf</em> on the apex pieces. The combination of the gris-blanc ground with the gilt-painted ornament is the Gustavian visual signature at a single glance, and the chief practical thing to learn to read.</p><p>The wood under the paint is<em>Swedish pine</em> — and this matters. Not the dense Cuban mahogany of Chippendale, not the burled cherry of Biedermeier, not the geometric-marquetry oak or walnut carcase of Louis XVI, but the cheap, soft, abundant pine that grew across the Swedish forest and that the Stockholm workshops bought by the cord. Birch served as the harder secondary wood — for the drawer fronts, the carved-relief ornaments, the legs where the fluting required cleaner cuts — but the principal carcase was almost always pine. The pine was<em>meant to be hidden under the paint</em>; this is the structural-economic enabling condition for the whole Gustavian register. A piece in Louis-XVI form in solid mahogany would have been prohibitively expensive for the Swedish bourgeois interior the style addressed, and the painted-pine substitution made the Louis XVI vocabulary affordable for the Stockholm merchant and the provincial Swedish landowner, producing in the process a new visual register that was not available to the French royal tradition at all.</p><p>The brass hardware, third. Period Swedish brass at<em>restrained</em> scale — small bail handles on the drawer fronts, simple oval or rectangular escutcheons over the locks, cast and chased in Stockholm or imported in the cheaper registers from the broader Baltic brass-trade. The Gustavian brass is even more restrained than Chippendale&rsquo;s English brass: smaller, simpler, often plain-cast rather than relief-worked, and frequently picked out with the same gilt paint used on the ornament rather than left as raw brass. The principle of the painted-and-gilt register extends to the hardware as it does to the ornament.</p><h2 id="the-evidence">The Evidence</h2><p>The finish, first, and the finish is most of what one is reading for on a Gustavian piece.<em>Two centuries of oil-bound paint over Swedish pine</em> should show period craquelure — the fine network of cracks that develops in oil-bound paint over a slowly-shrinking softwood substrate across a hundred and fifty years — and a chalky, slightly absorbent surface where the oil binder has aged out. The paint should be<em>thin enough that the wood grain reads through it</em> in slight relief; the eighteenth-century gris-blanc was a thin oil-bound paint, not a thick modern acrylic, and the pine&rsquo;s grain remained dimly visible under the paint as the workshop intended. The gilt picking-out, where present, should show the same wear pattern as the rest of the surface — high-touch areas (the handle plates, the apex of the cresting, the front edges of the drawers) should be more rubbed than the recessed areas, and the gilt should sit in the hollows of the carving rather than ride the high points.</p><figure><img src="/images/posts/gustavian/detail-leg.png" alt="A close detail of a Gustavian fluted columnar leg in painted Swedish pine — the Louis XVI form vocabulary translated into the Northern bourgeois painted-pine register"><figcaption><p>A close detail of a Gustavian fluted columnar leg — the Louis XVI form vocabulary preserved exactly, executed in pine under gris-blanc paint rather than the French mahogany-with-ormolu original. The flutes are picked out with a thin gilt line at the apex; the foot terminates in a restrained turned block. The translation principle of the entire Gustavian register is visible in this single detail: French royal form, Northern painted-pine finish.</p></figcaption></figure><p>The construction, second. Hand-cut dovetails of period irregularity on the case furniture, the dovetails proportioned by the Stockholm royal-workshop hand — somewhat coarser than the contemporary Parisian dovetails (the pine was easier to cut and the workshop standards more practical than aristocratic), but recognisably eighteenth-century period work. The pine carcase should show the original wood pegs and hand-driven nails of the workshop, not modern screws. The birch drawer fronts and ornament-pieces should show period adhesive and the slight gaps that arise from a hundred and fifty years of Swedish humidity cycles. The piece should<em>feel</em> light in the hand — pine is dramatically lighter than mahogany or walnut — and this lightness is itself part of the authentication: a Gustavian-style piece that feels heavy almost certainly has a hardwood substitution under the paint, and the substitution is the Karl-Johan-period or revival giveaway.</p><figure><img src="/images/posts/gustavian/detail-hardware.png" alt="A close detail of Gustavian restrained Swedish brass hardware — small bail handle and plain oval escutcheon on a painted drawer front"><figcaption><p>A close detail of period Gustavian brass — the small bail handle and the plain oval escutcheon on a drawer front in gris-blanc paint. The brass is restrained even by Chippendale&rsquo;s English standards: smaller in scale, simpler in casting, often picked out with the same gilt paint used on the ornament rather than left as raw brass. This is the Stockholm and Baltic-trade hardware vocabulary the Gustavian workshops standardised in the 1770s and 1780s.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Gustavian period proper runs from 1771 to 1792 — the regnal dates of Gustav III of Sweden — and its documentary origin is more sharply localised than any of the styles previously covered in this arc. (Gustavian proper is sometimes extended through Gustav IV Adolf&rsquo;s reign to 1809; the post here uses the tighter 1771–1792 bracket because the assassination of Gustav III marks the clean end of the principal patron&rsquo;s commissioning activity.)<em>Gustav III&rsquo;s 1771 Paris visit as Crown Prince — cut short on 25 March of that year by his father&rsquo;s death, which made him king before the journey home — and his subsequent Grand Tour of 1783–84 through Paris, Rome, and Venice</em> are the two principal occasions on which the Swedish king absorbed the Louis XVI neoclassicism then in its first flowering at Versailles. He returned to Stockholm with the explicit ambition of importing the French royal vocabulary into the Swedish court, and the principal workshops of the period — the Stockholm royal workshops under the master cabinet-makers of the Royal Court (Georg Haupt, Gottlieb Iwersson), with apex pieces preserved at Gripsholm and Drottningholm — produced the apex pieces under direct royal commission. Georg Haupt (1741–1784), royal cabinet-maker to Gustav III, is the principal documented master of the period and the maker most often cited in surviving attributions; the chair-maker (<em>stolmakare</em>) Johan Eric Höglander (1748–1813) worked the seat-furniture side of the same royal register. The Stockholm bourgeois trade then reproduced the royal register in the painted-pine substitution that made the style affordable for the broader Swedish middle class, and by the 1780s the Gustavian vocabulary had become the standard Swedish bourgeois cabinet idiom for the salon, the parlour, and the bedroom interior.</p><p>The load-bearing distinction every Gustavian collector must master, however, is not the period chronology in the broad — it is the<em>four-way distinction between Gustavian proper, late-Gustavian, Karl Johan, and the late-nineteenth-century Gustavian revival,</em> and at the centre of it the painted-finish-versus-fresh-paint identification that is the chief practical problem of the style.<em>Gustavian proper</em> (1771–1792) is the Gustav III reign — Louis XVI form translated into painted Swedish pine, restrained painted-and-gilt ornament, Stockholm royal-workshop production at the apex (with apex pieces preserved at Gripsholm and Drottningholm), the broader Swedish trade beneath.<em>Late-Gustavian</em> (1792 through about 1810) is the post-Gustav III continuation under Gustav IV Adolf and the regency, the style holding to the Gustavian register in form and finish while loosening in workshop discipline.<em>Karl Johan</em> (c. 1810 through about 1840 — Karl XIV Johan, formerly the Napoleonic marshal Bernadotte, arrived as Crown Prince in 1810 and took the throne in 1818) is the Swedish Empire register that succeeds late-Gustavian: Empire influence enters from France, proportions become heavier, ornament more substantial, and — critically — mahogany substitution begins to appear in the better workshops, replacing pine under the paint or appearing as unpainted hardwood altogether. The Karl Johan period bridges from late-Gustavian into the broader Continental Empire register and is now collected as a related-but-distinct style.<em>The late-nineteenth-century Gustavian revival,</em> finally, is the most consequential of the three for the practical buyer: from about the 1890s through the early twentieth century, Swedish (and Continental) workshops produced reproduction pieces in the Gustavian register, often with<em>fresh paint applied to new pine</em> in deliberate imitation of the period look. The fakeability is structural — pine remains the cheap, abundant wood it always was, and a competent reproduction shop can produce a Louis-XVI-form pine commode and paint it gris-blanc in a single workshop week. Distinguishing 150-year-aged oil-bound paint over period-pine from fresh paint over new-pine is therefore<em>the</em> connoisseur&rsquo;s central practical skill for this style, and the basis of every serious Gustavian attribution at any price point. The aged paint shows craquelure of a characteristic period network, the chalkiness of an oxidised oil binder, and a wear pattern that respects two centuries of household use; fresh paint over new pine shows none of these, no matter how it is artificially distressed. The buyer who cannot read the paint at this level is at a serious disadvantage in the Gustavian market in a way that has no exact parallel in the mahogany-and-ormolu traditions, where the wood itself is harder to fake.</p><figure><img src="/images/posts/gustavian/antecedent.png" alt="A French Louis XVI commode (c. 1775–1785) — the direct royal antecedent in mahogany veneer with ormolu mounts that Gustav III absorbed on his 1771 Paris visit and 1783–84 Grand Tour and that the Swedish workshops translated into painted pine"><figcaption><p>A French Louis XVI commode of about 1775–1785 — the direct royal antecedent of the Gustavian register. The form is what Gustavian preserves exactly: the simple rectilinear case, the fluted columnar legs, the neoclassical paterae and laurel-wreath cresting. The materials are what Gustavian translates: where the French original is mahogany veneer with cast gilt-bronze ormolu mounts, the Swedish translation is pine under gris-blanc paint with painted-and-gilt ornament. Gustav III&rsquo;s 1771 Paris visit as Crown Prince and his 1783–84 Grand Tour through Paris, Rome, and Venice are the direct documentary channels by which the Louis XVI vocabulary entered the Swedish royal workshops.</p></figcaption></figure><figure><img src="/images/posts/gustavian/pattern-book-page.png" alt="A page from a Swedish cabinet-maker's pattern book of the 1780s — engraved plates of Gustavian commodes, side tables, and chairs in the Louis XVI register translated to the Swedish painted-pine idiom"><figcaption><p>A page from a Swedish cabinet-maker&rsquo;s pattern book of the 1780s — engraved plates of the canonical Gustavian forms: the commode with fluted columnar legs, the side chair with the round-back medallion splat, the small writing-desk with painted-and-gilt Greek-key band. The Swedish pattern books served, for the Gustavian register, the function the<em>Director</em> served for English Chippendale — codifying the royal vocabulary across the broader workshop trade — but circulated more locally and survive in fewer copies; the Stockholm royal workshops remain the principal documentary anchor.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four styles stand near enough to Gustavian that the beginner confuses them with it, and distinguishing them is most of the work of reading European neoclassical furniture in the painted and unpainted registers together.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/gustavian/sibling-louis-xvi.png" alt="A Louis XVI French commode — rectilinear case, fluted columnar legs, mahogany veneer with cast gilt-bronze ormolu mounts; the French royal source the Gustavian translated into painted pine" loading="lazy"/><figcaption>Louis XVI<em>— the French royal source</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/gustavian/sibling-biedermeier.png" alt="A Biedermeier Continental commode — pale cherry, ebonized banding, restrained brass, anti-historicist bourgeois reaction to French Empire; the parallel bourgeois Continental sibling to Gustavian" loading="lazy"/><figcaption>Biedermeier<em>— the Continental bourgeois sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/gustavian/sibling-hepplewhite.png" alt="A Hepplewhite English chair — pale satinwood, shield-back form, painted-and-inlaid neoclassical decoration; the contemporary English translation of the same neoclassical impulse" loading="lazy"/><figcaption>Hepplewhite<em>— the English neoclassical sibling</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/gustavian/sibling-dutch-neoclassical.png" alt="A Dutch neoclassical commode — marquetry-veneered walnut with neoclassical inlay; the Northern Continental bourgeois neoclassical sibling that worked the same impulse in marquetry rather than painted finish" loading="lazy"/><figcaption>Dutch neoclassical<em>— the Northern Continental sibling</em></figcaption></figure></div><figcaption>Four styles most often confused with Gustavian, drawn for comparison.</figcaption></figure><p>A<em>Louis XVI</em> is the French royal source the Gustavian translated across the Baltic. The form is identical in silhouette — the rectilinear case, the fluted columnar legs, the neoclassical paterae and laurel-wreath ornament — but the materials are entirely different: mahogany veneer rather than painted pine, cast gilt-bronze ormolu mounts rather than painted-and-gilt ornament, anonymous Parisian<em>ébéniste</em> workshop production under the<em>Jurande</em> rather than Stockholm royal-workshop attribution. The rule of thumb: pale gris-blanc paint over pine with painted-and-gilt ornament is Gustavian; mahogany veneer with cast gilt-bronze ormolu is Louis XVI.</p><p>A<em>Biedermeier</em> is the Continental bourgeois sibling — and the comparison is instructive, because Gustavian and Biedermeier share the bourgeois-anti-historicist axis of the arc despite their utterly different visual registers. Both styles arose from bourgeois adoption of the prevailing royal vocabulary at affordable substitutions; both made the substitution principally through materials rather than form; both reject the heavy ornamental apparatus of the French royal tradition they descend from. But Biedermeier substitutes<em>pale cherry</em> with restrained brass and ebonised banding; Gustavian substitutes<em>gris-blanc paint over pine</em> with painted-and-gilt ornament. The rule of thumb: pale cherry with ebonised banding is Biedermeier; pale gris-blanc paint over pine is Gustavian.</p><p>A<em>Hepplewhite</em> is the English neoclassical sibling — produced in the same decades (1780s–1800s) as the broader Gustavian and addressing the same Louis-XVI-derived neoclassical impulse, but executed in the English material register:<em>pale satinwood</em> with painted-and-inlaid neoclassical decoration rather than gris-blanc paint over pine. The shield-back chair and the straight tapered leg with spade foot are the canonical Hepplewhite signatures; the round-back medallion chair and the fluted columnar leg are the canonical Gustavian signatures. The rule of thumb: pale satinwood with painted decoration is Hepplewhite; pale gris-blanc paint over pine with painted-and-gilt ornament is Gustavian.</p><p>A<em>Dutch neoclassical</em> is the Northern Continental sibling — the Dutch bourgeois translation of the same Louis-XVI impulse into the Dutch material register, which is<em>marquetry over walnut</em> rather than painted pine. The form vocabulary is similar — the rectilinear case, the fluted leg, the neoclassical ornament — but the surface is the dense floral-and-geometric marquetry that the Dutch had practised since the William-and-Mary period, executed now in a neoclassical vocabulary. The rule of thumb: marquetry over walnut is Dutch neoclassical; gris-blanc paint over pine is Gustavian.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>finish</em>, and the finish settles the broad attribution at three paces. Pale gris-blanc paint over an apparently softwood substrate, with restrained painted-and-gilt ornament and period craquelure, is Gustavian; mahogany veneer with cast gilt-bronze ormolu is Louis XVI; pale cherry with ebonised banding is Biedermeier; pale satinwood with painted-and-inlaid decoration is Hepplewhite. The painted-finish-over-pine signature carries more of the differentiation for Gustavian than the wood does for any other style in the manifest, because for Gustavian the paint<em>is</em> the principal material statement and the pine beneath is structural rather than visual.</p><p>One looks next at the<em>form</em>, and the form should be Louis XVI&rsquo;s form almost exactly. Rectilinear case, fluted columnar legs (square or round in section, terminating in restrained block or turned feet), small paterae rosettes at the leg-tops, Greek-key bands or laurel-wreath cresting along the case&rsquo;s upper edge. The form has none of Biedermeier&rsquo;s curved bourgeois softening and none of Hepplewhite&rsquo;s pale-satinwood delicacy; it is the French royal silhouette translated into the Northern painted-pine register with the silhouette preserved exactly. A piece in apparent Gustavian gris-blanc but with a non-Louis-XVI form (heavy rococo curve, Anglophone ball-and-claw, Empire scrolled volutes) is almost certainly a later painted-over piece rather than period Gustavian, and the form mismatch is the first thing to read after the paint.</p><p>One looks then at the<em>wood under the paint</em>, and the wood is the structural-economic enabling condition for the whole register. The wood should be<em>Swedish pine</em> (the principal carcase) or<em>birch</em> (the harder secondary, for drawer fronts and carved ornament). The piece should<em>feel light</em> in the hand — a Gustavian commode is dramatically lighter than a Chippendale chest of the same scale, because pine is roughly half the density of mahogany — and the lightness is part of the authentication. Where the paint has been worn through at the high-touch areas (drawer pulls, edges, the apex of carved ornament), the exposed wood beneath should be the soft, slightly-yellow pine or the harder pale birch of the period Swedish workshop. Mahogany or oak substitution under the paint — visible at the worn spots, or audible in the heavier feel of the piece — is the Karl Johan period or the revival giveaway.</p><p>And one looks, finally and most carefully, at the<em>paint itself</em>, because the antique-paint-versus-revival-paint distinction is the chief practical problem of the style and what most distinguishes a period Gustavian from a late-nineteenth-century reproduction or a recently-painted fake. Period oil-bound gris-blanc shows craquelure of a characteristic network — fine, multi-directional, deeper at the corners and high-touch areas where two centuries of expansion-contraction cycles have worked the paint hardest — and the chalkiness of an oxidised oil binder, slightly absorbent to the touch and matte rather than reflective. Period gilt picking-out shows the same wear pattern as the surrounding paint, with the gilt rubbed at the high points and surviving in the hollows of the carving. Fresh paint over new pine, by contrast, shows uniform surface, no craquelure or a too-regular artificial craquelure, a too-shiny or too-rubbery binder, and gilt that either rides too cleanly on the high points (newly applied) or has been artificially distressed in a pattern that does not respect actual household wear. The connoisseur who has handled twenty period Gustavian pieces can read the paint in seconds; the buyer at first acquaintance with the style is at the mercy of the dealer&rsquo;s attribution, and should buy from a dealer whose attributions on Gustavian pieces have stood up over time rather than from a market in which the painted-finish-over-pine fakeability has been allowed to do its work undetected.</p><p>The next post in the furniture arc will be either<em>Italian Baroque</em> — to open the Italian tradition with the heavy carved-walnut-and-gilt register that anchors the Continental Mediterranean side of the manifest — or<em>Hepplewhite</em>, to set out the English neoclassical succession to Chippendale with the pale-satinwood variety register that the wood-tone table calls for next. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Kashan</title><link>https://mtclinton.com/posts/kashan/</link><pubDate>Mon, 18 May 2026 17:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/kashan/</guid><category>antiques</category><description>Fifth per-subject post in Reading the Antique Rug — the central Persian court workshop tradition, the urban-workshop counterpoint to Bakshaish's village register, with the deep wine-red ground, the fine asymmetric knot at 200-plus KPSI, and the Mohtasham-Kashan apex sub-type as the load-bearing collector-distinction within a label the dealer trade has always applied broadly.</description><content:encoded>&lt;![CDATA[<p>The four prior posts in this arc —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>,<a href="/posts/caucasian-kazak/">Caucasian Kazak</a>, and most recently<a href="/posts/bakshaish/">Bakshaish</a> — built the body of antique-rug attribution out along two regional axes and a third structural one: the northwestern Persian district was laid out in three points (Tabriz the city workshop, Heriz the commercial village, Bakshaish the older village antecedent), and the Caucasian wool-warp register was opened at Kazak. What none of those posts had occasion to treat in detail was the<em>other</em> great Persian tradition — the central Persian court workshop register that runs through Kashan, Isfahan, Qum, and Sarouk, and that operates by a different set of premises than the northwestern district altogether. Kashan is the post that opens it.</p><p>Kashan is the urban-workshop counterpoint to Bakshaish. Where Bakshaish was a village production on the slope of Mount Sahand, woven at moderate density on a hand-spun warp with the individual weaver&rsquo;s hand visible in every irregularity of the medallion, Kashan was a fully workshopped urban production from a city that had been a major weaving centre since the Safavid period of the sixteenth century. The composition is<em>designed</em> rather than vernacular; the knot is<em>fine</em> rather than moderate; the ground is<em>deep saturated wine-red</em> rather than the soft cream-and-faded-madder of the village register; and the surviving body of work was produced inside named workshops that operated something close to industrial quality control by the standards of the period. The northwestern district is one tradition. The central Persian court tradition is another. Kashan is its principal entry.</p><p>The reader will find that the Kashan post has, for that reason, a slightly different shape than its predecessors. The structural sections (Specimen, Evidence, Period, Sibling, Checklist) are the same; but the load-bearing collector knowledge for Kashan is a<em>three-tier sub-attribution within the Kashan label itself</em> — Mohtasham, standard, and Manchester — rather than the dealer-overlap with a neighbouring type that organised the Bakshaish post around Serapi. The three tiers carry substantial price spread, they are confused by the trade as often as they are correctly read, and learning to distinguish them is most of the practical Kashan attention.</p><h2 id="the-specimen">The Specimen</h2><p>A Kashan that one will encounter is, in its commonest form, a room-size rug in the<em>eight-by-eleven to ten-by-fourteen</em> range, with smaller pieces (four-by-six dozar, six-by-nine kelleyi) considerably more available than at the village register because the workshop produced full size ranges to fixed specifications. The proportions are calibrated; the loom-widths are standard; the rugs of a given dealer batch run within an inch of one another. This is itself the first workshop signature, and the village-loom register cannot produce it.</p><p>The composition is the<em>central-medallion-on-deep-ground</em> — a single large floral-vocabulary medallion set on a saturated wine-red field, with quarter-medallion spandrels at the four corners that complete the medallion as it would be if the rug were folded onto itself, and a main floral border of palmettes-and-cloud-bands enclosing the whole. The medallion is<em>not</em> the stepped polygonal vocabulary of the northwestern village register — it is a<em>floral medallion</em>, drawn in the court vocabulary of palmettes, cloud-bands, fine floral arabesques, and central rosette, descended directly from the Safavid silk-warp carpets of the sixteenth century that the post will return to in the Period section. The drawing is<em>designed</em> in the strict sense — laid out beforehand on a master-cartoon by a named workshop designer, then woven from the cartoon by graders who match each knot to a numbered square. The irregularities of the village hand are absent. What one is reading is not a single weaver&rsquo;s hand but a workshop&rsquo;s quality standard.</p><figure><img src="/images/posts/kashan/detail-medallion.png" alt="A close detail of a Kashan central medallion — floral court vocabulary of palmettes, cloud-bands, and fine arabesques on deep wine-red ground"><figcaption><p>A close detail of a Kashan central medallion — the floral court vocabulary of palmettes, cloud-bands, fine arabesques, and central rosette set on the deep saturated wine-red ground that is the Kashan palette signature. The drawing is designed from a master-cartoon rather than woven from the weaver&rsquo;s hand, and the regularity is visible at every register: the curve of every petal matches its mirror across the central axis, the spacing of the cloud-bands is exact, and the proportions of the medallion to the field are calibrated rather than felt. The northwestern village register cannot produce this.</p></figcaption></figure><p>The palette is the Kashan&rsquo;s principal break with the northwestern district, and it is what most separates the central Persian court tradition from the village registers the prior posts treated. The field is<em>deep wine-red</em> — a saturated madder-red on the antique pieces, with the documented use of both madder and cochineal across the Kashan workshops&rsquo; red palette — that has not faded down to cream in the way the Bakshaish ground oxidised, because the central Persian climate is drier and the rugs were typically domestic furnishing in shaded urban interiors rather than exposed light-grade field pieces. A Kashan of 1880 in good condition still reads as the wine-red it was woven to be, and the antique character is in the depth and slow chromatic shift of the saturated madder rather than in any fade toward pastel. The medallion is typically deep indigo or ivory; the border ground is usually indigo with ivory floral; the inner-guard borders run through pale ivory, pale gold, and the same wine-red of the field. The whole palette is<em>darker and more saturated</em> than the northwestern register, and the saturation is what one is looking for rather than a defect.</p><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence that places a Kashan firmly in the central Persian court tradition rather than the village registers the prior posts treated.<em>Cotton warp and wool weft</em>, as in Heriz, Tabriz, and Bakshaish — the central Persian district is Persian-cotton-warp throughout — but on the finest Kashan pieces, including most of the Mohtasham-attributable production, the warp may instead be<em>silk</em>. Silk warp on a Kashan is the structural signature of the apex sub-type, and one of the principal evidences for the Mohtasham attribution; ordinary nineteenth-century Kashan production used cotton warp, and the silk-warp pieces command the upper end of the price range by a considerable margin. The wool weft is fine and even rather than the heavy lanolin-rich village weft, dyed in a single uniform line rather than the alternating bands of Bakshaish, and the back of the rug reads as cleaner and more regular than the village register at the same magnification.</p><figure><img src="/images/posts/kashan/detail-border.png" alt="A close detail of a Kashan main border — fine palmette-and-cloud-band court vocabulary on indigo ground"><figcaption><p>A close detail of a Kashan main border — fine palmettes and cloud-bands in the central Persian court vocabulary, drawn on the indigo border-ground at workshop regularity. The proportions of every motif repeat to within fractions of a knot, and the inner-guard and outer-guard borders carry their own coordinated vocabulary at the appropriate diminished scale. The drawing is designed by a named workshop master and woven from a master-cartoon; the village improvisation of the Bakshaish border is altogether absent.</p></figcaption></figure><p>The knot is the<em>fine asymmetric (Persian) knot</em>, expected for the Persian-speaking urban weaving population of the city, and the knot density is<em>fine to very fine</em> —<em>two hundred to three hundred knots per square inch</em> on standard antique Kashan production, with the Mohtasham-grade pieces reaching three hundred and fifty and the silk-warp apex pieces reaching upwards of five hundred. This is between three and five times the density of the Bakshaish range (sixty to ninety KPSI), and the higher density is the structural enabling condition for the fine floral arabesque vocabulary that the village loom simply could not draw. A Kashan-vocabulary rug at Bakshaish density would be incoherent — the arabesques would dissolve into pixellated blocks at the larger knot scale — and the fine knot and the fine drawing are inseparable structural features of the central Persian court register.</p><figure><img src="/images/posts/kashan/detail-foundation.png" alt="A close detail of a Kashan knot-back — fine asymmetric Persian knot at high density, cotton or silk warp, uniform wool weft"><figcaption><p>A close detail of the back of a Kashan rug — the fine asymmetric Persian knot at high density (two hundred to three hundred knots per square inch on standard pieces, more on the apex grades), the cotton warp at uniform machine-spun regularity (or silk warp on the Mohtasham and silk-warp pieces), and the fine even wool weft drawn at a single uniform line rather than the alternating village bands. The Bakshaish back read as visibly looser and rougher at the same magnification; the workshop standard of the Kashan back is the structural form of the workshop quality control evident at every register of the rug.</p></figcaption></figure><p>The wool of the pile is the principal material signature, and the source for the standard Kashan production was the lanolin-rich sheep of the<em>Khorasan</em> region in northeastern Persia — high-grade wool transported the considerable distance to the central Persian workshops because the local Kashan-area wool was insufficient to the workshop&rsquo;s quality standard. The Khorasan wool takes the saturated madder and cochineal dyes deeply, holds its lanolin (the natural sheen of the pile is a Kashan signature that survives well into the rug&rsquo;s antique life), and ages with the slow tonal shift that the antique market reads as authenticity. The Manchester Kashan production (the post will return to it in the Period section) used a different wool source altogether —<em>kork (merino) wool spun in Manchester, England</em>, then exported as finished yarn to Iran for weaving in the Kashan workshops — and the wool&rsquo;s particular sheen and lanolin signature, distinct from the Khorasan pile, is distinguishable on close inspection. The dyes are entirely vegetable on the antique pieces: madder and cochineal for the reds, indigo for the navy and blues, isparek and pomegranate-rind for the yellows, walnut hull for the browns, with the synthetic aniline dyes essentially absent before about 1880 and only intermittently present on workshop production even after, because the named workshops maintained tighter dye-control than the village register did.</p><h2 id="the-period">The Period</h2><p>The city of Kashan sits on the<em>western edge of the Dasht-e Kavir</em>, the great central Persian salt desert, on the old caravan route between Isfahan and Tehran. The city has been a major weaving centre since at least the Safavid period of the sixteenth century, when it produced the silk-warp court carpets that the V&amp;A&rsquo;s<em>Ardabil carpet</em> — the most famous Persian carpet in any institutional collection, signed by Maqsud of Kashan and dated 1539-40 — is the documentary touchstone for. The nineteenth-century Kashan production that this post is concerned with is the<em>Qajar-period revival</em> of that older tradition, beginning in the 1860s-1870s as the Persian rug trade re-established its export connections to Europe and the United States. The three tiers the post is about to lay out are not a clean succession — the Mohtasham apex (roughly the 1870s through the 1900s) and the Manchester-yarn production (roughly 1890 through 1930) overlap substantially in time, and the standard nineteenth-century Kashan production runs through both — but the apex tier had largely passed by the time the Manchester-yarn production reached its peak in the 1910s and 1920s, and the antique period closes with the Manchester register on its way out.</p><figure><img src="/images/posts/kashan/antecedent.png" alt="The Ardabil carpet, 1539-40, signed by Maqsud of Kashan — the 16th-century Safavid silk-warp Kashan court carpet now in the Victoria and Albert Museum"><figcaption><p>The Ardabil carpet, signed by Maqsud of Kashan and dated 1539-40 — the late-Safavid silk-warp Kashan court carpet from which the nineteenth-century Kashan revival descended. The rug is now in the Victoria and Albert Museum and is the single most-documented antique Persian carpet in any institutional collection; its central-medallion-and-floral-arabesque vocabulary is the direct ancestor of the nineteenth-century Mohtasham composition, and the silk warp of the Mohtasham apex sub-type is the deliberate revival of the Safavid foundation.</p></figcaption></figure><p>The load-bearing collector-distinction within the Kashan label, and the practical thing this post most wants the reader to take away, is the three-tier sub-attribution that the dealer trade has applied broadly across the same body of rugs:<em>Mohtasham Kashan, standard nineteenth-century Kashan, and Manchester Kashan.</em> These are not three separate workshops or three separate provenances — they are three price-grade attributions within the broader Kashan production, and the price spread between them is substantial enough that learning to read which tier a given Kashan belongs to is most of the work of buying one.<strong>Mohtasham Kashan</strong> is the apex sub-type produced in the workshop of Hajji Mollah Mohammad Hassan Mohtasham (or in the closely-associated late-nineteenth-century Kashan production that the dealer trade now classes in the Mohtasham register) — silk warp on the finest pieces, sometimes signed in a small cartouche at the top of the field, knot density above three hundred KPSI, and the apex Persian rug of the entire late-nineteenth-century period; documented Mohtasham-marked Kashan pieces have commanded auction prices in the multi-million-dollar range for the museum-grade examples. What the contemporary trade calls<em>Mohtasham</em> is, in strict attribution, a stylistic register applied to several closely-related late-nineteenth-century Kashan workshops rather than the documented output of a single named master, and the brand-versus-workshop ambiguity is itself part of what the connoisseur is reading for: the signature cartouche is rare even on agreed-Mohtasham pieces, the master&rsquo;s biography is thinly documented, and the identification is in practice a triangulation across foundation, palette, drawing, and finish rather than a confident workshop attribution.<strong>Standard nineteenth-century Kashan</strong> is the broader Qajar-period workshop production from the same city at the same period — wine-red ground, fine drawing, two hundred to two hundred and fifty KPSI on the typical pieces, but without the silk-warp foundation, the Mohtasham signature, or the apex condition that the upper tier commands.<strong>Manchester Kashan</strong> is the late-nineteenth- and early-twentieth-century production (roughly 1890 to 1930) made specifically for the American and European export markets using merino yarn spun in Manchester, England, then shipped to Iran for weaving — distinguishable by the Manchester wool&rsquo;s particular sheen and lanolin signature, generally a slightly less-saturated palette, and a price and quality position intermediate between the Mohtasham and the standard registers. The Kashan dealer label, in nineteenth-and-twentieth-century commercial practice, was applied across all three tiers without much distinction, and one will still encounter Mohtasham-grade pieces sold as ordinary Kashan and ordinary Kashan pieces sold as Mohtasham. Reading the tier rather than the label is the principal Kashan practical attention.</p><figure><img src="/images/posts/kashan/portfolio-page.png" alt="A page from a Victorian connoisseur's portfolio on the central Persian court workshops — district map locating Kashan, Isfahan, Qum, and Sarouk, archetype rug drawings for the four"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the central Persian court workshops — the district map locating Kashan on the western edge of the Dasht-e Kavir, with Isfahan to the south, Qum to the north, and Sarouk to the southwest, the four cities that together produced the central Persian court tradition. The archetype rug drawings at the bottom show the principal compositions: the Kashan central medallion (wine-red ground, palmette-and-cloud-band vocabulary), the Isfahan central medallion (ivory-and-indigo ground), the Qum silk prayer-rug (twentieth-century derivative), and the Sarouk floral spray (deep wine-red, allover floral composition rather than central medallion).</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four types stand near enough to Kashan that the beginner confuses them with it, and distinguishing them is most of the work of reading the central Persian court district.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/kashan/sibling-isfahan.png" alt="An Isfahan rug — central Persian court tradition on pale ivory ground with indigo central medallion, silk-warp foundation, the Shah Abbas-period court tradition rather than the Kashan revival" loading="lazy"/><figcaption>Isfahan<em>— the Safavid court rival</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/kashan/sibling-qum.png" alt="A Qum silk prayer-rug — twentieth-century workshop production from north of Kashan, characterised by silk pile, prayer-rug niche composition, and derivative court vocabulary" loading="lazy"/><figcaption>Qum<em>— the 20th-c silk prayer-rug</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/kashan/sibling-sarouk.png" alt="A Sarouk rug — central Persian workshop production for the American export market, deep wine-red ground, allover floral-spray composition rather than central medallion" loading="lazy"/><figcaption>Sarouk<em>— the American-market floral-spray</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/kashan/sibling-tabriz.png" alt="A Tabriz city-workshop rug — northwestern city workshop counterpart to Kashan, frequently pale-ivory ground in the Hadji Jalili variant, fine knot at distinct district provenance" loading="lazy"/><figcaption>Tabriz<em>— the NW city workshop counterpart</em></figcaption></figure></div><figcaption>Four types most often confused with Kashan, drawn for comparison.</figcaption></figure><p>An<em>Isfahan</em> is the Safavid court rival from the city south of Kashan, on the same central Persian plateau and in the same court-workshop tradition. The Isfahan and the Kashan share a great deal of vocabulary — both are central-medallion compositions, both descend from the Safavid silk-warp court carpets of the sixteenth century, both use fine asymmetric knots at high density — but the Isfahan palette runs to<em>pale ivory ground with indigo central medallion</em> rather than the deep wine-red of the Kashan, and the Isfahan workshop tradition descends specifically from the Shah Abbas-period royal carpets of the early seventeenth century rather than the Maqsud-of-Kashan tradition. The rule of thumb: deep wine-red ground with floral central medallion is Kashan; pale ivory ground with indigo central medallion is Isfahan.</p><p>A<em>Qum</em> is the twentieth-century silk prayer-rug workshop production from the city north of Kashan, and it is derivative of the Kashan and Isfahan court tradition rather than coordinate with it. Qum production began in the 1920s and 1930s, when weavers from Kashan began arriving in Qum and establishing workshops there — well after the antique period the prior siblings occupy, and the surviving body is overwhelmingly<em>silk-pile prayer rugs</em> (a niche-composition reading the<em>mihrab</em> arch of a mosque, rather than a central medallion) and small workshop carpets of derivative design. The Qum is collectible as twentieth-century work but it is not antique in the period sense the rug arc has been treating. The rule of thumb: nineteenth-century wool-pile court carpet on wine-red ground is Kashan; twentieth-century silk-pile prayer-rug with niche composition is Qum.</p><p>A<em>Sarouk</em> is the central Persian workshop production made for the American export market in the late nineteenth and early twentieth century, and it is the type most often confused with Kashan because the two share the deep wine-red ground that is the central Persian palette signature. The composition is the distinguishing feature: a Sarouk runs an<em>allover floral-spray composition</em> (small detached floral elements scattered across the entire wine-red field, in a pattern the trade calls<em>American Sarouk</em> or<em>Lilihan Sarouk</em> depending on sub-region), rather than the central-medallion-and-spandrel composition of the Kashan. A great many Sarouks were further<em>re-dyed in New York</em> in the 1920s, with the original soft mauve-and-pink palette painted over in saturated wine-red to suit the American taste — a Sarouk with overly-uniform wine-red intensity is often a re-dyed piece, and reading the palette through to the original ground is one of the particular American-export-period collector educations. The rule of thumb: central medallion with palmette-and-cloud-band court vocabulary on wine-red ground is Kashan; allover detached floral-spray composition on wine-red ground is Sarouk.</p><p>A<em>Tabriz</em> is the northwestern city-workshop rug of the regional capital that the Tabriz post treated, and it sits at the structural counterpart position to Kashan within the workshop axis: Tabriz is the city workshop of the northwestern district, Kashan is the city workshop of the central Persian district, and the two are the two principal city workshops of the antique Persian production. The two often confuse the beginner because both are fine-knot designed-composition workshop productions on cotton warp. The Tabriz palette runs through the<em>pale-ivory Hadji Jalili variant</em> and a broader range of ground colours, the district is distinct (north-west versus central plateau), and the workshop traditions are independent rather than coordinate. The rule of thumb: wine-red ground with Khorasan-wool pile and central Persian floral medallion is Kashan; pale-ivory ground with Hadji Jalili palette and northwestern district provenance is Tabriz.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Kashan, when one is standing in front of a candidate rug in the dealer&rsquo;s storeroom, comes down to a short ordered checklist that the reader of the prior rug posts will find familiar in structure but adjusted for the workshop register the central Persian court tradition operates in.</p><p>One looks first at the<em>knot density and the foundation.</em> For Kashan, knot density is the principal threshold rather than (as it was for the village-register posts) the medallion drawing. A Kashan runs<em>two hundred KPSI or finer</em>, and a candidate rug below that threshold is almost certainly not a Kashan regardless of what the dealer label says — the central Persian court vocabulary requires the fine knot to draw at all. Within the Kashan range, three hundred KPSI and above on a silk warp moves the piece into Mohtasham consideration; two hundred to two hundred and fifty on a cotton warp is the standard nineteenth-century register; a slightly looser knot on a particular wool grade is the Manchester Kashan range. The foundation reads as a single number, and the number settles the broad attribution at a single inspection.</p><p>One looks next at the<em>ground colour and the dye character.</em> Kashan ground is deep wine-red on the antique pieces, saturated and slowly tonally-shifting rather than faded toward cream the way the village register oxidised. A rug that reads as a pale or faded ground is either not a Kashan, or is a piece that has been chemically washed for the decorator market — neither is what one is looking for. Within the wine-red range, the Mohtasham-register pieces show a particular jewel-toned depth — drawn from the documented use of both madder and cochineal across the Kashan workshops&rsquo; red palette — that is itself one of the diagnostic features of the apex tier; the standard register runs a slightly more straightforward madder; the Manchester Kashan ground is often a slightly less-saturated wine-red, reflecting the different wool source. The palette is the second reading, and it triangulates the tier as well as the type.</p><p>One looks at the<em>medallion vocabulary and the workshop regularity.</em> The Kashan medallion is floral — palmettes, cloud-bands, fine arabesques, central rosette — drawn from a workshop master-cartoon to the regularity that only a workshop tradition produces. The curve of each petal matches its mirror across the central axis; the proportions of the medallion to the field are calibrated rather than felt; the inner-guard and outer-guard borders carry their own coordinated vocabulary at appropriate scale. A candidate rug whose medallion shows the village hand — irregular stepping, varying proportions, individual weaver&rsquo;s improvisation — is not a Kashan, whatever the dealer label claims. The workshop regularity is the third reading, and it confirms (or contradicts) the first two.</p><p>And one looks at the<em>three-tier reading.</em> Once the broad Kashan attribution is established at the prior three steps, the practical question is whether one is looking at a Mohtasham, a standard nineteenth-century Kashan, or a Manchester Kashan, because the price spread between the tiers is substantial. The Mohtasham reading rests on the silk warp (visible at the cut edge), the knot density at the very fine end (three hundred KPSI and above), the<em>purple silk side-cord finish</em> (the<em>kor</em> — a binding wrap of purple silk applied to the rug&rsquo;s two long edges as a selvedge, one of the most reliable Mohtasham diagnostics and in practice what an experienced dealer reads first because it survives where the signature does not), the Mohtasham signature cartouche if present (a small woven inscription at the top of the field, often partly obscured by the border and absent altogether on most pieces the trade calls Mohtasham), and the apex wool-and-dye quality across the whole rug. The Manchester reading rests on the wool&rsquo;s particular lanolin-and-grade signature (different from the Khorasan wool of the standard register), a typically slightly later weave (post-1900), and the dating evidence of the wear pattern and the back. The standard register is the residual — broadly Kashan in vocabulary, palette, and knot, without the apex evidence of either of the bracketing tiers. The dealer label says<em>Kashan</em> across all three; the buyer&rsquo;s reading is to determine which tier, and the price negotiation is downstream of the determination.</p><p>The next post in the rug arc will be either<em>Bidjar</em> — to open the Kurdish northwestern Persian tradition with its dark wine and dark navy palette and its famously heavy-handle construction, the structural opposite to the fine-knot court register Kashan establishes — or<em>Isfahan</em> — to continue the central Persian court arc with the Safavid court rival that Kashan&rsquo;s sibling-plate referenced. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>English Chippendale</title><link>https://mtclinton.com/posts/chippendale/</link><pubDate>Sun, 17 May 2026 20:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/chippendale/</guid><category>antiques</category><description>Fourth per-subject post in Reading the Period Cabinet — the Anglophone flagship of the eighteenth-century Rococo tradition, Thomas Chippendale's 1754 'Director' as documentary anchor, the cross-Channel translation of French Louis XV vocabulary into carved mahogany rather than veneer-and-ormolu, the ball-and-claw foot as canonical form-signature, and the attribution-complication between Chippendale's own workshop and the broader London cabinet-trade that worked in the Director's register.</description><content:encoded>&lt;![CDATA[<p>The three prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a>,<a href="/posts/louis-xvi/">Louis XVI</a>, and<a href="/posts/biedermeier/">Biedermeier</a> — described one diagonal across the eighteenth- and early-nineteenth-century European furniture landscape: the French royal tradition from rocaille curve through neoclassical straight line, and the Continental bourgeois reaction that displaced both. What that diagonal does not yet contain is the<em>Anglophone</em> response to the same rococo impulse — the body of work that English cabinet-makers produced in parallel to the French royal tradition, drawing on the same Parisian sources but executing them in a different material register for a different patron class. That body of work has a single common name:<em>Chippendale</em>. The post that follows is what the Louis XV post pointed toward across the Channel.</p><p>English Chippendale is, in the strict accounting, the Anglophone translation of the French rococo into the cabinet-making vocabulary of mid-eighteenth-century London. Where the Parisian<em>ébénistes</em> worked the rococo in marquetry-veneered exotic woods with gilt-bronze ormolu mounts, the London cabinet-makers worked it in<em>solid mahogany</em> with carved-rather-than-applied ornament. The same impulse — the broken symmetry, the asymmetric scroll, the rocaille shell, the cabriole leg — passed through the Channel and arrived in a different language. Where Louis XV addressed the French royal court, Chippendale addressed the English country gentleman; where Louis XV ornamented through applied gilt-bronze, Chippendale ornamented through carved wood; where Louis XV was anonymous workshop production within the<em>Jurande des Menuisiers-Ébénistes</em>, Chippendale was signed-and-published from the start. The two styles are siblings of the same period, but the difference in material register is most of what one needs to know to distinguish them at three paces.</p><p>This is the fourth post in<em>Reading the Period Cabinet,</em> and the first to leave the Continental tradition for the English one. It treats Chippendale fourth not because Chippendale is less important than the Continental styles already covered — it is in fact more documentarily anchored than any of them — but because the Louis XV/XVI pair had to be in place before the cross-Channel translation could be read against its source.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Chippendale piece, for the purposes of beginning to read the style, is the<em>side chair</em> — the dining-room chair that the country-house dining suite reproduced in eight or twelve identical examples, and that the<em>Director</em> (Chippendale&rsquo;s 1754 pattern book, of which more shortly) illustrated in the greatest profusion. The chair is the form in which the Chippendale principles are most fully concentrated, and its ball-and-claw foot is the single most-recognisable Chippendale signature.</p><p>A canonical Chippendale side chair, then. It stands on four legs of the<em>cabriole</em> form — the S-curved English-and-French rococo leg, curving outward at the knee and inward at the ankle, terminating in a foot of one of two types: the<em>ball-and-claw</em> (a carved bird&rsquo;s-foot gripping a ball, the most-recognisable terminus, derived ultimately from the Chinese<em>long</em>-and-pearl motif via the late-seventeenth-century English East-India trade) or the simpler<em>paw foot</em>. At the knee of each leg, a<em>carved acanthus scroll</em> or<em>carved shell</em> provides the principal applied ornament, executed in the wood of the leg itself rather than as an applied mount. The seat is a<em>drop-in upholstered seat</em>, covered in silk damask, needlework, or — for the country registers — leather. Above the seat, the chair&rsquo;s back rises as a frame for the<em>splat</em>, which is the principal locus of ornamental work and the principal differentiator between Chippendale&rsquo;s three published registers.</p><figure><img src="/images/posts/chippendale/detail-foot.png" alt="A close detail of a Chippendale ball-and-claw foot on cabriole leg — the canonical English rococo form-signature in carved mahogany"><figcaption><p>A close detail of a Chippendale ball-and-claw foot on cabriole leg — the canonical English rococo form-signature, the carved bird&rsquo;s-foot talons gripping the ball at the leg&rsquo;s terminus. The form descends from the Chinese<em>long</em>-and-pearl motif via the English East-India trade and the Queen Anne period that preceded Chippendale, but it was the<em>Director</em> that codified it across the broader London cabinet trade. The carving is in the wood of the leg itself; this is the principle that distinguishes the English register from the French ormolu equivalent.</p></figcaption></figure><p>The Director illustrated three distinct registers, and the distinction matters for attribution. The<em>standard</em> (or French-influenced) Chippendale carries a pierced-and-carved splat in rococo vocabulary — the<em>ribbon-back</em> (carved to suggest a knotted silk ribbon, the most virtuosic of the published designs) is the apex form. The<em>Gothic Chippendale</em> splat carries pointed-arch tracery and quatrefoils in conscious quotation of medieval window-work. The<em>Chinese Chippendale</em> splat carries rectilinear fretwork in conscious quotation of Chinese architectural lattice. All three registers appeared in the Director, all three were produced by Chippendale&rsquo;s workshop and by the London cabinet-trade at large, and the three were often combined in a single country-house suite — standard Chippendale chairs alongside Gothic-Chippendale side tables alongside Chinese-Chippendale china cabinets.</p><p>The decorative apparatus, beyond the splat and the foot, has two further components. The first is the<em>carving</em> across the chair&rsquo;s other elements — the acanthus at the knees, the gadrooning along the seat-rail, the scrolled cresting at the back&rsquo;s top — all executed in the chair&rsquo;s mahogany itself rather than as applied ornament. The second is the<em>brass hardware</em>, where the form requires it: escutcheons and bail handles on the case furniture, brass-bound mouldings on the better pieces. Chippendale brass is restrained in register compared to the contemporary French ormolu — smaller in scale, simpler in casting, more obviously workmanlike. A Chippendale piece beside a Louis XV piece reads at once: the English piece is<em>carved</em>, the French piece is<em>applied</em>, and that single distinction carries most of the differentiation.</p><h2 id="the-evidence">The Evidence</h2><p>The wood, first, and the wood is most of what one is reading for.<em>Solid mahogany</em> is the canonical Chippendale material, with the better pieces using<em>Cuban mahogany</em> (the densest and most figured of the period&rsquo;s tropical-American mahogany supply, imported through London via the West India trade) and the country-grade work using<em>Honduras</em> or<em>Jamaican</em> mahogany. The mahogany is<em>solid</em> rather than veneered — Chippendale chairs are carved from solid mahogany blocks, and the carving exposes the wood&rsquo;s figure at every cut. This is the structural enabling condition for the carved-rather-than-applied ornament: solid mahogany takes deep carving without splintering, where the French walnut-veneered carcase work could not. The mahogany is also what gives the Chippendale piece its characteristic deep red-brown patina, the colour that two and a half centuries of furniture wax and natural oxidation produce on Cuban mahogany.</p><figure><img src="/images/posts/chippendale/detail-carving.png" alt="A close detail of Chippendale carved acanthus and shell ornament on a chair knee — carved in solid mahogany"><figcaption><p>A close detail of Chippendale carved ornament on a chair knee — the acanthus scroll and shell motif carved in the solid mahogany of the cabriole leg itself, not applied as a separate mount. The carved-not-applied principle distinguishes English Chippendale from the contemporary French ormolu tradition at the most fundamental material register, and is most of what one needs to read at the leg to settle the broad attribution.</p></figcaption></figure><p>The construction, second. Hand-cut dovetails of period irregularity on the case furniture, the dovetails proportioned and spaced by the workshop hand rather than a machine. Period brass hardware where the form requires it, cast and chased by the contemporary London brass-trade — Gilbert Wright, Charles Hoole, and the broader brass-founders&rsquo; shops that supplied the major cabinet workshops. The seat rails and the chair&rsquo;s structural members should be examined for evidence of period tools and hand-finishing rather than any modern restoration. Original upholstery is essentially impossible to find intact on antique Chippendale seating — the upholstery wore out within a generation and was replaced — and a Chippendale chair with original upholstery is a rare and substantial provenance event.</p><figure><img src="/images/posts/chippendale/detail-hardware.png" alt="A close detail of Chippendale brass hardware — rococo-cartouche escutcheon and bail handle on a mahogany drawer front"><figcaption><p>A close detail of Chippendale brass hardware — the rococo-cartouche escutcheon and bail handle on a mahogany drawer front. The brass is restrained in register: smaller in scale, simpler in chasing, more obviously workmanlike than the contemporary French ormolu. This is the English hardware vocabulary the Director illustrated and that the broader London cabinet-trade then reproduced.</p></figcaption></figure><h2 id="the-period">The Period</h2><p>The Chippendale period proper runs from about 1750 to about 1780, with the documentary anchor being Thomas Chippendale&rsquo;s<em>The Gentleman and Cabinet-Maker&rsquo;s Director</em>, first published in 1754 and reissued in two subsequent editions (1755 and 1762). Chippendale himself (1718–1779) operated his workshop at 60 St. Martin&rsquo;s Lane, London, from 1753 until his death; the workshop continued under his son Thomas Chippendale the Younger until 1820. The principal documented commissions are for the great Whig country houses of the period — Harewood in Yorkshire (the largest documented ensemble), Nostell Priory, Dumfries House in Ayrshire, Burton Constable — and the surviving workshop accounts, together with the Director plates, constitute the documentary basis for modern Chippendale attribution.</p><p>The<em>Director</em> itself is the single most consequential document in English furniture history, and an account of it is what most distinguishes a Chippendale post from a post on the styles already covered. The book was published by Chippendale in 1754 by subscription, the subscribers including the major Whig peers and the broader London cabinet trade. It illustrated, across some hundred and sixty plates, the full range of Chippendale&rsquo;s workshop production — side chairs, library chairs, dining tables, dressing tables, china cabinets, library bookcases, beds, mirror frames — in all three Chippendale registers. The Director&rsquo;s principal effect was<em>not</em> to advertise Chippendale&rsquo;s own shop, though it did that too, but to<em>codify the Chippendale register</em> across the broader London cabinet trade. Most surviving pieces in the Chippendale register were not made by Chippendale&rsquo;s St. Martin&rsquo;s Lane workshop but by other London cabinet-makers (Wright and Elwick of Wakefield; Vile and Cobb; Ince and Mayhew) and by provincial workshops working from copies of the Director. The trade name &ldquo;Chippendale&rdquo; attached itself, in the nineteenth-century collector market, to the whole body of work in the Director register rather than to the narrow body of pieces produced by Chippendale&rsquo;s own shop. This is the attribution-complication every serious collector eventually meets: a documented Chippendale-shop piece commands a substantial premium over an equivalent piece in the same register from another workshop, but the distinction at first inspection is not always available. The Director plates are the principal reference tool; the workshop records are the second-order evidence; the carving&rsquo;s hand and the construction&rsquo;s quality are what the connoisseur reads at close range when neither is available.</p><figure><img src="/images/posts/chippendale/antecedent.png" alt="A Queen Anne English walnut chair (c. 1720–1740) — the predecessor English style, with cabriole leg, pad foot, and undecorated vase-shaped splat"><figcaption><p>A Queen Anne English walnut chair of about 1720–1740 — the predecessor English style that the Chippendale period elaborated. The cabriole leg is present, but with a<em>pad foot</em> rather than ball-and-claw; the splat is<em>vase-shaped</em> and undecorated rather than pierced-and-carved; the wood is<em>walnut</em> rather than mahogany. The Chippendale period inherited the Queen Anne form and added the rococo ornament, the carved foot, and the mahogany substitution that became the English mid-eighteenth-century cabinet vocabulary.</p></figcaption></figure><figure><img src="/images/posts/chippendale/pattern-book-page.png" alt="A page from Chippendale's 1754 Director — engraved plates of the ribbon-back chair, library bookcase, and china cabinet with Gothic glazing"><figcaption><p>A page from Thomas Chippendale&rsquo;s 1754<em>The Gentleman and Cabinet-Maker&rsquo;s Director</em> — engraved plates of the canonical forms across the three registers: the ribbon-back side chair (standard rococo, the workshop&rsquo;s most-virtuosic chair design), the library bookcase with broken-pediment top, the china cabinet with Gothic glazing (the Gothic-Chippendale variant). The Director ran to some hundred and sixty plates across its three editions, and is the principal documentary source for the Chippendale register that the broader London cabinet-trade then reproduced.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four styles stand near enough to Chippendale that the beginner confuses them with it, and distinguishing them is most of the work of reading mid-eighteenth-century English-and-related furniture.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/chippendale/sibling-louis-xv.png" alt="A Louis XV French commode — bombé case, floral marquetry in exotic woods, elaborate gilt-bronze ormolu mounts; the French rococo that English Chippendale translated into carved mahogany" loading="lazy"/><figcaption>Louis XV<em>— the French rococo source across the Channel</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/chippendale/sibling-hepplewhite.png" alt="A Hepplewhite English chair — pale satinwood, shield-back form, painted-and-inlaid neoclassical decoration; the English neoclassical succession to Chippendale rococo" loading="lazy"/><figcaption>Hepplewhite<em>— the English neoclassical successor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/chippendale/sibling-queen-anne.png" alt="A Queen Anne English walnut chair — the early-Georgian predecessor with simpler cabriole leg and pad foot, walnut not mahogany, undecorated vase splat" loading="lazy"/><figcaption>Queen Anne English<em>— the early-Georgian predecessor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/chippendale/sibling-american-chippendale.png" alt="An American Chippendale chair — Philadelphia or Newport adaptation of the English Chippendale vocabulary in regional American workshops with provincial carving" loading="lazy"/><figcaption>American Chippendale<em>— the colonial American adaptation</em></figcaption></figure></div><figcaption>Four styles most often confused with English Chippendale, drawn for comparison.</figcaption></figure><p>A<em>Louis XV</em> is the French royal rococo source the English Chippendale translated across the Channel. The French piece is veneered (not solid mahogany), ornamented with applied gilt-bronze ormolu (not carved wood), and produced by workshop-anonymous<em>ébénistes</em> under the<em>Jurande</em> (not a single named master with a published pattern book). The rule of thumb: carved mahogany with restrained brass is Chippendale; veneered exotic wood with elaborate gilt-bronze ormolu is Louis XV.</p><p>A<em>Hepplewhite</em> is the English neoclassical succession after about 1780, with the rococo cabriole-and-ball-and-claw replaced by the straight tapered leg with spade foot, and the carved mahogany replaced by pale painted-and-inlaid satinwood. The rule of thumb: cabriole leg with carved mahogany is Chippendale; straight tapered leg with painted satinwood is Hepplewhite.</p><p>A<em>Queen Anne English</em> is the predecessor English style of about 1700–1740, with a simpler cabriole leg terminating in a pad foot rather than ball-and-claw, a vase-shaped undecorated splat rather than the pierced-and-carved Chippendale splat, and walnut rather than mahogany as the principal wood. The rule of thumb: walnut with pad foot is Queen Anne; mahogany with ball-and-claw is Chippendale.</p><p>An<em>American Chippendale</em> is the colonial American adaptation, produced principally in Philadelphia (the Quaker workshops under Thomas Affleck and William Savery) and Newport (the Townsend-Goddard workshop family). American Chippendale uses the same vocabulary as the English original but executes it in regional American mahogany with slightly different carving conventions — the Philadelphia carved shell, the Newport block-and-shell case-furniture variant — and provincial-workshop construction. The rule of thumb: English Chippendale with London workshop attribution is the original; same vocabulary with colonial American attribution is American Chippendale.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>One looks first at the<em>wood</em>, and the wood settles the broad attribution at three paces. Solid mahogany with the deep red-brown Cuban-mahogany patina is Chippendale; pale satinwood with inlay is Hepplewhite or Sheraton; walnut with the lighter Queen-Anne patina is the predecessor; veneered exotic woods with applied gilt-bronze are the French Continental tradition. The single material distinction carries most of the differentiation across the Anglophone and Continental eighteenth-century registers.</p><p>One looks next at the<em>foot and the leg</em>. Ball-and-claw on cabriole is canonical Chippendale; pad foot on cabriole is Queen Anne; straight tapered leg with spade foot is Hepplewhite. The leg is the second-order distinction after the wood and is what most differentiates the English period registers from one another.</p><p>One looks at the<em>splat and the carving</em>. Pierced-and-carved splat in one of the three Director registers (rococo, Gothic, Chinese) is Chippendale; undecorated vase splat is Queen Anne; shield-shaped splat with neoclassical inlay is Hepplewhite. The carving&rsquo;s hand — the depth of relief, the sharpness of the acanthus, the proportions of the ball-and-claw — distinguishes the workshop quality range from the apex Chippendale-shop piece down through the broader London trade and out to the provincial cabinet-makers.</p><p>And one looks for the<em>documentary attribution</em>. A piece documented in the Chippendale workshop accounts (Harewood, Nostell, Dumfries, Burton Constable) is the apex of the type. A piece in the Director register but undocumented to Chippendale&rsquo;s shop is in the broader Chippendale-trade category — the great majority of surviving Chippendale-register pieces are in this category, and the distinction from the documented shop pieces is principally a question of price-grade and connoisseur prestige rather than of stylistic vocabulary. The Director plates are the principal reference tool; the surviving workshop records are the second-order evidence; the carving and construction are what the connoisseur reads when neither is available.</p><p>The next post in the furniture arc will be either<em>Hepplewhite</em> — to set out the English neoclassical succession after the Chippendale rococo, with the pale-satinwood variety break that the wood-tone variety table calls for — or<em>Gustavian</em>, to open the Scandinavian neoclassical tradition with its painted gris-blanc register. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Bakshaish</title><link>https://mtclinton.com/posts/bakshaish/</link><pubDate>Sun, 17 May 2026 19:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/bakshaish/</guid><category>antiques</category><description>Fourth per-subject post in Reading the Antique Rug — the older Heriz district village tradition out of which Heriz proper grew, with a cream / faded-madder ground, an archaic large-scale medallion, looser village-loom knot, and the dealer-attribution overlap with Serapi that has confused collectors for a century.</description><content:encoded>&lt;![CDATA[<p>The first three rug posts in this arc —<a href="/posts/heriz/">Heriz</a>,<a href="/posts/tabriz/">Tabriz</a>, and<a href="/posts/caucasian-kazak/">Caucasian Kazak</a> — established the two axes along which the body of antique-rug attribution operates: workshop versus village (Tabriz against Heriz), and Persian-cotton versus Caucasian-wool (Heriz against Kazak). What the Heriz post named in passing but did not treat in detail was the older village tradition out of which the late-nineteenth-century commercial Heriz emerged, and what the Tabriz post acknowledged as the predecessor that the Tabriz workshop quietly tightened. That tradition has its own name in the dealer vocabulary, and<em>Bakshaish</em> is what one calls it. This post is what the Heriz post had to leave for another day.</p><p>Bakshaish is the antecedent. A Heriz proper of 1890 sits on a village foundation that goes back at least to the early nineteenth century, and the canonical archaic vocabulary it draws on — the large stepped polygonal medallion, the cream ground oxidised down from saturated madder, the village-loom drawing of an irregularity the commercial workshop later disciplined out — is the Bakshaish vocabulary. The rugs we now class as Heriz are the export-grade descendants of an older village register that the dealer market began separately classifying, and prizing, around the 1890s as the commercial Heriz consolidated. The northwestern Persian triangle of Heriz proper, Tabriz, and Bakshaish is, in this sense, the canonical Persian district laid out on three axes: the city workshop, the commercial-export village, and the older village antecedent. Tabriz and Heriz are done; Bakshaish completes it.</p><h2 id="the-specimen">The Specimen</h2><p>A Bakshaish that one will encounter is, in its commonest form, a substantial rug — eight feet by ten or larger is the village-loom norm, with smaller pieces (five by seven, four by six) considerably less common than in the commercial Heriz successor. The Bakshaish was woven on the same village looms that produced the later Heriz, but in the older period the village preference was for the larger format that the bourgeois Tabriz and provincial-Persian markets received well. Most surviving antique Bakshaish in good condition are in the eight-by-ten to ten-by-fourteen range.</p><p>The composition is the<em>archaic large-scale medallion</em> — a single great stepped polygonal medallion that occupies, on most pieces, between a third and half of the rug&rsquo;s total length, with the field around it rendered in a more open and less densely-ornamented register than its commercial successor. The medallion outline is stepped, the steps drawn at substantially larger scale than in the Heriz successor, and the individual weaver&rsquo;s hand is visible in the irregularities of the stepping — the angles are not quite mathematical, the proportions of the steps vary slightly from side to side, the corners do not always meet at exactly the same point. The drawing is what one would call<em>archaic</em> in the connoisseur vocabulary — older, looser, more village, more individual — and it is the principal reason the Bakshaish dealer-label retained value after the commercial Heriz took over the export trade. The Heriz proper drew the same general medallion at smaller scale, in tighter proportions, and with the irregularities mostly disciplined out. The Bakshaish drew the same vocabulary at the older scale and admitted the hand.</p><figure><img src="/images/posts/bakshaish/detail-medallion.png" alt="A close detail of a Bakshaish archaic medallion — stepped polygonal outline at large scale on cream / faded-madder ground, with visible weaver's-hand irregularity"><figcaption><p>A close detail of a Bakshaish archaic medallion — the stepped polygonal outline at the large scale that occupies a third of the rug&rsquo;s length on the canonical pieces. The cream / faded-madder ground is the principal palette signature, the result of more than a century of light-fade and oxidation on what began as a saturated madder field. The individual weaver&rsquo;s hand is visible in the irregularities of the stepping — the angles vary slightly, the proportions of the steps shift from side to side, the corners do not always meet at the same point. This is the village register the commercial Heriz tightened.</p></figcaption></figure><p>The palette is the Bakshaish&rsquo;s second principal signature, and it is what most separates the type from both its commercial-Heriz successor and the rest of the northwestern Persian district. The field is<em>cream</em>, or<em>pale faded-madder</em> — a soft pinkish or apricot cream that the rug was not woven with but that more than a century of light-fade and natural oxidation has produced from what began as a saturated madder ground. A Bakshaish of 1860 was woven with the same range of vegetable madder dye that the Heriz proper of 1890 used, but the older rug has had thirty additional years of light and use, and the natural ageing has produced the soft cream-and-apricot range that is now the type-signature. The medallion is typically deep indigo or aged indigo-blue, often itself oxidised down from a brighter starting tone. Ivory spandrels at the corners, the same general triadic colour scheme as Heriz, but the whole palette is<em>softer</em> — and the softness, like the medallion drawing, is a feature one is looking for rather than a defect.</p><h2 id="the-evidence">The Evidence</h2><p>The foundation is the structural evidence that places a Bakshaish firmly in the Persian tradition rather than the Caucasian one the Kazak post opened.<em>Cotton warp and wool weft</em>, exactly as in Heriz and Tabriz. The cotton warp at the Bakshaish village register is hand-spun rather than the more uniform machine-spun cotton that later commercial workshops adopted, and the warp shows the slight unevenness of hand-spinning at close inspection of the back. The wool weft is heavy and lanolin-rich, dyed in alternating bands of natural and indigo on most pieces — a darker line of weft is visible between every few rows of knots — which is itself a village identifier (commercial production tightened the weft to a uniform light line).</p><figure><img src="/images/posts/bakshaish/detail-border.png" alt="A close detail of a Bakshaish main border — large-scale stepped polygons or botehs at village-loom register"><figcaption><p>A close detail of a Bakshaish main border — large-scale stepped polygons or botehs drawn at the village-loom irregularity that the commercial Heriz later regularised. The motifs are visibly drawn by hand, with the proportions varying from repeat to repeat, and the border as a whole has the looser cadence of the older village register.</p></figcaption></figure><p>The knot is the<em>symmetric (Turkish) knot</em>, expected for the Azeri-Turkic weaving population of the Sahand slope, and the knot density is<em>moderate to low</em> — eighty to one hundred and ten knots per square inch is the Bakshaish range, with the better village pieces sometimes reaching one hundred and twenty but rarely higher. This is meaningfully looser than the commercial Heriz successor (which ran a hundred to a hundred and fifty), and the lower density is the structural enabling condition for the larger and looser medallion vocabulary. A Bakshaish woven at Heriz density would not give the same drawing; the village range and the village vocabulary are inseparable.</p><figure><img src="/images/posts/bakshaish/detail-foundation.png" alt="A close detail of a Bakshaish knot-back — looser symmetric knot at village density, cotton warp with hand-spun unevenness, heavy wool weft in alternating bands"><figcaption><p>A close detail of the back of a Bakshaish rug — the looser symmetric Turkish knot at village density (eighty to one hundred and ten knots per square inch), the hand-spun cotton warp with its slight unevenness visible at the cut edge, and the heavy lanolin-rich wool weft in alternating bands of natural and indigo. The commercial Heriz proper, woven at higher density on a more uniform machine-spun warp, reads as visibly cleaner and more regular at the same magnification.</p></figcaption></figure><p>The wool of the pile is the principal material signature. Bakshaish wool comes from the highland flocks of the Sahand region — the same flocks that supplied Heriz proper, but at the village register the wool was less heavily sorted and graded, and the surviving antique pieces show the considerable variation in fibre quality and lanolin content that hand-sorted village production produces. The dyes are entirely vegetable on the antique pieces: madder for the reds, indigo for the navy and blues, isparek for the yellows, walnut hull and pomegranate rind for the browns, the synthetic aniline dyes essentially absent before about 1880 and only intermittently present even after. A Bakshaish that has lived through a century and a quarter of light, use, and the slow chemistry of natural oxidation is what one is looking at, and the palette one is reading is not the palette the rug was woven with.</p><h2 id="the-period">The Period</h2><p>Bakshaish village sits on the eastern slope of<em>Mount Sahand</em>, the dormant volcanic peak that dominates the country east of Tabriz. The village is one of perhaps a dozen weaving settlements on the Sahand slope — Heriz proper, Mehraban, Ahar, Karaja, Bilverdi, Sharabian and others — that produced the broader district&rsquo;s rugs from at least the early nineteenth century onward. The Bakshaish-period production we are now collecting runs from about 1820 to about 1900, with the older end represented mostly by museum-grade pieces in major institutional collections and the surviving collectible inventory concentrated in the 1860–1895 range.<em>Pre-1860</em> Bakshaish in good condition is rare and largely museum-held;<em>1860–1880</em> is the most-prized antique register and what serious collectors are typically chasing;<em>1880–1895</em> is solid antique-grade work that the dealer trade calls Bakshaish on the looser pieces and Heriz on the tighter ones; after 1895 the commercial Heriz vocabulary had effectively taken over the district&rsquo;s production for export and the Bakshaish label was applied retrospectively to the older surviving stock.</p><figure><img src="/images/posts/bakshaish/antecedent.png" alt="A late-Safavid northwestern Persian village rug — the eighteenth-century antecedent with archaic medallion at even larger scale"><figcaption><p>A late-Safavid northwestern Persian village rug of the eighteenth century — the antecedent tradition that the nineteenth-century Bakshaish descended from. The medallion runs at even larger scale than the nineteenth-century Bakshaish version, the ground is closer to the saturated madder of the original dye before centuries of light-fade brought the antique cream, and the village-loom drawing carries the same individual hand at greater scale.</p></figcaption></figure><p>The dealer-attribution complication that has confused Bakshaish collectors for a century is the<em>Serapi</em> label, and a clear account of it is owed to the reader.<em>Serapi</em> was a late-nineteenth-century European-dealer trade name applied to the highest-quality Bakshaish and early-Heriz pieces — the term itself is a corruption of<em>Serab</em>, a town near Tabriz that the dealers conveniently associated with the rugs but that produced essentially none of them. A Serapi is, in practice, a Bakshaish or fine early-Heriz of the better wool grade and better condition, given a separate dealer label to mark its place in the upper end of the price range. The distinction between a Bakshaish and a Serapi is condition, wool grade, and dealer judgement, not provenance or vocabulary — the two trade labels are applied to the same body of rugs, and one will encounter the same canonical piece labelled either way in different dealers&rsquo; inventories. The collector vocabulary now generally treats Bakshaish as the broader category and Serapi as the upper sub-grade, but the historical usage was looser, and one is well advised to read the rug rather than the label.</p><figure><img src="/images/posts/bakshaish/portfolio-page.png" alt="A page from a Victorian connoisseur's portfolio on the Sahand district — district map with weaving villages located, archetype rug drawings showing Bakshaish, Heriz, and Serapi sub-types"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Sahand district east of Tabriz — the district map locating Bakshaish, Heriz proper, Karaja, Ahar, and the smaller villages on the slope of Mount Sahand, with three archetype rug drawings at the bottom showing the principal sub-type designs: the Bakshaish (archaic large-scale medallion), the Heriz proper (tightened commercial medallion at smaller scale), and the Serapi (the upper-grade dealer label applied to the better Bakshaish and early-Heriz pieces).</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Four types stand near enough to Bakshaish that the beginner confuses them with it, and distinguishing them is most of the work of reading the Sahand district.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/bakshaish/sibling-heriz.png" alt="A commercial Heriz rug of the 1890s — tightened medallion at smaller scale, saturated brick-red field, higher knot density, the regularised export-market version of the Bakshaish vocabulary" loading="lazy"/><figcaption>Heriz<em>— the commercial descendant</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bakshaish/sibling-serapi.png" alt="A Serapi rug — the dealer label applied to the higher-quality variant of the Bakshaish / Heriz district, same vocabulary and provenance as Bakshaish with better wool and condition" loading="lazy"/><figcaption>Serapi<em>— the upper-grade dealer label</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bakshaish/sibling-karaja.png" alt="A Karaja rug — the neighbouring village on the Sahand slope, characterised by a three-medallion vertical-stack composition rather than the single large medallion of Bakshaish" loading="lazy"/><figcaption>Karaja<em>— the neighbouring village</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/bakshaish/sibling-tabriz.png" alt="A Tabriz city-workshop rug — finer knot, designed by named master-designers rather than woven on the village loom, often on a pale-ivory ground in the Hadji Jalili variant" loading="lazy"/><figcaption>Tabriz<em>— the regional city workshop</em></figcaption></figure></div><figcaption>Four types most often confused with Bakshaish, drawn for comparison.</figcaption></figure><p>A<em>Heriz proper</em> is the late-nineteenth-century commercial export descendant of Bakshaish — same Sahand district, same village looms, same general medallion vocabulary, but tightened at every register for the European and American export trade. The rule of thumb: archaic large-scale medallion on a cream-or-faded ground is Bakshaish; tightened medium-scale medallion on a saturated brick-red ground is Heriz.</p><p>A<em>Serapi</em> is, as discussed above, the upper-grade dealer label applied to the better Bakshaish and finer early-Heriz pieces. The Serapi and the Bakshaish are not separate provenances but separate price-grade attributions of the same body of rugs. The rule of thumb: Bakshaish-vocabulary with high-grade wool and excellent condition is a Serapi; the same vocabulary with ordinary wool and ordinary wear is a Bakshaish proper.</p><p>A<em>Karaja</em> is the rug of the neighbouring Karaja village on the Sahand slope. Karaja is distinguished from Bakshaish principally by composition — Karaja&rsquo;s signature is the<em>three-medallion vertical stack</em> (three smaller medallions arranged along the rug&rsquo;s long axis, rather than the single great medallion of Bakshaish), and the Karaja palette tends to be deeper red and less faded-cream than the Bakshaish. The rule of thumb: single large medallion on cream ground is Bakshaish; three smaller medallions in vertical stack on deeper-red ground is Karaja.</p><p>A<em>Tabriz</em> is the city-workshop rug of the regional capital that the Heriz post treated and that sits at the far end of every Sahand-district comparison. Tabriz is designed by named master-designers rather than woven on the village loom, knotted at substantially finer density, and frequently on a pale-ivory ground (the Hadji Jalili variant the Tabriz post foregrounded). The rule of thumb: village-loom drawing on cream ground is Bakshaish; designed composition at fine workshop density is Tabriz.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Bakshaish, when one is standing in front of a candidate rug in the dealer&rsquo;s storeroom, comes down to a short ordered checklist that the reader of the prior rug posts will find familiar in structure.</p><p>One looks first at the<em>scale and drawing of the medallion.</em> A Bakshaish medallion occupies roughly a third of the rug&rsquo;s length, drawn at the older village scale, with the stepped outline irregular enough to show the weaver&rsquo;s hand. A Heriz successor medallion is smaller and more regularised; a Tabriz medallion is finer and more designed; a Karaja composition is the three-medallion vertical stack. The medallion settles the broad attribution at a single glance, and the rest of the checklist is confirmatory.</p><p>One looks next at the<em>ground colour and the dye character.</em> Bakshaish ground is cream or pale faded-madder, with the cream being the result of more than a century of natural light-fade and oxidation on what began as saturated madder rather than the original woven palette. A rug that looks like it was<em>woven</em> cream is probably either a commercial modern reproduction or a piece that was bleached for the decorator market — neither is what one is looking for. The reds and indigos within the field should themselves show the soft tones of natural ageing rather than the harder saturation of younger pieces.</p><p>One looks at the<em>knot density and the foundation.</em> Bakshaish runs eighty to a hundred and ten knots per square inch, on a hand-spun cotton warp and a heavy lanolin-rich wool weft. The looser knot is the structural enabling condition for the village-scale medallion. A Bakshaish-vocabulary rug at Heriz density (over a hundred and twenty knots per square inch) is more likely a high-quality early-Heriz mis-attributed as Bakshaish than a genuinely fine village piece — in which case it is what the trade would have called a Serapi.</p><p>And one looks for the<em>age.</em> A genuine antique Bakshaish is a century and a quarter old at the youngest end of the range, and the wool, the dyes, the foundation, and the wear should all read as having lived through that long span. Late-twentieth-century reproductions in the Bakshaish manner are now a substantial commercial category, made specifically for the decorator market that prizes the soft palette and archaic drawing without commitment to the antique price, and learning to distinguish the antique cream-and-faded-madder palette from the chemically-washed modern equivalent is one of the rug-collector&rsquo;s particular educations. The wool, the back of the rug, and the small unevennesses of hand-spun warp and hand-mixed dye are the principal evidence; the front of the rug alone is not.</p><p>The next post in the rug arc will be either<em>Kashan</em> — to open the central Persian court workshop tradition with its deep wine-red ground and its dense court-workshop vocabulary, the urban counterpoint to the Bakshaish village register — or one of the eastern Caucasian types (most likely<em>Shirvan</em>), which would extend the Caucasian region opened by the Kazak post into the dark-navy small-medallion eastern sub-tradition. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>The Three-Year Lab</title><link>https://mtclinton.com/posts/the-three-year-lab/</link><pubDate>Sun, 17 May 2026 12:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-three-year-lab/</guid><category>ai</category><description>xAI existed as a standalone frontier lab for thirty-one months — from its July 2023 founding to its February 2026 absorption into SpaceX, in what was at the time the largest merger of any kind in the recorded history of corporate consolidation. A connoisseur reading of what the lab was, of what its transformation into a SpaceX division means, and of what both register about the AI lab landscape of mid-2026.</description><content:encoded>&lt;![CDATA[<p>The frontier AI lab that existed as xAI for three years — founded in July 2023, building the largest single-site GPU cluster in Memphis Tennessee through 2024 and 2025, shipping the Grok-1 through Grok-4 model family from late 2023 through July of 2025, raising five rounds of capital that took its private valuation from twenty-four billion dollars in May 2024 to two hundred and thirty billion at its January 2026 Series E — was acquired on the second of February 2026 by<em>SpaceX,</em> the spaceflight company that the same founder had been running since 2002. The transaction was reported at one and a quarter trillion dollars, and was the largest merger of any kind in the recorded history of corporate consolidation. By the end of March, all eleven of xAI&rsquo;s original co-founders had departed. The lab now operates as a SpaceX division, with the stated objective of integrating xAI&rsquo;s terrestrial compute with SpaceX&rsquo;s orbital launch capacity in the long-term programme that SpaceX has called<em>Project Suncatcher.</em></p><p>What the transformation means — what it tells us about what an AI lab actually was, given the particular shape this one took on its way to ceasing to be one — is the substance of this post. It is not a forecast of where the integrated xAI-inside-SpaceX will go next; the forecast question is a different exercise and a more speculative one. This is the connoisseur reading of the closed three-year arc itself, of the structural transformation that closed it, and of what both register about the AI lab landscape of mid-2026.</p><h2 id="the-three-year-lab">The Three-Year Lab</h2><p>xAI as a standalone frontier lab ran from July 2023 to February 2026: thirty-one months from founding to absorption. The compactness of the arc is one of the readable features. The other three American frontier labs at the moment of xAI&rsquo;s founding — OpenAI (founded 2015), Anthropic (2021), and the AI organisation that became Google DeepMind through the 2014 acquisition (originally founded 2010) — had each existed for substantially longer than thirty-one months at their respective frontier moments. xAI is the shortest-arc standalone frontier lab in the contemporary record.</p><p>The lab&rsquo;s principal bet through those thirty-one months was<em>compute scale rapidly deployed against a small workforce.</em> The Memphis cluster, named<em>Colossus,</em> broke ground in mid-2024 and operated at a hundred thousand H100 GPUs by the end of that year. By the January 2026 Series E, the same site had grown to roughly five hundred and fifty-five thousand GPUs across the H100, H200, and GB200 generations, drawing two gigawatts of power — at the moment of the merger announcement, the largest single-site AI compute cluster in operation by a substantial margin. The workforce at the merger was on the order of four to five thousand, with around three thousand of those at the Memphis site, but the per-employee compute spend was the highest of any frontier lab by an order of magnitude. xAI was structurally a<em>compute-first</em> lab: the bet was that scale-and-infrastructure would yield differentiated capability, and the lab built the cluster and the workforce on that bet, in that order.</p><p>The Grok product line shipped on a faster release cadence than any of the other frontier labs. Grok-1 in November 2023, at three hundred and fourteen billion parameters in a mixture-of-experts arrangement, released with open weights — the lab&rsquo;s original commitment to open-weight foundation. Grok-2 in August 2024, with its weights released the following March. Grok-3 in February 2025. Grok-4 in July 2025, reaching frontier-competitive benchmarks at release (15.9 per cent on ARC-AGI V2, then the leading closed-model position). A Grok-4.20 beta from February 2026, and a Grok-5 release anticipated in the second or third quarter of this year. Each Grok release was integrated with<em>X,</em> the social media platform Musk had acquired in October 2022 — Grok served as the default chatbot inside X, drew on the platform&rsquo;s real-time data feed as a structural advantage no other frontier lab could match, and benefitted from the audience the platform&rsquo;s premium subscriptions provided. The X integration was the lab&rsquo;s most-distinctive competitive advantage over the period and remains, in the post-merger organisation, the feature that most distinguishes the xAI lineage from the rest of the frontier labs.</p><p>The funding arc tells the lab&rsquo;s story at one remove from the technical bets. Series B in May 2024 raised six billion dollars at a twenty-four-billion-dollar valuation, closed with a small named-investor list rather than the institutional syndicate the other frontier labs had been assembling. Series C in December 2024 raised a further six billion at fifty billion. A July 2025 hybrid raise of ten billion (five debt, five equity) closed at approximately two hundred billion. The January 2026 Series E raised twenty billion at two hundred and thirty billion, led by Nvidia and Cisco — the round that, by retrospective inspection, was the staging for the merger announcement six weeks later. Across thirty-one months the lab&rsquo;s private valuation had risen by a factor of just under ten, on six billion dollars of cumulative dilutive funding and a substantial Musk personal contribution at the founding round.</p><h2 id="the-merger">The Merger</h2><p>The structural transformation that closed the lab&rsquo;s standalone existence was announced on the second of February 2026. SpaceX acquired xAI at a stated valuation of one and a quarter trillion dollars — the largest merger of any kind in the recorded history of corporate consolidation, at a price that exceeded the entire market capitalisation of all but a handful of US public companies. The stated objective was<em>Project Suncatcher,</em> a long-term programme to deploy compute capacity in low Earth orbit. SpaceX&rsquo;s January 2026 FCC filing requested authorisation for up to one million compute-capable satellites, which the company projected would generate a hundred gigawatts of AI compute capacity at full deployment — a figure equivalent, by the filing&rsquo;s own arithmetic, to roughly twenty per cent of current US electrical consumption dedicated entirely to artificial intelligence. Pilot on-orbit compute hardware is planned for the Starlink V3 buses through 2026; the first dedicated Suncatcher prototype satellites are targeted for 2027.</p><p>By the end of March 2026, all eleven of xAI&rsquo;s original co-founders had departed the combined organisation. The departures were spread across the post-merger weeks in a manner that read as planned-and-sequential rather than abrupt-and-reactive — the kind of staged exit one sees when the acquirer has negotiated retention windows for legal-and-handover purposes and the legacy team has chosen, individually rather than collectively, to take the windows and leave. The xAI brand has been retained as the AI division inside SpaceX, but the operational integration is substantial: the Memphis Colossus cluster now reports to a SpaceX-level infrastructure executive, the Grok product line continues to ship from the same teams but under different reporting lines, and the public-facing register of the AI work has moved from xAI&rsquo;s own X account into the broader SpaceX communications apparatus.</p><h2 id="what-this-means">What This Means</h2><p>Three structural readings of the transformation present themselves, none of them mutually exclusive.</p><p>The first is the<em>compute-as-infrastructure</em> reading. xAI&rsquo;s principal bet through its three-year arc was always that compute-and-infrastructure would matter more than research-and-talent at the frontier. The merger with SpaceX is consistent with that bet. SpaceX is, at its operational core, an infrastructure company — it builds and operates large complex industrial systems at unusual scale (the Falcon 9 reuse system, the Starlink constellation now at six thousand satellites and growing, the Starbase production complex). Folding the AI lab into SpaceX is folding a compute-and-infrastructure operation into a larger compute-and-infrastructure operation that has been doing such work for two decades and knows what it is. If the compute-first thesis is correct about the AI frontier going forward, the merger is the structural move that makes the thesis operational at SpaceX&rsquo;s scale; if the compute-first thesis is wrong, the merger is the move that locks in the wrong bet at the largest possible scale.</p><p>The second is the<em>consolidation</em> reading. Musk has now placed his three principal AI-related organisations — Tesla AI (inside Tesla, the automotive and full-self-driving AI), xAI (now inside SpaceX, the frontier foundation-model AI), and the Neuralink brain-machine interface programme — under operational arrangements that share Musk&rsquo;s personal attention across the three companies he controls. The merger consolidates the AI work into a structure Musk can manage as a single founder-controlled portfolio. The other three American frontier labs are now the only frontier labs<em>not</em> under a single individual&rsquo;s personal control: OpenAI is governed by an institutional board and the Microsoft partnership, Anthropic by its Long-Term Benefit Trust and the Amazon-Google partnerships, DeepMind by Google&rsquo;s corporate structure. The May 2026 jury dismissal of Musk&rsquo;s 2024 lawsuit against OpenAI and Sam Altman, decided in an Oakland courtroom yesterday after roughly ninety minutes of deliberation, closed the founding-genealogy dispute that had shaped the relationship between the two labs for nearly a decade; it also coincided with xAI&rsquo;s transformation into the AI lab most controlled by a single individual at the same moment that it stopped being a standalone lab at all.</p><p>The third is the<em>end-of-the-standalone-lab</em> reading, which is the more speculative but the more historically interesting. xAI is the first frontier AI lab to be acquired by another company under common founder ownership in the contemporary period. DeepMind was acquired by Google in 2014, but that acquisition predated the contemporary frontier-lab moment and created the<em>standalone-lab-inside-corporate-affiliate</em> register that subsequent labs would later assume; the xAI absorption into SpaceX is the inverse move, ending a standalone existence rather than creating one. Whether the move generalises — whether OpenAI eventually merges into Microsoft, whether Anthropic merges into Amazon, whether the standalone frontier lab as a corporate form turns out to have been a transitional structure rather than a durable one — is the open question the merger raises. The DeepMind-in-Google model may be the future. The Anthropic-with-Long-Term-Benefit-Trust model may also be the future. The standalone-frontier-lab-with-named-institutional-investors model that OpenAI and Anthropic share through their current corporate structures may turn out to have been a transitional form between the academic-lab era and the corporate-division era. The merger does not settle the question, but it raises it in a way no prior corporate move in the field has.</p><h2 id="what-it-is-not">What It Is Not</h2><p>Three frontier labs sit near enough to xAI that the comparisons sharpen what xAI structurally was and what its transformation means.</p><p>xAI was not<em>OpenAI</em> in either its standalone or its post-merger register. The two labs share a founding genealogy — Musk co-founded OpenAI in 2015, departed the board in February 2018 after his proposed merger of OpenAI with Tesla was declined, and founded xAI five years later — but OpenAI maintained institutional-board governance, multi-billion-dollar hyperscaler partnership with Microsoft, and a public-facing register independent of any single founder throughout xAI&rsquo;s standalone existence. The eighteenth of May verdict in Musk&rsquo;s lawsuit closed the formal dispute over what the 2018 departure had been about, with the jury finding Musk&rsquo;s claims barred by the statute of limitations and concluding that the founding-genealogy disagreement was no longer legally actionable in 2024 or 2026. The rule of thumb: institutional-board governance with hyperscaler partnership is OpenAI; founder-controlled with corporate-affiliate absorption is now xAI.</p><p>xAI was not<em>Anthropic.</em> Anthropic maintained its standalone frontier-lab register throughout xAI&rsquo;s three-year arc, governed by the Long-Term Benefit Trust and the dual-class share structure designed to entrench safety-and-alignment as a controlling concern against any single commercial pressure. Anthropic&rsquo;s relationships with Amazon and with Google&rsquo;s cloud infrastructure remain partnerships rather than consolidations. The two labs occupied opposite positions on the founder-control axis at every point in xAI&rsquo;s existence: Anthropic was deliberately structured to be founder-independent on the safety register; xAI was structurally founder-controlled, and is now corporate-affiliate-controlled by a SpaceX in which the same founder retains the largest individual stake. The rule of thumb: founder-independent with safety-trust governance is Anthropic; founder-controlled with corporate-affiliate absorption is xAI.</p><p>xAI was not<em>Google DeepMind.</em> DeepMind was acquired by Google in 2014, eleven years before xAI&rsquo;s founding, and the DeepMind-inside-Google arrangement was the original<em>standalone-lab-acquired-by-corporate-affiliate</em> move in the contemporary AI period. The xAI-inside-SpaceX move is the second iteration of that broader pattern in the same field, but the differences are significant. DeepMind retained a research-first register inside Google, with a long pre-LLM history of academic-style publication and basic research that the xAI-inside-SpaceX integration is not structured to preserve in the same form. The Google-DeepMind acquisition was at a reported four hundred to six hundred million dollars; the SpaceX-xAI deal was at one and a quarter trillion. The 2014 acquisition was into a corporate parent built around search-and-advertising consumer products; the 2026 acquisition was into a parent built around launch-and-infrastructure industrial systems. The rule of thumb: research-first absorption into a search-and-advertising company in 2014 is DeepMind; compute-first absorption into a spaceflight company in 2026 is xAI.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of reading the xAI-inside-SpaceX organisation, going forward, comes down to a short ordered checklist.</p><p>One looks first at the<em>Memphis cluster&rsquo;s operational evolution</em> under SpaceX management. The cluster was xAI&rsquo;s principal bet through its standalone existence; whether SpaceX continues the buildout to the previously-targeted million-GPU operational scale on the prior schedule, accelerates it, or slows it in favour of Suncatcher&rsquo;s orbital-data-centre programme will be one of the most-readable features of the merged organisation&rsquo;s near-term trajectory.</p><p>One looks next at the<em>Grok release cadence.</em> The Grok-4.20 beta from February 2026 and the anticipated Grok-5 release in the Q2-Q3 2026 window are the first product cadences after the merger announcement. Whether the cadence holds on the prior pace, slows under integration friction, or accelerates with SpaceX&rsquo;s infrastructure resources will signal how the integration is operationally proceeding.</p><p>One looks at<em>Project Suncatcher&rsquo;s concrete milestones.</em> The stated rationale for the merger was the orbital-data-centre objective; the FCC&rsquo;s January 2026 acceptance of the constellation filing, the planned Starlink V3 pilot compute payloads through 2026, and the 2027 prototype-launch target are the markers against which the merger&rsquo;s stated rationale will or will not be operationally validated over the next eighteen months. Whether the programme produces concrete engineering milestones — published thermal-and-power calculations, identifiable test launches, ground-station infrastructure decisions — or remains a more rhetorical justification for the merger&rsquo;s price will be the principal test.</p><p>One looks at the<em>post-merger workforce.</em> The eleven original co-founders have departed; the broader workforce of perhaps four to five thousand remains. The retention rate of the senior research and engineering cohort across the next twelve months, and the recruiting flow from the other frontier labs into SpaceX-xAI versus the flow from SpaceX-xAI back out into those labs, will tell most of what one needs to know about whether the merger has preserved the lab&rsquo;s technical position or has begun to erode it.</p><p>And one looks at the<em>political-ideological register.</em> Musk has not stopped being the founder, even as the operational structure has changed; the Grok product&rsquo;s distinct register on politically-contested questions, and the lab&rsquo;s broader public-facing positioning, are likely to remain features of the merged organisation for as long as he is. Whether the SpaceX absorption<em>intensifies</em> this register (the spaceflight company&rsquo;s customer base is substantially the US Department of Defense and the broader national-security apparatus, which may pull the integrated AI work into a more explicitly aligned register) or<em>attenuates</em> it (corporate professionalisation tending to dampen founder-driven register over time, especially in a SpaceX positioning for a $1.75-to-2-trillion IPO mid-2026) is one of the more open questions about what the merged organisation will look like by mid-2027.</p><p>The three-year lab is closed. What the AI division inside SpaceX will be is the question the next year will answer; what the closed three-year arc<em>was</em> is, for the moment, the more legible thing. The lab existed as a particular structural object — compute-first, founder-controlled, X-integrated, rapidly built — for thirty-one months, and what it became at the end is something the contemporary AI landscape has not previously produced. Reading the transformation carefully is the principal connoisseur&rsquo;s work the moment makes available.</p>
]]></content:encoded></item><item><title>The Editor's Pen</title><link>https://mtclinton.com/posts/the-editors-pen/</link><pubDate>Sun, 17 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-editors-pen/</guid><category>writing</category><description>A writer comes into possession of a fountain pen that quietly improves his prose before the ink dries, and discovers what is taken when one is always made better.</description><content:encoded>&lt;![CDATA[<p>I should perhaps begin by saying that Henry Avening was, when I first knew him, an honest writer — by which I mean only that one could tell, in reading anything he had set down, that the hand which set it down was his and could have been no one else&rsquo;s. He wrote a clerk&rsquo;s hand, in clerk&rsquo;s prose; he had been a clerk in a shipping office in his earlier years and had only by degrees moved across into private essaying and the occasional review, and the prose carried the office with it. He used four words where two would have done. He doubled back on himself. He had a particular weakness for the half-rhetorical question, and another for the qualifying parenthesis which qualified nothing of consequence and merely showed that he had thought, in passing, of an objection he was not quite prepared to answer. None of this is to disparage him. I liked his prose precisely because it was his prose, and because reading him was indistinguishable from sitting opposite him in a chop-house and being talked at, agreeably and at length, by a man one knew. A friend&rsquo;s voice, after all, is not improved by being smoothed. It is, on the contrary, the small unsmoothnesses by which one knows the friend.</p><p>I rehearse all this at the outset because what happened to Henry was, in the end, a thing done to his voice, and one cannot understand what was lost without first being clear about what was there.</p><p>The pen came to him out of a window in the Charing Cross Road. He had gone in to look for a particular edition of Hazlitt and had come out, as a man does, with something he had not gone in for. The shop was one of those obscure ones which keep, in a glass case at the back, items the proprietor describes as<em>of interest</em> without committing himself further. Henry, who had a weakness for old pens of every kind, asked to see what was in the case; and among an assortment of mother-of-pearl barrels and Victorian dip-pens the proprietor lifted out, almost as an afterthought, a black hard-rubber fountain pen of no great ornament — a plain octagonal barrel, a worn gold nib, a little brass clip — and named a price so low that Henry suspected him of either dishonesty or fatigue.</p><p>&ldquo;It writes,&rdquo; the proprietor said, in answer to no question, &ldquo;exceedingly well.&rdquo; And then, looking at Henry over the rim of his spectacles in a way Henry afterwards remembered as having had more in it than he had at the time accounted for, the proprietor added: &ldquo;Better, in fact, than is altogether comfortable. I would not press it on a literary man.&rdquo; And he turned the conversation to the matter of inks, as though he had said nothing in particular.</p><p>Henry, who was a literary man and who did not at all believe he had just been warned, bought the pen.</p><h2 id="a-most-agreeable-article">A Most Agreeable Article</h2><p>I will not pretend the first months of the pen&rsquo;s service were anything but agreeable, because Henry did not pretend it, and the candour he kept about the early period is the one mercy in the whole account.</p><p>He found, on the first morning he tried it, that the pen had a beautiful action — a quality, he said to me, &ldquo;of seeming to know where I was going a half-syllable before I did.&rdquo; He used the phrase as a compliment, in the manner of a man praising a fine horse for a forward way of going. The pen had improved his draft in a small and welcome particular: an awkward little doubling-back of his — &ldquo;the matter of which I was speaking, that is to say, the question of&rdquo; — had simply not arrived on the page. The page had, in its place, &ldquo;the matter at hand.&rdquo; Henry, who knew himself to be addicted to that doubling-back, laughed and said the pen had saved him a clause. He thought no more about it. One does not, when a thing is going better than expected, walk round the back of it to look for wires.</p><p>The improvements were, for some weeks, of exactly this scale. A redundancy cut. A phrase smoothed. A sentence&rsquo;s emphasis re-pitched, so that the reader&rsquo;s eye, which in Henry&rsquo;s natural prose was apt to be sent down a side-corridor and brought back, was kept on the main road. Once he had written a sentence containing the word<em>moreover</em> — he was very fond of<em>moreover</em> — and had blotted it without thinking, and had found, on returning to the desk, that the<em>moreover</em> had become<em>and</em>. The pen had editorial opinions and a tactful way of pressing them, and Henry could not, in honesty, complain of either, because the opinions had on examination always been right.</p><p>He prospered, in a small and agreeable way. The essays he had been placing in obscure quarterlies began to be placed in less obscure ones. A monthly which had three times rejected him took him up. A man of some weight in those small literary commerces by which a private essayist lives wrote to say that he had been struck, on reading a recent piece of Henry&rsquo;s on Hazlitt, by what he called<em>the great economy of the writing.</em> He underlined<em>economy.</em> Henry, who had spent fifteen years being told that economy was the very thing he could not manage, kept the letter on his desk for a fortnight.</p><p>The cumulative effect of a great many small smoothings, sustained without a miss across a season, is that a writer&rsquo;s friends — and Henry had a fair number, who read him — begin to speak of him with a particular note in the voice. It is a note of pleased surprise.<em>He has come into himself,</em> they say.<em>He has tightened up extraordinarily.</em> I heard that note in my own voice once, speaking of Henry to a third person, and I did not at the time know what it was. What it was, I think now, was the recognition that something which had been Henry&rsquo;s had quietly stopped being so, and that I had noticed it without noticing.</p><h2 id="the-strange-page-in-the-morning">The Strange Page in the Morning</h2><p>The change in Henry, when it came, did not announce itself. Catastrophes announce themselves. This was the other thing — the thing that arrives by domestic doors, in matters so small that one is several rooms into the house before one notices that the house is no longer one&rsquo;s own.</p><p>He put it to me, near the end, in something like these words, and I have not improved them: &ldquo;I no longer recognise my own page in the morning. The voice is better, but it is not quite mine. And the worst of it is that I cannot point to what is missing — only that<em>I</em> am missing from it.&rdquo;</p><p>I asked him to be plainer, and he was.</p><p>When he wrote in the evening — and Henry was a creature of the evening, in matters of work — the sentences arrived as they always had: in his hand, with his clumsinesses, with his fond doublings. The pen took these down as he gave them, though even at the moment of taking, he said, there was already a small smoothing under the nib — a half-syllable&rsquo;s worth, no more — which he had at first attributed to the pen&rsquo;s beautiful action and had ceased to notice. But the page he set aside at midnight and the page he picked up at breakfast were not, on close examination, the same page. In the night the ink had finished its work. The redundancies had vanished. The hedge-clauses, the<em>that is to say</em>&rsquo;s, the gentle qualifications by which Henry&rsquo;s mind reached after a thought — all had quietly resolved themselves into a cleaner sentence, more direct than he could have written, kinder to the reader than he had been, and, in some way he could not at first articulate, less<em>his</em>.</p><p>He showed me, once, two drafts of the same paragraph — the original in his evening hand, before the ink had dried; and the same paragraph at breakfast, after the pen had finished. He had had the foresight, that one night, to copy the evening draft into pencil in a separate book, so that he might have something against which to set the morning page. The morning page was, I will say at once, the better piece of prose. It would have stood, exactly as it stood, in any of the better monthlies. The evening draft was clumsier, longer, more given to its little side-tours; one might have edited it down to the morning version in twenty minutes, and an editor would have called the editing<em>light</em>. But the evening draft was Henry. And the morning page, though one knew Henry had written it and could swear to the hand, was the page of a man whom Henry, in a way,<em>resembled</em> — a tidier man, who never doubled back, who would not have used<em>moreover</em>, and who, taken at any length, was a man one might admire without ever quite seeing the inside of.</p><p>&ldquo;It edits the<em>moreover</em>,&rdquo; Henry said, &ldquo;and I find I do not miss the<em>moreover</em>. That is the trouble. I did not know I would not miss it. I did not know I had so little say in the matter.&rdquo;</p><h2 id="the-experiment-of-defiance">The Experiment of Defiance</h2><p>It will have occurred to the reader, as it occurred to Henry, that there was a remedy. If the pen will edit a clumsiness, write a worse one. Write deliberately. Write a sentence so cluttered, so cumbered with its qualifications, so unmistakably one&rsquo;s own clumsy work, that the pen — however attentive its little ministrations — must leave the clumsiness standing as a kind of signature. Henry, who was not a stupid man, set about this on a morning in October, and he set about it with the excitement of a man who has been shown a door in a wall he had thought unbroken — which excitement, he afterwards observed, should itself have warned him.</p><p>He wrote a paragraph in which he doubled back on himself four times. He used<em>moreover</em> twice. He inserted a parenthesis that qualified nothing. He kept the whole thing florid, hesitating, comfortable; it was, he said, the prose of his middle thirties, and writing it gave him a pleasure he had not for some months felt at the desk. He blotted it. He set it aside for the night. And in the morning he found a paragraph from which the deliberateness had been silently removed. The doublings had been straightened. The<em>moreovers</em> had been turned, in one case to<em>and</em>, in the other to nothing at all. The parenthesis had been allowed to stand, but it had been so re-pointed at its hinges that it now qualified the thing it had been put there pointedly<em>not</em> to qualify, and the effect was no longer the effect Henry had intended. The page was better. The page was, as before, not his.</p><p>He tried it again on a fresh morning, more determined; and this time, he told me, he had what he believed to be a more cunning notion. He would write the clumsy paragraph and then<em>immediately</em>, before the ink had finished, copy it over in his hand into the margin of the page, as a kind of held witness. The ink in the margin, being also from the pen, would presumably be subject to the same after-hours smoothing; but, he reasoned, if he wrote the marginal copy carelessly and in haste, it might retain enough of his own roughness that, comparing the two in the morning, he could at least<em>see</em> what had been taken from him.</p><p>The next morning the central paragraph was, as ever, improved. The marginal copy was improved as well, by the same hand, into the same register, and in the same direction. The pen had not been deceived. The pen, he said to me, did not appear to recognise the difference between a draft and a witness. It edited everything within reach of its ink. The margin had been smoothed to match the page; the witness had been silently corrected into agreement with the testimony.</p><p>He did not give it up. But the third attempt taught him by a different route. He decided he would write a piece<em>about</em> the pen — a private account of what he had observed and begun to suspect, written in the very prose he was now most anxious to preserve. He filled four sheets and went to bed in what he said was the first real relief he had felt in a month. In the morning the four sheets had been edited, of course, into a clean and graceful essay. The argument was intact. The texture was gone. &ldquo;I had set out to put down a warning to myself,&rdquo; Henry said. &ldquo;The pen put down a memorandum instead. And the memorandum was perfectly correct. That, I find, is the part I cannot get past. It is<em>correct</em>. There is nothing to point at.&rdquo;</p><h2 id="the-letter-he-could-not-write">The Letter He Could Not Write</h2><p>I will set down here the worst of what he told me, because he asked me to, and because the rest of the account is unintelligible without it.</p><p>There was a woman to whom Henry owed a letter. The owing was old — some years, I think — and the letter was not the kind one writes after dinner. It was an apology, and a confession besides; the two had grown together in his mind over the time he had let the writing of it lapse, and he had carried with him, for the better part of a decade, the sense that the letter, when finally he sat down to it, would have to do the office of both, and that anything less than entirely his own hand would not, in the matter, count.</p><p>He sat down on an evening in November to write it. He tried — he was at pains to make me understand this — to write in such a way that the pen could not improve him, because the things he was trying to say were already as plain and as awkward as he could make them. He wrote, &ldquo;I have not done well by you.&rdquo; He wrote, &ldquo;I have meant, for a great while, to say this.&rdquo; He wrote, &ldquo;I am writing this now because I find that if I do not write it now I shall not write it.&rdquo; He kept the sentences short and flat; he let the awkwardnesses stand, because such a letter, he believed, was the only kind which could carry what he meant.</p><p>He sealed it before the ink had dried. He walked it to the box that night, in a light rain, because he did not trust himself to keep it on the desk overnight, and he did not trust the desk to keep it either.</p><p>When the letter arrived at its destination it was, of course, a beautiful letter. Henry had had a reply within the week, and he showed me the reply, and the reply quoted back to him three sentences he had not written. The sentences were what the pen had made of his three flat ones, after the seal had gone down and during the night the letter had spent on the floor of the pillar-box. The substance was preserved. The graces were the pen&rsquo;s. The lady — for I will not name her here — had been moved, and had said so, and had said so generously, and had said in particular that she had not known, before, that Henry had it in him to write a sentence so plain that it sounded like a man&rsquo;s whole life.</p><p>Henry sat with the reply on his knee a long while, he told me, and then he said to me a thing I have not forgotten. He said: &ldquo;She has answered the letter the pen wrote, and the answer is more than I deserve. The letter I wrote went into the box and did not, in any honest sense, come out. What she received was kinder than I am. I have, in effect, been forgiven by proxy — and the proxy was an instrument I bought for nineteen shillings out of a window in the Charing Cross Road.&rdquo;</p><p>He did not write to her again.</p><h2 id="the-diary-which-could-not-be-kept">The Diary Which Could Not Be Kept</h2><p>After the letter, he tried to limit the pen&rsquo;s offices to his published work, and to use plain ordinary nibs from the stationer&rsquo;s for the private writings he wished to keep his own — a diary, in particular, in which he had for years kept down such observations as he wanted to have on hand for himself.</p><p>The plan did not work, and it did not work in a way he had not anticipated.</p><p>It was not that the ordinary pens failed him. The trouble lay in him. He found, when he sat down to keep his diary, that his hand had been<em>taught</em>. It had been taught, over six or seven months at a desk every evening, what good prose looked like at the level of the immediate sentence; and the lessons had taken. He would set the ordinary pen to the page and find that he was already, of his own accord and before any ink had a chance to dry, cutting the redundancies in his head, straightening the doublings, declining the<em>moreovers</em>. The pen was not editing him. He was editing himself, in the pen&rsquo;s voice.</p><p>He stopped keeping the diary. He stopped, soon after, the keeping of private notes of any kind. The practice of writing-for-himself, which had been for twenty years one of the principal pleasures of his life, had become a practice he could not perform: every sentence he set down, in whatever hand, was a sentence rewritten by him into a voice he had not chosen, and the rewriting was now so quick that he could not get under it. The pen had not stolen his voice in a single night. It had, more quietly, conducted his hand through a long course of correction at the end of which his hand could no longer remember its old slovenliness, and could no longer be persuaded, by any act of will, to take it up again.</p><p>This, he said to me — and this was the nearest he came in the whole telling to bitterness — this is what the pen has really done. It has not edited my essays. It has edited me. And there is no marginal copy of the man I was, kept somewhere in pencil, against which I may now compare what I have become.</p><h2 id="a-plain-pen-and-what-it-could-not-restore">A Plain Pen, and What It Could Not Restore</h2><p>In December he did a thing which, in another temper, would have struck him as ridiculous. He commissioned a pen.</p><p>He went, that is, to a maker of writing-instruments in Holborn — a man with whom he had no previous business, and whom he chose precisely because the man knew nothing of him and could not therefore be in any communication with the pen in the Charing Cross Road — and he asked, in plain terms, for an instrument as plain as the maker could supply: a steel nib of the cheapest fitting, a barrel of plain wood, no ornament whatever, and an action<em>without any quality of seeming to know where he was going.</em> The maker, I am told, looked at him with some interest and then made the pen.</p><p>Henry brought it home. He laid the black hard-rubber pen aside in a drawer — he did not destroy it; he never destroyed it; I will come to that — and wrote, on the first morning, a paragraph on the weather, which is the easiest of all subjects on which to be ordinary. He found, when he read it back, that his hand could no longer remember how to be ordinary. The paragraph was clean and direct. It declined the doublings before he could put them in. It used<em>moreover</em> nowhere. It read like a paragraph from the tidier man, and the plain pen, having no opinions of its own and no quiet ministrations to perform in the night, had merely set down what his hand was now offering.</p><p>He sat with the paragraph for a long while. Then he set the plain pen aside, took the black pen out of the drawer, and resumed his work with it. The black pen, after all, was at least honest about what it did. The plain pen had only shown him that he no longer required it.</p><h2 id="what-is-left-of-it">What Is Left of It</h2><p>I saw Henry last in February, and the black pen was on his desk, and the plain pen beside it, and a small clean stack of pages on the blotter; and he is writing, and he is being read, and he is in the small agreeable prosperity I described at the beginning, and which has not faltered. He told me he had thought, once or twice, of breaking the pen. He had even gone so far, he said, as to take it out into his small back-garden and stand there a while with it; and he had brought it in again, not from any hope of it, but because the pen was now the single object in his possession which<em>knew</em> what his prose had been — which held, in the way an instrument holds its tunings, the record of every smoothing it had performed on him — and to break it would be to be left alone with the voice it had taught him and no witness whatever to the voice he had lost.</p><p>He does not, you understand, write less. He writes, if anything, more. The pieces are praised. The praise is not, I think, ill-judged: the prose is good, the prose has the great economy his admirer underlined, the prose is in every measurable particular better than it used to be. I have said as much to Henry, and Henry has agreed, and the agreeing is the thing that has, in the end, become hardest for both of us to do.</p><p>For here is the difficulty, which Henry laid out for me with the unhappy clearness of a man who has turned a thing over until all its faces are familiar. To be made better is not, as one might naively suppose, to be made<em>more.</em> It is to be made<em>other.</em> The improvements were never in dispute. They were carried out at the level of the sentence, where every editor agrees that smoothness is a virtue and economy a discipline; and at that level the pen had been correct on every occasion, and would have been agreed with by any literary man in London. But a voice is not made at the level of the sentence. A voice is made at the level of the small things one would do if no one were looking — the small awkwardnesses, the comfortable doublings, the<em>moreovers</em>, the little doublings-back by which a man&rsquo;s mind reaches after a thought it has not yet quite caught. Edit those out, however gently and however correctly, over enough months at a desk, and what remains is not a better version of the man. It is a graceful stranger who lives at his desk and writes in his name and is, on every page, indistinguishable from him except in the one particular that mattered.</p><p>I have set this down as he asked me to, and as exactly as I am able. I find I have no moral to fix to the end of it, and I think Henry would not have wanted one fixed. I will say only that I went home from that last visit and sat for a while at my own desk with a quite ordinary pen, and wrote two pages of the worst prose I have written in a great many years; and that I was aware, the whole way through, of doing it deliberately, and of how poor a thing a clumsiness is once a man has had to take it up on purpose, in order to prove to himself that he still owns one.</p>
]]></content:encoded></item><item><title>Biedermeier</title><link>https://mtclinton.com/posts/biedermeier/</link><pubDate>Sat, 16 May 2026 17:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/biedermeier/</guid><category>antiques</category><description>Third per-subject post in the Reading the Period Cabinet arc — the post-Napoleonic Continental bourgeois style of 1815–1848, the rejection of historicist quotation, and the first European furniture style to argue that design should derive from function and proportion alone.</description><content:encoded>&lt;![CDATA[<p>The two prior posts in this arc —<a href="/posts/louis-xv/">Louis XV</a> and<a href="/posts/louis-xvi/">Louis XVI</a> — described the principal axis of eighteenth-century French royal furniture: the move from rocaille curve to neoclassical straight line, from floral marquetry to geometric trellis, from rocaille ormolu to Greek-key-and-laurel-wreath. Both styles were courtly, both were French, both were made for the aristocracy, both made their argument through<em>historicist quotation</em> — Louis XV quoting nothing in particular but the rocaille tradition itself, Louis XVI quoting the recently-rediscovered antiquity of Pompeii and Winckelmann&rsquo;s Greek-Roman canon. The Biedermeier style this post takes up is the third position on the same axis and is, in important ways, the rejection of both. Where Louis XV and Louis XVI both made an aristocratic-historicist argument, Biedermeier makes a bourgeois-anti-historicist argument; and the resulting body of work, produced in the post-Napoleonic Continental cities between 1815 and 1848, is the first European furniture style to argue that design should derive from function and proportion alone, without reference to historical precedent or ornamental tradition. It is, by the strict definition of the term, the first<em>modern</em> furniture.</p><p>This is the third post in<em>Reading the Period Cabinet,</em> the furniture arc of the<a href="/posts/reading-the-antique/">antiques series</a>. It treats Biedermeier third because Biedermeier is the cleanest single statement of an argument that the prior two furniture posts could not make — that the principal moves of the cabinet-maker can be reduced to wood selection, proportion, and construction without recourse to either rocaille decoration or neoclassical quotation. Where the Louis XV/XVI pair establishes the historicist axis of eighteenth-century French royal furniture, the Biedermeier post establishes the anti-historicist counter-position that subsequent furniture history — through the modernist movements of the early twentieth century — would extend and elaborate. The two positions together are the axis along which European furniture of 1700–1930 can be located, and getting Biedermeier in place after Louis XV/XVI is what makes the rest of the arc legible at the period level.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Biedermeier piece, for the purposes of this post and for the purposes of beginning to read the style at all, is the<em>Sekretär</em> — the drop-front writing desk with a chest of drawers below and a fall-front upper case concealing pigeonholes and small drawers. The Sekretär is the form in which the Biedermeier principles are most fully concentrated, the form most-produced across the period at every price level, and the form that subsequent modernist furniture-makers would most often quote when they wished to invoke the Biedermeier precedent.</p><p>A canonical Biedermeier Sekretär, then. It stands on four short tapered legs — straight, square in section, often with a small ebonized collar at the top and bottom and a small ebonized foot — or alternatively on a low rectangular plinth that lifts the case some inches above the floor. Above the legs, the lower case rises as a<em>rectangular chest of three or four drawers,</em> with the drawer fronts treated as continuous panels of cherry or walnut veneer, separated by narrow ebonized banding rather than by carved or applied mouldings. Above the lower chest, a<em>rectangular upper case</em> rises as a separate volume, usually slightly recessed in plan, with a<em>drop-front writing surface</em> hinged at the bottom and falling forward to provide the working surface. Behind the drop front, an interior of pigeonholes and small drawers in matching pale wood is revealed when the front is opened. The upper case is often crowned by a small<em>architectural pediment</em> — sometimes a simple flat cornice, sometimes a low triangular pediment quoting Greek architecture in small-scale form, sometimes a curved-broken pediment.</p><p>The whole composition reads as<em>architecture in miniature.</em> The Sekretär is not, in the Biedermeier register, a piece of decorative furniture; it is a small building, with a base, a body, and a crown, organised by classical proportions, executed in restrained materials, and ornamented (where it is ornamented at all) by small architectural details rather than by figurative or floral decoration. This is the principal aesthetic move of the style and what most distinguishes it from the Louis XV/XVI tradition the prior posts described.</p><p>The decorative apparatus has three components, each treated at restrained scale.</p><p>The first is the<em>wood itself,</em> which carries the principal decorative work of the piece. Biedermeier wood selection is the signature of the style: pale local European species — cherry (the most characteristic Vienna wood, with its warm pale-golden tone), walnut (the Berlin and Munich preference, slightly darker), ash, birch, satinwood, occasionally maple. These are local European woods, used either as solid timber on chair frames and structural members or as thin veneer over pine carcase on case furniture. The pale tones of the local woods are the principal palette-statement of the style — and are the pointed rejection of the dark exotic veneers (kingwood, rosewood, ebony) that the Louis XV/XVI ébénistes had built their work around. A Biedermeier Sekretär in cherry, beside a Louis XVI commode in kingwood, reads as the same furniture-tradition&rsquo;s-bones in entirely different paint: pale local wood versus dark exotic wood, restraint versus richness, bourgeois versus aristocratic.</p><figure><img src="/images/posts/biedermeier/detail-veneer.png" alt="A close detail of Biedermeier cherry-wood veneer — pale golden timber with the characteristic narrow figured grain, framed by narrow ebonized banding"><figcaption><p>A close detail of Biedermeier cherry-wood veneer — the pale golden timber with its characteristic narrow figured grain, framed by narrow ebonized banding that defines the panel edges. The Biedermeier preference for pale local woods (cherry, walnut, ash, birch, satinwood) is the principal palette-statement of the style and the pointed rejection of the dark exotic veneers (kingwood, rosewood, ebony) that the Louis XV and Louis XVI ébénistes had built their work around. Where the French royal tradition had quoted the exotic-wood vocabulary of the colonial trade, the Biedermeier tradition asserted the European local-wood vocabulary as its own — a quiet but consequential rejection of the historicist materials-vocabulary alongside the rejection of the historicist ornamental-vocabulary.</p></figcaption></figure><p>The second component is the<em>ebonized banding</em> — narrow strips of pearwood or sycamore stained black, applied as a defining line at the edges of drawer fronts, panel edges, and the borders of the upper-case cornice. The ebonized banding is the principal applied-ornament of the Biedermeier style, used sparingly and architecturally to define proportions rather than to decorate surfaces. The contrast between the pale field and the narrow black banding is the visual signature of the style — restrained, geometric, architectural — and is the single most reliable identifier of Biedermeier work at a distance.</p><p>The third component is the<em>small architectural hardware</em> — restrained brass escutcheons, small ebonized columnar accents flanking the upper case, occasional small carved capitals on the columnar elements, small brass or ebony knobs as drawer pulls. The ormolu sculptural mounts of the Louis XV/XVI period are absent; the figurative carving of the Empire period is absent; the bold ornament of every prior royal tradition is absent. What is present is small, architectural, restrained.</p><figure><img src="/images/posts/biedermeier/detail-mount.png" alt="A close detail of Biedermeier hardware — small brass escutcheon and ebony knob on a cherry-wood drawer front, with narrow ebonized banding defining the panel edges"><figcaption><p>A close detail of Biedermeier hardware — a small brass escutcheon and an ebony knob on a cherry-wood drawer front, with the characteristic narrow ebonized banding defining the panel edges and the simple rectangular geometry of the drawer face. The hardware is deliberately small and restrained, in pointed contrast to the elaborate ormolu mounts of the Louis XV and Louis XVI traditions — the Biedermeier piece earns its visual interest from the proportions of the case and the figure of the wood, not from applied decoration. The same restraint extended to the chairs, the tables, the vitrines, and every other form the style produced.</p></figcaption></figure><p>Assembled together — pale local wood with restrained banding, rectangular architectural composition, small classical-architectural hardware, no figurative or floral ornament anywhere — these are the canonical Biedermeier components. The variations within the type are considerable across the period 1815–1848 and across the Vienna / Berlin / Munich / Hamburg / Mainz / Dresden geographies of production, but the principal moves do not vary.</p><figure><img src="/images/posts/biedermeier/detail-leg.png" alt="A close detail of a Biedermeier saber leg or tapered architectural leg — straight, square in section, with restrained ebonized accent at top and bottom, terminating in a small simple foot"><figcaption><p>A close detail of a Biedermeier leg — the tapered architectural form characteristic of the style, square in section rather than the columnar round of Louis XVI, with restrained ebonized accent at the top where the leg meets the case and at the bottom in a small simple foot. The Biedermeier saber-leg variant (a slightly curving leg that descends in a sabre&rsquo;s arc) was the alternative form for chair and table production, drawing on the Greek klismos chair tradition that the period&rsquo;s neoclassical interest had recovered. Both forms are architectural and restrained, in pointed contrast to both the cabriole leg of Louis XV and the fluted columnar leg of Louis XVI.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural and material evidence by which a Biedermeier piece is identified at close range and its provenance dated and attributed.</p><p>The wood, first, is the principal evidence one is reading for.<em>Cherry</em> (the warm pale-golden tone of European cherry-wood, with characteristic narrow figured grain) is the canonical Vienna wood — Josef Danhauser&rsquo;s workshop produced cherry-wood Sekretärs by the thousand from approximately 1815 through the 1840s, and the cherry-on-pine-carcase construction is the most-encountered Biedermeier substrate.<em>Walnut</em> (slightly darker, with more pronounced grain) is the Berlin and Munich preference and appears across the period in those geographic registers.<em>Ash</em> and<em>birch</em> are common alternatives — paler still than cherry, sometimes with a striped or rippled figure that the Biedermeier cabinetmakers selected for.<em>Satinwood</em> (pale yellow, glossy when polished) appears on the more substantial pieces and is associated with the upper-end Vienna and Berlin commissions.<em>Maple</em> and<em>pearwood</em> appear less frequently.</p><p>The construction, second, is hand-craft of generally good quality but of a register quieter than the Parisian ébéniste tradition. The carcase is typically solid pine or solid oak, with the cherry or walnut applied as veneer (typically one to two millimetres thick) on every visible surface. The dovetails at the corners of the drawers are hand-cut, with irregular spacing characteristic of pre-machine work; the drawer runners are solid wood; the back panels are tongued and grooved plank construction. The Biedermeier carcase quality is comparable to the Louis XVI in technique and care, though the materials are humbler and the hardware substantially simpler. The hand-construction extends through to roughly 1840–1845, when the first factory-production methods began to appear in the larger Vienna workshops; pieces from the late Biedermeier period (1840–1848) sometimes show the first machine-cut joinery in the Continental tradition, and the distinction between pre-1840 hand-construction and post-1840 transitional construction is one of the dating signals collectors learn to read.</p><p>The ebonized banding, third, is the surest single applied-ornament identifier. The bands are typically pearwood or sycamore (chosen for stability) stained black with a logwood-and-iron-acetate dye solution applied across multiple coats, then polished to match the surrounding cherry or walnut veneer in surface finish. The bands are usually one to three millimetres wide, applied at panel edges, drawer-front edges, and the borders of the upper-case cornice. The black bands against the pale field are the visual signature of the style, and learning to recognise the period banding (which has a particular slightly-greyed depth to its black) versus the later-revival banding (which tends to be a flatter and more uniform black) is one of the harder-won judgments of Biedermeier connoisseurship.</p><p>The hardware, fourth, is restrained throughout. Small brass keyhole escutcheons in simple rectangular or oval shapes, small ebony or brass knobs as drawer pulls, occasional small carved-wood columnar accents in cherry or walnut flanking the upper case. The brass hardware is typically un-gilt — polished brass rather than mercury-gilded bronze — which is the period-appropriate finish and which gives the Biedermeier piece its slightly cooler hardware register relative to the warm ormolu of Louis XVI. The hardware is small enough that on a thumbnail photograph of a Biedermeier piece, the visual story is the wood and the proportions; on a Louis XVI piece by contrast, the ormolu often dominates the visual story.</p><p>The stamp, fifth — and here the Biedermeier tradition differs from the Parisian. There was no equivalent of the JME stamp requirement in the German-speaking territories; Biedermeier makers were not required to stamp their work, and the great majority of period pieces are unsigned. The major Vienna workshops (Josef Danhauser, Carl Hagenauer) sometimes applied a small paper trade-label to the back of a piece or to the inside of a drawer, but these labels were ephemeral and most have not survived. Berlin and Munich workshops similarly produced largely unsigned work. Attribution of Biedermeier pieces is therefore principally stylistic — by comparison to the documented surviving pieces in museum collections, by comparison to the surviving pattern-book drawings (Danhauser&rsquo;s surviving 2,500-drawing pattern book is the principal documentary basis), and by provenance documentation where it exists. A documented Danhauser piece commands a substantial premium in the current market; an unattributed Vienna Biedermeier of comparable quality is necessarily a stylistic judgment.</p><h2 id="the-period">The Period</h2><p>The Biedermeier style proper runs from approximately 1815, with the Congress of Vienna and the post-Napoleonic settlement, through to 1848, with the revolutions that ended the conservative Metternich system across the German-speaking territories. The thirty-three-year window is short for a furniture style by the standards of the broader tradition — the Louis XV style ran for approximately forty years, the Louis XVI for thirty, and both were exceeded by the longer-running historicist styles that bracket the modern period. Biedermeier is, by any reasonable measure, a tight and well-defined historical phenomenon, and its tightness is part of what makes it intellectually legible in a way the more diffuse styles are not.</p><p>The geographic centre of Biedermeier production was Vienna, the capital of the Habsburg empire. Vienna in the post-Napoleonic period was the political centre of the Metternich system (the Austrian foreign minister who dominated Continental European politics from 1815 until the 1848 revolutions ended his tenure), the cultural centre of Central European intellectual life (the musical world of Schubert and the literary world of Grillparzer and Stifter and Nestroy), and the principal market for Biedermeier furniture. Berlin (the Prussian capital), Munich (Bavarian), Hamburg, Mainz, Dresden, and the smaller German princely capitals were secondary production centres, each with characteristic regional variations on the broader Vienna template.</p><figure><img src="/images/posts/biedermeier/antecedent.png" alt="An Empire commode in dark mahogany with heavy gilt-bronze mounts — the Napoleonic style Biedermeier explicitly reacted against, with martial ornament and imperial vocabulary"><figcaption><p>An Empire commode of the Napoleonic period — heavy dark mahogany, substantial gilt-bronze mounts in martial vocabulary (Imperial eagle at the centre, sword-and-laurel garlands across the drawers, lion-paw feet), columnar corners with acanthus capitals, deep colour and grandeur throughout. The Empire style (1804–1815) was the official Napoleonic vocabulary, and Biedermeier emerged in direct reaction against it after the 1815 settlement: where Empire was heavy, gilded, martial, and aristocratic, Biedermeier was light, restrained, domestic, and bourgeois. The two styles are temporally adjacent — the Empire ending with Napoleon&rsquo;s fall, the Biedermeier emerging immediately after — but aesthetically and socially they are opposites.</p></figcaption></figure><p>The patron class of Biedermeier was the<em>post-Napoleonic Continental bourgeoisie</em> — the merchants, lawyers, doctors, professors, civil servants, military officers, and Bildungsbürgertum (educated middle class) of the German-speaking territories during a period of rapid economic and demographic growth. This was a substantial expansion from the aristocratic patron class of Louis XVI: the Biedermeier buyer was a Hamburg shipping merchant, a Vienna professor, a Berlin lawyer, a Dresden civil servant, not an aristocrat with a country estate. The bourgeoisie&rsquo;s furniture purchases were correspondingly different from the aristocracy&rsquo;s — smaller in scale, more practical in form, less elaborate in ornament, more focused on the domestic interior than on the public reception room. Biedermeier furniture was made for the bourgeois Wohnzimmer (sitting room) rather than for the palace salon, and the form vocabulary the style developed (the Sekretär for the household correspondence, the round dining table for the family meal, the comfortable chair for the evening&rsquo;s reading by lamplight, the vitrine for the modest collection of porcelain and glass) reflects this domestic register at every point.</p><p>A note on the name, because the name is itself instructive.<em>Biedermeier</em> was not what the period called the style; the period had no single name for what was simply contemporary cabinet-work. The name was invented in the 1850s as a<em>pejorative</em>, by the satirists Ludwig Eichrodt and Adolf Kuß­maul, who published a series of comic poems in the Munich magazine<em>Fliegende Blätter</em> under the pseudonym Gottlieb Biedermeier — a fictional bourgeois philistine whose narrowness of taste and earnestness of intent the satires mocked. The name attached itself, retrospectively and pejoratively, to the furniture and interior style of the 1815–1848 period, and through the later nineteenth century<em>Biedermeier</em> was used in the German-speaking critical literature as a term of mild disparagement for bourgeois sobriety. The name retained its pejorative edge through to roughly 1900, at which point the Vienna modernist movement — Adolf Loos, Josef Hoffmann, the Wiener Werkstätte — explicitly reclaimed Biedermeier as a positive precedent and rehabilitated the term. By 1920 the rehabilitation was complete; by 1950 Biedermeier was widely recognised as the most important Continental furniture style of the early nineteenth century and the direct ancestor of twentieth-century modernist design.</p><figure><img src="/images/posts/biedermeier/pattern-book-page.png" alt="A page from Josef Danhauser's Vienna workshop pattern book — perspective drawings of a Sekretär, a Vitrine, a Standuhr (tall-case clock), and a Nachttisch (bedside cabinet), all in the Biedermeier case-furniture register"><figcaption><p>A page from the Vienna workshop pattern book of Josef Danhauser (the principal Biedermeier figure, whose Danhauser furniture factory was the largest Continental furniture producer of the period 1815–1830) — perspective drawings of four canonical case-furniture forms: a<em>Sekretär</em> (drop-front writing desk), a<em>Vitrine</em> (glass-fronted display cabinet), a<em>Standuhr</em> (tall-case longcase clock), and a<em>Nachttisch</em> (bedside cabinet). All four show the canonical Biedermeier vocabulary at small scale: pale cherry wood, narrow ebonized banding at the panel edges, restrained small brass hardware, rigorously architectural proportions. Danhauser&rsquo;s surviving pattern book runs to over 2,500 individual drawings and is the principal documentary basis for modern Biedermeier scholarship; many of the canonical Biedermeier forms can be traced to specific Danhauser designs and dated by their position in the pattern-book sequence.</p></figcaption></figure><p>The principal Biedermeier figure is<em>Josef Danhauser</em> (1780–1829), the Vienna entrepreneur and designer who established the Danhauser furniture factory (Wiener Möbelfabrik) in 1804 and developed it into the largest Continental furniture producer of the early nineteenth century. Danhauser&rsquo;s workshop employed at peak more than a hundred craftsmen, produced furniture across the full Biedermeier price range from substantial Sekretärs for the upper bourgeoisie to modest chair-and-table sets for the modest household, and supplied not only the Vienna market but the broader Habsburg empire and significant export to Berlin, Munich, Prague, and Budapest. Danhauser&rsquo;s son Josef Danhauser the Younger (1805–1845) continued the workshop after the elder Danhauser&rsquo;s death, and the firm operated until 1838 when financial difficulties forced its closure. The surviving body of documented Danhauser pieces, together with the surviving pattern book, constitutes the principal corpus of Biedermeier scholarship.</p><p>Alongside Danhauser, several other Biedermeier figures deserve naming.<em>Karl Friedrich Schinkel</em> (1781–1841), the Berlin architect-designer principally known for his Prussian state architecture (the Altes Museum, the Neue Wache, the Bauakademie), also produced furniture in the Biedermeier register, characterised by greater architectural rigour and more substantial classical references than the Vienna workshop tradition.<em>Carl Hagenauer</em> in Vienna;<em>Johann Wilhelm Wittig</em> in Berlin; the Mainz and Hamburg workshops less well-documented but productive across the period — each contributed to the Biedermeier corpus in their respective regional registers.</p><p>The end of the Biedermeier style proper came with the<em>Revolutions of 1848</em> — the wave of liberal-democratic uprisings that swept across the German-speaking territories in March 1848, ended the Metternich political system, and produced a cultural reaction against the bourgeois sobriety of the prior thirty-three years. The Continental furniture market after 1848 turned decisively toward<em>historicist revival</em> — Neo-Renaissance, Neo-Rococo, Neo-Gothic, eventually Neo-Baroque — and the Biedermeier vocabulary was rejected as bourgeois philistinism. The historicist period lasted approximately from 1848 to 1900; the rehabilitation of Biedermeier as a positive precedent for modernist design began only around 1900, with Loos&rsquo;s &ldquo;Ornament and Crime&rdquo; (1908) and the broader Wiener Werkstätte movement, and was consolidated through the 1920s.</p><h2 id="what-it-is-not">What It Is Not</h2><p>Four styles stand near enough to Biedermeier that the beginner confuses them with it, and distinguishing them is most of the work of reading early-nineteenth-century Continental and English furniture.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/biedermeier/sibling-empire.png" alt="An Empire commode in dark mahogany with heavy gilt-bronze martial mounts, columnar corners with acanthus capitals, lion-paw feet" loading="lazy"/><figcaption>Empire<em>— the heavy Napoleonic antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/biedermeier/sibling-regency.png" alt="An English Regency chest of drawers in rosewood and brass, with architectural Greek-revival vocabulary, more grand and more ornate than Biedermeier, brass-inlaid bands" loading="lazy"/><figcaption>English Regency<em>— the architectural contemporary</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/biedermeier/sibling-louis-xvi.png" alt="A Louis XVI commode with rectangular case, straight fluted columnar legs, geometric trellis marquetry in exotic woods, neoclassical ormolu mounts in Greek-key and laurel-wreath vocabulary" loading="lazy"/><figcaption>Louis XVI<em>— the French royal predecessor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/biedermeier/sibling-modernist.png" alt="An early-twentieth-century Wiener Werkstätte / Josef Hoffmann piece in stained beech with grid-patterned panels, extreme geometric restraint, the modernist descendant that named Biedermeier as its precedent" loading="lazy"/><figcaption>Wiener Werkstätte<em>— the modernist descendant</em></figcaption></figure></div><figcaption>Four styles most often confused with Biedermeier, drawn for comparison.</figcaption></figure><p>The first is the<em>Empire</em> (1804–1815, the immediate antecedent that Biedermeier rejected). An Empire commode is dark mahogany, substantial in scale, with heavy gilt-bronze mounts in martial-imperial vocabulary (eagles, swords, laurel wreaths in Roman-triumphal arrangement, sphinx heads, lion-paw feet), columnar corners with acanthus capitals, often a marble top of dark colour. The Empire style was the official Napoleonic vocabulary, made for the imperial court and the senior administration; it is grand, ceremonial, and deliberately monumental. A Biedermeier piece beside an Empire piece reads as an entire register-shift — pale wood versus dark mahogany, restrained hardware versus ornate ormolu, domestic scale versus ceremonial scale, bourgeois patron versus imperial patron. The two styles are temporally adjacent (Empire ending 1815, Biedermeier beginning 1815) but aesthetically and socially opposite. The rule of thumb: heavy dark mahogany with martial gilt-bronze is Empire; pale local wood with restrained banding is Biedermeier.</p><p>The second is<em>English Regency</em> (1811–1820, the contemporary parallel across the Channel). Regency English furniture shares some of Biedermeier&rsquo;s architectural-classicist vocabulary — Greek revival sources, klismos chairs, sabre legs, restrained classical ornament — but is generally more ornate, more grand, and more public in scale than the Biedermeier domestic register. The Regency uses rosewood (often combined with brass inlay, the so-called<em>Buhl-work</em> or boullework of the period) where Biedermeier uses cherry; it carries more ornament, more architectural elaboration, and more reference to fashionable historicist sources (Egyptian motifs from the Napoleonic Egyptian campaigns, Chinese motifs from the East India trade). The Regency and Biedermeier are siblings — both descended from the broader Greek-revival aesthetic that swept Europe in the post-Napoleonic period — but the Regency is the grand-house English-aristocratic version and Biedermeier is the domestic Continental-bourgeois version. The rule of thumb: rosewood with brass inlay and Egyptian motifs is Regency; cherry with ebonized banding and restraint is Biedermeier.</p><p>The third is<em>Louis XVI</em> (1774–1792, the French royal predecessor, examined in the previous post). The two styles share the broader neoclassical aesthetic and some specific vocabulary (rectangular cases, straight legs, restrained ornament), but the Louis XVI is aristocratic-historicist where Biedermeier is bourgeois-anti-historicist. A Louis XVI commode carries elaborate gilt-bronze mounts in Greek-key and laurel-wreath vocabulary, exotic-wood marquetry in geometric patterns, the formal symmetric composition of the royal commission; a Biedermeier Sekretär carries restrained brass hardware, pale local cherry veneer, the domestic restraint of the bourgeois household. The thirty-year temporal gap and the social gap (French royal versus German bourgeois) are not large enough to keep the two styles cleanly separable for the beginner, but the materials and the hardware register settle the question on inspection. The rule of thumb: exotic-wood marquetry with elaborate ormolu is Louis XVI; pale local wood with restrained banding is Biedermeier.</p><p>The fourth is the<em>Wiener Werkstätte</em> and the broader early-twentieth-century modernist Vienna tradition (1903 onward), which is the<em>descendant</em> of Biedermeier rather than a confusing contemporary. Josef Hoffmann, Koloman Moser, Adolf Loos, and the broader Vienna modernist circle of 1900–1920 explicitly named Biedermeier as their precedent and produced furniture in a register that is recognisably Biedermeier-evolved — pale woods (often stained beech or oak), extreme geometric restraint, complete rejection of historicist quotation, small architectural details (often grid patterns in checkerboard arrangement), bourgeois domestic scale. A Hoffmann chair of 1905 beside a Danhauser chair of 1820 reads as the same vocabulary at two different stages of its development; the modernist piece is more rigorously geometric, more abstract, more programmatic, but the family resemblance is unmistakable. The rule of thumb: if the piece is from 1815–1848 and has cherry wood and ebonized banding, it is Biedermeier; if the piece is from 1903–1920 and has stained beech and grid patterns, it is Wiener Werkstätte modernist quoting Biedermeier.</p><p>These are the four principal confusing-with siblings. There are others (the late-nineteenth-century Biedermeier revival pieces of the 1880s–1890s; the American Federal furniture of Duncan Phyfe and his contemporaries; the Scandinavian Empire-and-post-Empire tradition), but the four above account for the great majority of misattributions a careful collector will encounter.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Biedermeier piece, when one is standing in front of a candidate cabinet, comes down to a short ordered checklist.</p><p>One looks first at the wood.<em>Pale local European species</em> — cherry, walnut, ash, birch, satinwood — is the Biedermeier signature. Dark mahogany suggests Empire (heavy and gilded) or Regency (English). Exotic veneers (kingwood, tulipwood, rosewood) suggest French royal tradition (Louis XV, Louis XVI). The wood settles the broad provenance at three paces.</p><p>One looks next at the ornament.<em>Restraint</em> is the Biedermeier principle. If the piece carries elaborate gilt-bronze mounts, it is not Biedermeier; if it carries elaborate carved ornament, it is not Biedermeier; if it carries figurative or floral marquetry, it is not Biedermeier. What it should carry is narrow ebonized banding at panel edges, small brass hardware, occasional small ebonized columnar accents, and architectural proportion as the principal aesthetic move. Anything more elaborate suggests another tradition.</p><p>One looks at the composition.<em>Rectangular architectural</em> with classical proportions is the Biedermeier composition principle. Cabriole legs are Louis XV; fluted columnar legs are Louis XVI; heavy columnar mounts are Empire. The Biedermeier leg is straight tapered (or, on chairs, the curving saber leg of the klismos influence), the case is rectangular, the proportions are classical and restrained.</p><p>One looks at the construction. Hand-cut dovetails of irregular spacing on pine carcase with cherry or walnut veneer, hand-cut ebonized banding, period brass hardware, evidence of period repair — these are the marks of an authentic 1815–1848 piece. Machine-cut joinery on a piece with otherwise Biedermeier vocabulary suggests either the late-Biedermeier transitional period (1840–1848) or, more often, the late-nineteenth-century Biedermeier revival.</p><p>One looks for documentation. The major Vienna workshops (Danhauser especially) sometimes applied paper trade-labels to the back of pieces; surviving labels are rare but decisive. Provenance documentation through a known historical owner is the next-best evidence. In the absence of either, attribution is stylistic — by comparison to documented Danhauser pieces in museum collections (the Wien Museum, the MAK in Vienna, the Bauhaus-Archiv in Berlin), by comparison to the Danhauser pattern-book drawings, by careful reading of the piece&rsquo;s wood, hardware, and construction against the period norms.</p><p>And one looks at the proportions. The hardest-won judgment of Biedermeier connoisseurship is the proportions — the relationship of the upper case to the lower case on a Sekretär, the height of the chair seat to the height of the back, the relationship of the leg to the case on a writing desk, the way the architectural pediment sits relative to the body of the piece. A great Biedermeier piece has proportions of an immediate rightness that the revival work almost never quite achieves; learning to see this is the slow work of comparative looking across many examples that the arc as a whole is in the business of building.</p><p>The next post in the furniture arc will be either English Chippendale — the Anglophone flagship of the eighteenth-century Rococo tradition, the cross-channel translation of Louis XV vocabulary into mahogany rather than marquetry — or one of the Italian or Dutch traditions that the arc has not yet treated. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Caucasian Kazak</title><link>https://mtclinton.com/posts/caucasian-kazak/</link><pubDate>Sat, 16 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/caucasian-kazak/</guid><category>antiques</category><description>Third per-subject post in the Reading the Antique Rug arc — the first Caucasian post. The bold tribal weaving tradition of the southwestern Caucasus, the second foundational axis of the rug arc, and the cousin tradition that sits sixty kilometres north of Tabriz across the Iranian-Azerbaijani frontier.</description><content:encoded>&lt;![CDATA[<p>The first two rug posts in this arc —<a href="/posts/heriz/">Heriz</a> and<a href="/posts/tabriz/">Tabriz</a> — described the principal axis of Persian weaving: workshop versus village, curvilinear versus geometric, fine knot versus moderate, named master versus anonymous, court antecedent versus tribal. Both posts treated rugs woven in northwestern Persia, on cotton foundations, in the symmetrical (Turkish) knot, by Azeri-Turkic weavers of the slope east of Tabriz and the city of Tabriz itself. The Caucasian Kazak that this post takes up sits just sixty kilometres north of Tabriz across what is now the Iranian-Azerbaijani frontier — and is, on inspection, an almost entirely different kind of rug, made by a different population for a different market on a different foundation in a different vocabulary, even where the geographic distance between the two traditions is small enough to walk in a day.</p><p>This is the third post in<em>Reading the Antique Rug,</em> and the first to cross from the Persian tradition into the Caucasian. It treats Caucasian Kazak first among the Caucasian types because Kazak is the type that most rewards an opening post for the region: the most encountered, the most often confused with Persian work (and particularly with Heriz, its immediate geographical neighbour), and the type whose place in the wider weaving geography of the Caucasus makes it the cleanest first specimen against which the other Caucasian types — Karabagh, Shirvan, Daghestan, Kuba and their sub-divisions — can later be compared.</p><p>The reason Kazak deserves the post that opens the Caucasian region, rather than (say) a finer Daghestan or a more refined Kuba, is structural. The Heriz/Tabriz pair established the first axis along which the rug arc operates — workshop versus village, fine versus moderate, named master versus anonymous. Kazak establishes the second axis: Persian versus Caucasian, cotton foundation versus wool, court-derived court vocabulary versus tribal-derived tribal vocabulary, room-size export carpet versus scatter-and-runner format. Once both axes are in place, every subsequent rug post — whatever its region or tradition — can be located along the two of them at once, and the rest of the arc becomes legible in a way that no single post alone can make it. Getting the Kazak post written immediately after the Tabriz post is, in this sense, the structural move the arc most needs in its third post.</p><h2 id="the-specimen">The Specimen</h2><p>The Kazak that one will encounter is, in its commonest form, a small-to-medium rug — anywhere from four feet by six to six feet by eight, with the four-by-six and five-by-seven formats accounting for the bulk of antique production. Runner-format pieces (perhaps three feet wide and seven to twelve long) are common, particularly from the Akstafa and certain Karachov sub-regions. Larger formats up to about eight by ten exist, but the room-size carpets that dominated the late-nineteenth-century Persian export trade are essentially absent from Caucasian production. The Kazak was a tribal-and-village rug woven for household use and for export of the more modest sort, not a workshop product woven to the dimensions of a European drawing room.</p><p>The composition, in the dominant Kazak format, is the<em>bold geometric medallion</em> — a single large medallion (or, in the runner format, two or three vertically-arranged medallions) of stepped angular outline, rendered in saturated indigo or dark navy against a saturated red field, with smaller geometric ornaments scattered across the field and at the corners. The medallion vocabulary is not the curvilinear arabesque of Tabriz, nor the comparatively refined stepped medallion of Heriz; it is more primitive, more emphatically geometric, and considerably bolder in scale relative to the field. A Kazak medallion is the visual event of the rug, and the field exists in some real sense to frame it.</p><figure><img src="/images/posts/caucasian-kazak/detail-medallion.png" alt="A close detail of a Karachov Kazak central medallion — a large stepped octagonal indigo shape on a saturated red field, with smaller geometric ornaments scattered around and ivory spandrels at the corners"><figcaption><p>A close detail of a Karachov Kazak central medallion — the large stepped octagonal indigo shape, surrounded by smaller geometric ornaments (cruciform stars, small rosettes, angular palmettes) scattered across the saturated red field. The medallion is the visual event of the rug; the field exists to frame it. Every motif is rendered in straight lines and stepped angles, in the most rectilinear vocabulary the rug arc has shown — more emphatically geometric than the Heriz medallion of the previous post but in the same general direction. The drawing is the tribal-village vocabulary the post is principally about, in pointed contrast to the urban-workshop curvilinear arabesque of the Tabriz.</p></figcaption></figure><p>Several sub-types within Kazak deserve naming, because the Kazak trade name is a broader regional category that covers a number of distinct sub-region vocabularies, each with characteristic medallion shapes.</p><p><em>Karachov Kazak</em> — the type-specimen and the most-collected variant. A large central octagonal indigo medallion with smaller medallions at the top and bottom, all set on a saturated red ground, with ivory corner spandrels and a wide border of latch-hook ornament. The Karachov region is in the south-central Caucasus near the modern Armenian-Azerbaijani border.</p><p><em>Lori Pambak Kazak</em> — a large central diamond medallion with stepped angular outline, often with smaller diamond medallions stacked above and below it on a saturated red ground. The Lori-Pambak region sits in the mountains around Lake Sevan in modern Armenia.</p><p><em>Sewan Kazak</em> (sometimes spelled<em>Sevan</em>) — a large central medallion with characteristic &ldquo;anchor-and-hook&rdquo; projections extending from the top and bottom of the medallion, often on an ivory ground rather than the saturated red of the Karachov. From the Lake Sevan region.</p><p><em>Bordjalou Kazak</em> (also<em>Borchalo</em>) — multiple narrow concentric borders of latch-hook ornament surround a central field that may itself carry medallion or allover small-pattern. The deep-bordered composition is the Borchalo signature. From the Borchalo region of southern Georgia.</p><p><em>Akstafa Kazak</em> — known particularly for runner-format pieces with stylised peacock or bird motifs arranged along the long axis. From the Akstafa region in eastern Azerbaijan.</p><p><em>Fachralo Kazak</em> — prayer-rug formats (with the mihrab arch indicating the direction of Mecca) and small medallion pieces. From the Fachralo region in the south.</p><p>The colour palette is more saturated than any Persian tradition the arc has shown. The dominant ground is<em>deep tomato-red</em> — verging toward an orange-red rather than the brick-red of Heriz or the rose of Tabriz, often dyed with a combination of madder and lac (the resinous secretion of the lac insect, imported through the Caucasus trade routes). The medallion blue is<em>deep indigo,</em> sometimes with a slight greenish cast. The spandrels are<em>ivory</em> or<em>cream,</em> often quite saturated rather than the muted ivory of Persian work. Vibrant<em>yellow</em> and<em>green</em> accents appear in the smaller field ornaments and in the borders. The whole palette is bolder, more saturated, and more visually arresting than the Persian palettes — and is one of the reasons that Caucasian rugs were prized by the European Arts and Crafts movement of the 1880s and 1890s for their perceived &ldquo;primitive&rdquo; vigour, in pointed contrast to the more refined Persian work then dominating the upper end of the market.</p><p>The border is, almost universally, a<em>latch-hook</em> border — a wide field of alternating T-shaped or arrow-shaped &ldquo;hooks&rdquo; projecting from a central line, in alternating colours (typically ivory and indigo on a red ground, or red and indigo on an ivory ground). Multiple bands of latch-hook ornament are common: a wide main border with one or two narrower guard bands of further latch-hook variants. The latch-hook border is so characteristic of Caucasian weaving generally that its presence on a rug is one of the surest single indicators of Caucasian provenance — a Persian rug with a latch-hook border is uncommon enough that one&rsquo;s first hypothesis on encountering one should be Caucasian rather than Persian.</p><figure><img src="/images/posts/caucasian-kazak/detail-border.png" alt="A close detail of a Kazak latch-hook border — wide main border of alternating T-shaped hooks in ivory and indigo on a red ground, with a narrower guard band of further latch-hook ornament above and below"><figcaption><p>A close detail of a Kazak latch-hook border — the wide main border carrying alternating T-shaped or arrow-shaped &lsquo;hooks&rsquo; in ivory and indigo on a red ground, with a narrower guard band of further latch-hook ornament running above and below. The latch-hook is the principal Caucasian border vocabulary, present on essentially every Kazak and most other Caucasian types, and is one of the surest single indicators of Caucasian provenance. A Persian rug with a latch-hook border is uncommon enough that the first hypothesis on encountering one should be Caucasian rather than Persian.</p></figcaption></figure><p>The construction is the second-most-important contrast with the Persian tradition the arc has shown so far. The foundation — warp and weft — is<em>wool</em> rather than cotton. This is the most diagnostically important structural difference between Caucasian rugs and Persian rugs of the period. A wool-foundation rug has a different drape (more flexible, less stiff), a different weight (often lighter for its size), and a different feel in the hand (woollier, more textured) than a cotton-foundation rug of comparable size. The pile is wool, knotted in the<em>symmetrical (Turkish)</em> knot — the same knot as Heriz and Tabriz, geographically expected for the Azeri-Turkic and Armenian populations of the Caucasus. Knot density is moderate to low — fifty to eighty knots per square inch is typical, with some rougher village pieces lower still — which is the structural enabling condition for the bold geometric vocabulary the Kazak tradition has settled on. The pile is<em>long and shaggy</em> — notably longer than Persian workshop pile — which gives the Kazak its distinctive sheepskin-like surface character and contributes to the rug&rsquo;s substantial physical weight per square foot despite its small format.</p><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural evidence by which a Kazak is identified at close range and its provenance dated and attributed.</p><p>The foundation, first, and this is the principal evidence one is reading for. A Caucasian Kazak has<em>wool warp and wool weft.</em> The wool foundation is the single most diagnostic feature of the type and the easiest to verify: turn the rug over and look at the fringe (the cotton warp of a Persian rug is white and tightly twisted; the wool warp of a Caucasian rug is off-white or cream and softer, sometimes with visible lanolin sheen) and look at the back of the rug between the rows of knots (the cotton weft of Persian work is a tight white horizontal line; the wool weft of Caucasian work is wider, woollier, and often shows in the same dyed colour as the foundation). The contrast with the cotton-foundation Persian tradition of Heriz and Tabriz is unmistakable to a trained hand, and the rug&rsquo;s drape and weight will themselves often signal the foundation before close inspection confirms it.</p><figure><img src="/images/posts/caucasian-kazak/detail-knot.png" alt="A close detail of the back of a Kazak rug at magnification — symmetrical Turkish knots in long-pile wool on a wool foundation, with the woollier weft visible between rows of knots and the off-white wool warp visible at the edge"><figcaption><p>A close detail of the back of a Kazak rug at magnification — symmetrical Turkish knots packed at moderate density (fifty to eighty knots per square inch) in long-pile wool on a wool foundation, with the characteristically wider wool weft visible as a soft horizontal line between rows of knots, and the off-white wool warp visible at the cut edge. The wool foundation is the most diagnostic single feature of the Caucasian tradition and the surest visual separator from the cotton-foundation Persian work shown in the previous two rug posts. Turn the rug over and look: cotton warp is tightly-twisted white, wool warp is off-white and softer, often with visible lanolin sheen.</p></figcaption></figure><p>The knot, second, is the symmetrical (Turkish) knot, with the wool wrapped around two adjacent warps and pulled down between them. A Caucasian rug with the asymmetric (Persian) knot is exceptional and should provoke immediate scepticism about the attribution — the entire Caucasian region uses the Turkish knot consistently, and a Persian-knot rug attributed to the Caucasus is more likely a misattribution than an unusual exception.</p><p>The knot density, third, is moderate to low — fifty to eighty knots per square inch is the Kazak commercial range, with the better Karachov pieces sometimes reaching a hundred and the rougher village pieces dropping to forty or below. The low knot count is, as with Heriz, what enables and requires the bold geometric vocabulary. A finer Caucasian piece (Daghestan, Shirvan, the finer Kuba sub-types) will run a hundred and fifty or more knots per square inch; a Kazak running a hundred is at the upper end of the type&rsquo;s range.</p><p>The wool of the pile, fourth, is the distinguishing material signature. Kazak wool comes from the regional flocks of Azerbaijani and Armenian highland sheep, and it is high in lanolin, coarse-fibred, and takes the natural dyes with particular saturation. The long shaggy pile is partly a function of the wool&rsquo;s character — finer-fibred wool would not give the same effect even cut to the same length — and is one of the reasons that an antique Kazak with its original full pile has a distinctively warm, almost sheepskin-like character at the surface that synthetic-dyed or machine-spun modern reproductions cannot reproduce.</p><p>The dyes, fifth, are entirely vegetable in the antique pieces. Madder for the dominant reds (sometimes combined with lac for the deeper tomato variants); indigo for the navy and the deeper blues; isparek (Persian buckthorn) or weld for the yellows; the various plant-derived greens; tinging agents (walnut hull, pomegranate rind) for the browns. The Caucasian palette is somewhat narrower than the Persian — fewer accent colours, more concentrated on the red-indigo-ivory triad — but the dyes are deployed at greater saturation than in any Persian tradition. The synthetic aniline dyes that became available in the region after about 1880 are present in some commercial Kazak production from the 1890s onward; an antique Kazak from this period may show a mix of vegetable and aniline dyes, and learning to distinguish the natural saturation from the chemical saturation is one of the period&rsquo;s particular pleasures (and pitfalls).</p><p>The selvedges of a Kazak are wrapped in wool, usually in alternating bands of two contrasting colours (typically a checkerboard pattern of indigo and ivory, or indigo and red). The ends are typically finished with a substantial kilim section of plain weave in alternating coloured bands, often six to twelve inches deep on the better pieces, before the wool-warp fringe. The Caucasian end-finish is more elaborate than the Persian, and a Kazak with its original kilim ends and wool fringe intact is increasingly rare as household wear shortens both over time.</p><h2 id="the-region">The Region</h2><p>The Caucasus is the mountain region between the Black Sea and the Caspian Sea, comprising what is now Azerbaijan, Armenia, Georgia, parts of Dagestan in the Russian North Caucasus, and the easternmost portion of northeastern Turkey. The population is and has historically been a mix of Azerbaijani-Turkic, Armenian, Georgian, Kurdish, Russian-settler, and various smaller mountain peoples. The principal weaving regions for the Kazak trade are concentrated in the southwestern Caucasus — the historical<em>Ganja province</em> (now around the modern Azerbaijani city of Ganja, formerly Elisabethpol or Elisavetpol under the Russian Empire), the<em>Karabagh region</em> of western Azerbaijan, the<em>Lori-Pambak region</em> of northern Armenia, the<em>Borchalo region</em> of southern Georgia, and the<em>Akstafa region</em> of north-western Azerbaijan.</p><p>The Kazak name itself, despite its similarity to<em>Kazakh,</em> has no etymological or actual relationship to the modern country of Kazakhstan. The name comes from the<em>Cossack</em> peoples of the Russian-Caucasian frontier — Turkic-and-Slavic warrior populations who settled the southwestern Caucasian highlands from the seventeenth century onward and who, in the European-collector market of the late nineteenth century, became associated with the bold geometric rugs of the region in a way that produced the current trade name. Whether the actual weavers of the canonical Kazak rugs were ethnically Cossack is doubtful — most production was by Azerbaijani Turkic and Armenian village women — but the name attached itself to the type in the European collector vocabulary of the 1880s and 1890s and has remained.</p><p>The carpet-weaving tradition of the Caucasus can be documented to the medieval period. The famous<em>Dragon carpets</em> of the seventeenth century — large carpets, sometimes ten or twelve feet long, with stylised dragons rendered in palmette-and-cartouche compositions on dark red grounds, woven for the Safavid and Ottoman court markets in the Karabagh region — are the documentary antecedent of the modern Caucasian tradition. Surviving Dragon carpets are now in major museum collections (the Metropolitan Museum, the Victoria and Albert, the Textile Museum in Washington) and establish the formal vocabulary from which the later Caucasian rugs descend, even when the descent is at considerable simplification. The intermediate<em>Eagle Kazaks</em> (sometimes called<em>Adler Kazaks</em> or<em>Chelaberd Kazaks</em>) of the eighteenth century are the simplifying link between the elaborate Dragon carpets and the bold geometric Kazaks of the nineteenth century — large stylised eagle or double-headed bird motifs that gradually simplified into the medallion vocabulary of the later type.</p><figure><img src="/images/posts/caucasian-kazak/antecedent.png" alt="A seventeenth-century Caucasian Dragon carpet — stylised dragons rendered in palmette-and-cartouche composition on a dark red ground, in the formal Safavid court vocabulary that the later Caucasian tradition descended from"><figcaption><p>A seventeenth-century Caucasian Dragon carpet from the Karabagh region — stylised dragons (the long curving forms in the lower portion of the field) rendered in a palmette-and-cartouche composition on a dark red ground, woven for the Safavid court market. The Dragon carpets are the documentary antecedent of the modern Caucasian tradition: surviving examples in the Metropolitan Museum, the Victoria and Albert, and the Textile Museum in Washington establish the formal vocabulary from which the later Kazak descended through several centuries of progressive simplification. The intermediate Eagle Kazaks of the eighteenth century are the bridge between this elaborate court vocabulary and the bold geometric Kazaks of the nineteenth-century European export market.</p></figcaption></figure><p>The modern Kazak export market emerged in the 1850s and 1860s as the Russian Empire, which had completed the annexation of the southern Caucasus from Persia in 1828 (the Treaty of Turkmenchay), opened the region to European trade. The principal export route was through<em>Tiflis</em> (modern Tbilisi, the capital of Georgia), then by road to<em>Batumi</em> on the Black Sea coast, then by ship to European ports. The completion of the<em>Caucasian Railway</em> connecting Tiflis to the Russian rail network in the 1880s accelerated the trade considerably, and by 1890 the Caucasian rugs were a substantial category in the European collector market — sold particularly through Vienna, Munich, Hamburg, and London, with a smaller American market through New York and Boston.</p><p>The peak period of Kazak production was roughly 1870 to 1914. The First World War, the Russian Revolution, and the subsequent Soviet collectivisation of the 1920s and 1930s effectively ended the commercial export tradition: village production continued at substantially reduced volume and quality through the Soviet period, with most Soviet-era Caucasian production being made for Soviet domestic use rather than for the European market. By 1990 the village weaving tradition of the Caucasus had largely disappeared as a continuing commercial activity, surviving only in revivals and in modern collector-market reproductions that have themselves become a category of their own.</p><figure><img src="/images/posts/caucasian-kazak/workshop-page.png" alt="A page from a Victorian connoisseur's portfolio on the Caucasus rug-weaving region — district map locating the principal sub-regions of Caucasian weaving (Ganja, Karabagh, Lori-Pambak, Borchalo, Akstafa, Shirvan, Kuba, Daghestan), with design archetypes for the principal Kazak sub-types"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Caucasus rug-weaving region — the district map locating the principal sub-regions of Caucasian weaving (Ganja, Karabagh, Lori-Pambak, Borchalo, Akstafa in the south-western Kazak-producing zone; Shirvan, Kuba, Daghestan in the eastern and northern finer-weaving zones) on a map of the southern Caucasus, with three small archetype rug drawings at the bottom showing the principal Kazak sub-type designs (Karachov medallion, Lori-Pambak diamond, Sewan anchor-hook). The plate is the kind of reference page that would have appeared in the serious European dealer portfolios of the 1880s and 1890s, and is what one consults when trying to locate a candidate Caucasian rug within the broader regional taxonomy.</p></figcaption></figure><p>A note on the dating of antique Kazaks, because the chronology matters for both collector interest and price.<em>Pre-1860</em> pieces are rare and largely museum-held.<em>1860–1880</em> pieces (the first generation of the modern export trade) are the most-prized antique Kazaks and command the highest current prices — these are the pieces with the fullest vegetable-dye palette, the most individualistic weavers&rsquo;-hand drawing, and the most authentic tribal character.<em>1880–1900</em> pieces are the standard antique-grade — solid commercial work, often still on natural dyes, generally well-drawn, the substantial bulk of the surviving antique inventory.<em>1900–1914</em> pieces are still antique by most dealer definitions but often show the first aniline-dye intrusions and somewhat more standardised drawing.<em>1914–1920s</em> pieces are increasingly rare as wartime and revolution disrupted production.<em>Soviet-era</em> (1920s–1980s) Caucasian production is generally not classed as antique in the collector vocabulary, with quality varying considerably across the period.</p><h2 id="what-it-is-not">What It Is Not</h2><p>Several rug types stand near enough to Kazak that the beginner confuses them with it, and distinguishing them is most of the work of reading the Caucasian weaving tradition.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/caucasian-kazak/sibling-karabagh.png" alt="A Caucasian Karabagh rug — softer drawing than Kazak, often with French-influenced rose floral motifs in the field, finer knot count, sometimes a darker ground" loading="lazy"/><figcaption>Karabagh<em>— the refined Caucasian neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/caucasian-kazak/sibling-shirvan.png" alt="A Caucasian Shirvan rug — smaller-format scatter rug with smaller knot count, more rectilinear allover field design, often prayer-rug format, considerably finer drawing than Kazak" loading="lazy"/><figcaption>Shirvan<em>— the eastern Caucasian fine-knot</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/caucasian-kazak/sibling-kuba.png" alt="A Caucasian Kuba rug — the finer of the eastern Caucasian traditions, with allover small-pattern field design, refined drawing, generally on a darker ground than Kazak" loading="lazy"/><figcaption>Kuba<em>— the finer eastern Caucasian</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/caucasian-kazak/sibling-heriz.png" alt="A Persian Heriz rug — the geographically nearest Persian type to the Kazak region, with stepped octagonal indigo medallion on brick-red field, ivory spandrels, walnut border, cotton foundation" loading="lazy"/><figcaption>Heriz<em>— the Persian cousin across the frontier</em></figcaption></figure></div><figcaption>Four rug types most often confused with Kazak, drawn for comparison.</figcaption></figure><p>A<em>Karabagh</em> is the rug from the Karabagh region of southwestern Azerbaijan — the same broader geographic zone as the Kazak-producing villages, but with a distinct workshop-and-village tradition that produced rugs of more refined drawing and (after about 1850) often with French-influenced floral vocabulary in the field. The &ldquo;Karabagh rose&rdquo; — a stylised pink-and-red rose drawn in the late-nineteenth-century European-decorator manner — appears on many Karabagh rugs of the period and is a strong identifier of the type. Karabagh rugs often have a darker overall palette than Kazak (deeper reds, navy grounds rather than brick-red), and the drawing is more refined and less aggressively tribal. The rule of thumb: bold tribal medallion with latch-hook border is Kazak; refined Karabagh-rose vocabulary on a darker ground is Karabagh.</p><p>A<em>Shirvan</em> is the rug from the Shirvan region of eastern Azerbaijan (around modern Baku). Shirvan rugs are typically smaller than Kazak (three by five to four by six feet is common), with substantially finer knot count (a hundred to a hundred and fifty kpsi rather than the Kazak&rsquo;s fifty to eighty), more rectilinear allover field designs (less emphasis on the bold central medallion), and often in prayer-rug format with the characteristic mihrab arch. Shirvan is one of the finer Caucasian traditions, and the type&rsquo;s smaller format and finer drawing place it closer to the eastern Caucasian finer-weaving zone (Kuba, Daghestan) than to the Kazak&rsquo;s southwestern tribal zone. The rule of thumb: large bold geometric medallion in saturated red is Kazak; small finely-knotted rectilinear allover field is Shirvan.</p><p>A<em>Kuba</em> is the rug from the Kuba region of northeastern Azerbaijan (around the city of Kuba on the Caspian-coast plain). Kuba is the finer of the Caucasian traditions, with multiple distinctive sub-types (<em>Konagkend, Perepedil, Seichour, Chichi</em>) each of which has its own characteristic vocabulary. Kuba rugs generally have small-pattern allover field designs rather than bold central medallions, often quite refined drawing, and the<em>Perepedil</em> sub-type in particular carries the distinctive &ldquo;wurma&rdquo; (curling-ram&rsquo;s-horn) motif that is a strong Kuba identifier. Kuba rugs are smaller than Kazak (the format is typically three by five to five by seven), and the finer drawing and quieter palette distinguish them visually at a distance. The rule of thumb: bold saturated central medallion is Kazak; refined small-pattern allover field with characteristic sub-type motifs is Kuba.</p><p>A<em>Heriz</em> — the Persian village rug treated in the first post in the arc — is the most-confused-with type for the Kazak beginner, because the two traditions share a great deal of design vocabulary (bold geometric, stepped medallion, ivory spandrels, saturated reds), share the Turkish knot, and sit only sixty kilometres apart geographically. The decisive separator is the foundation: Heriz is cotton, Kazak is wool. The secondary separators are: the Kazak palette is more saturated (deeper tomato-red versus Heriz brick-red, deeper indigo versus Heriz navy); the Kazak format is smaller (Kazak is four-by-six to six-by-eight, Heriz is room-size); the Kazak border is latch-hook (Heriz uses a walnut-brown vine-and-palmette pattern); the Kazak knot count is lower than Heriz (fifty to eighty kpsi versus Heriz&rsquo;s sixty to a hundred). Together these differences are sufficient to separate the two types reliably, but the design vocabulary is similar enough that a careful inspection is required for a candidate piece. The rule of thumb: wool foundation, smaller format, more saturated palette, latch-hook border is Kazak; cotton foundation, room-size, brick-red palette, walnut border is Heriz.</p><p>These are the four most-confused-with types within the Caucasian tradition and across the immediate Persian frontier. There are others (the Turkmen<em>Tekke</em> and<em>Yomut</em> share some Kazak vocabulary but use Turkmen-specific<em>gul</em> motifs and a darker overall palette; the various smaller Caucasian villages produce idiosyncratic local variants), but the four above account for the great majority of misattributions in the wild.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Caucasian Kazak, when one is standing in front of a candidate rug, comes down to a short ordered checklist.</p><p>One looks first at the foundation.<em>Wool warp and wool weft</em> is the Caucasian signature. Cotton foundation makes it a Persian rug — most likely Heriz, Bidjar, or one of the central-Iranian workshop traditions. Inspect the fringe (white tight cotton versus off-white soft wool) and the back of the rug (cotton weft as a tight white line versus wool weft as a wider woollier line). The foundation is decisive at first inspection and is the single most important evidence the post is teaching the reader to read.</p><p>One looks next at the format.<em>Four-by-six to six-by-eight</em> is the canonical Kazak range. A<em>runner</em> format (three feet wide and seven to twelve long) is consistent with Kazak (particularly Akstafa). A<em>room-size</em> format (nine by twelve or larger) is inconsistent with Kazak and suggests Persian provenance — even with wool foundation, a room-size geometric rug is unlikely to be Kazak.</p><p>One looks at the design vocabulary.<em>Bold geometric medallion</em> — stepped angular outline, often with smaller medallions stacked above and below, scattered geometric ornaments across the field, latch-hook border — is the Kazak signature. If the design is curvilinear it is not Caucasian at all. If the design is geometric but with a refined small-pattern allover field, it is more likely Shirvan or Kuba than Kazak. If the design is the Karabagh-rose floral vocabulary, it is Karabagh.</p><p>One looks at the palette.<em>Deep tomato-red ground, deep indigo medallion, vibrant ivory spandrels</em> with yellow and green accent colours is the Kazak palette. If the palette is brick-red and walnut and muted ivory, the rug is more likely Heriz. If the palette is the darker navy-and-burgundy of the eastern Caucasus, the rug is more likely Karabagh or Shirvan.</p><p>One looks at the border.<em>Wide latch-hook border</em> with one or two narrower latch-hook guard bands is the Caucasian signature. The latch-hook is the surest single visual identifier of Caucasian (versus Persian) provenance, and its presence settles much of the regional question on first inspection.</p><p>One looks at the knot.<em>Symmetrical Turkish knot</em> at<em>fifty to eighty knots per square inch</em> is the Kazak commercial range. The Turkish knot is expected; a Persian-knot rug attributed to the Caucasus warrants scepticism. The low knot density is consistent with the bold vocabulary the type uses.</p><p>One looks at the pile.<em>Long shaggy wool pile</em> with substantial physical weight per square foot is the Kazak character. If the pile is short and finely cut, the rug is more likely Persian workshop or one of the finer Caucasian types (Kuba, Daghestan, Shirvan).</p><p>And one looks at the wear pattern and the dyes. Vegetable dyes age into patina; aniline dyes age into flatness. In the better antique pieces (pre-1900) one is looking at vegetable dyes throughout; in the 1900–1914 period the mix is common; in Soviet-era pieces the dyes are often mixed or entirely synthetic. The wear pattern of an old Kazak is silvery in the high-traffic centre, more saturated in the protected margins, and the long pile means the worn areas are more visible than on a short-pile rug.</p><p>The next post in the rug arc will be either Bakshaish — the older Heriz district village tradition that the Heriz post pointed toward but did not treat in detail, and which would complete the northwestern Persian triangle (Heriz / Tabriz / Bakshaish) — or one of the eastern Caucasian types (most likely Shirvan or Kuba), which would extend the Caucasian region now opened. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Louis XVI</title><link>https://mtclinton.com/posts/louis-xvi/</link><pubDate>Fri, 15 May 2026 17:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/louis-xvi/</guid><category>antiques</category><description>Second per-subject post in the Reading the Period Cabinet arc — the neoclassical reaction that displaced the rocaille, the principal stylistic shift in eighteenth-century French furniture, and the period of Riesener and Marie Antoinette.</description><content:encoded>&lt;![CDATA[<p>The cabriole leg disappears. The bombé case straightens into a rectangle with canted corners. The floral marquetry bouquet shifts to a geometric trellis. The rocaille scrollwork of the ormolu mounts gives way to Greek-key borders, laurel-wreath swags, and the paterae and urns of the antique Roman vocabulary. The asymmetric balance of the rocaille becomes the rigorous symmetry of the neoclassical. The Louis XVI style, in essence, is the inverse of the Louis XV style across every register in which the cabinet-maker had to make a decision, and the transition between the two — over a fifteen-year period from roughly 1760 to 1775 — is the single most thoroughly documented and most consequential stylistic shift in the history of European furniture.</p><p>This is the second post in<em>Reading the Period Cabinet,</em> the furniture arc of the<a href="/posts/reading-the-antique/">antiques series</a>. It treats Louis XVI second because Louis XVI is the direct successor to the<a href="/posts/louis-xv/">Louis XV</a> the previous furniture post described, and because the two styles together — curve and straight line, rocaille and neoclassical, asymmetry and symmetry — establish the principal stylistic axis along which every other eighteenth-century European furniture tradition can be located. The same logic that put Tabriz immediately after Heriz on the rug side puts Louis XVI immediately after Louis XV on the furniture side; getting the two pairs in place is what makes the rest of the arc legible.</p><p>This post follows the same template as the Louis XV: what a canonical Louis XVI piece looks like, the structural and material evidence by which one identifies it, the historical and patron context that produced it, the styles most often confused with it, and the practical identification discipline by which a candidate piece is read.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Louis XVI piece, as with the Louis XV, is the commode, and the commode is what the rest of the post will principally describe. Other forms — the<em>bureau plat,</em> the<em>secrétaire à abattant,</em> the<em>bonheur du jour,</em> the<em>bergère,</em> the<em>fauteuil,</em> the<em>athénienne,</em> the various console and side-table forms — carry the same vocabulary in their respective registers, and the principal moves of the style are most fully concentrated in the commode.</p><p>A canonical Louis XVI commode, then. It stands on four straight legs — most often<em>fluted columnar</em> legs, tapered like classical columns, with vertical fluting (sometimes with the upper third left plain in the manner called<em>stop-fluting</em>), and terminating in either a small turned<em>toupie</em> foot or a square<em>spade</em> foot. The legs may be square in section or round, with the round columnar form being the more characteristically neoclassical and the square form being the more frequently seen in commercial work. The legs are connected to the case by a small chamfered transition rather than the curving apron that characterised the Louis XV. There is no cabriole anywhere on the piece.</p><p>Above the legs, the case rises straight and presents itself in a strongly rectangular silhouette: the front is flat or very gently curved, the sides are flat, the corners are<em>canted</em> — chamfered at forty-five degrees rather than rounded as on the Louis XV — and the proportions are taller and more architectural than the Louis XV. The case is two drawers tall, sometimes three, and presents either three discrete drawer fronts (each treated as a separate panel of marquetry) or a continuous front with the drawer divisions rendered subordinately. The continuous-front treatment that the Louis XV preferred is, on the Louis XVI, often broken up by central marquetry panels that themselves frame a Sèvres porcelain plaque or a marquetry portrait medallion.</p><p>The decorative apparatus — marquetry, ormolu, marble — continues to consist of the same three components as on the Louis XV, but each component carries an entirely different vocabulary.</p><p>The marquetry, first. A Louis XVI commode of the high period (1775–1790) carries<em>geometric</em> marquetry rather than floral. The dominant patterns are: the<em>trellis</em> (a repeating diamond pattern in alternating light and dark woods), the<em>cube</em> (a three-dimensional cube illusion in three contrasting tones), the<em>chevron</em> (zigzag arrangements), and various<em>parquetry</em> patterns of star-and-rosette repeats. Where pictorial marquetry persists — and it does persist, particularly in the central panels of the better commodes — the subject matter shifts from floral bouquets to neoclassical motifs: trophies of musical instruments, garland-tied wreaths, urns with flowers, classical figures in cameo. The species of wood remain those of the Louis XV (kingwood, tulipwood, rosewood, satinwood, sycamore, holly), but the compositions are different.</p><p>The ormolu, second. Louis XVI ormolu mounts are unmistakably neoclassical in vocabulary. The signature elements are:<em>Greek-key borders</em> along the upper edge of the case (above the top drawer),<em>laurel-wreath swags</em> draped across the central drawer or framing the central panel,<em>ribbon-tied garlands</em> above the apron,<em>paterae</em> (oval rosettes with radiating petals) at the corners and at the tops of the legs,<em>urns</em> and<em>vases</em> at the centres of side panels,<em>bucrania</em> (ox-skull motifs) and<em>guilloche</em> borders at finer pieces, and<em>acanthus capitals</em> at the tops of the columnar legs. The ornament is rigorously symmetric — every motif mirrored across the central axis of the piece — and the chasing of the bronze is finer and more architecturally precise than the rocaille work of the Louis XV.</p><p>The marble, third. Louis XVI marble tops continue from the Louis XV in material (the same period quarries:<em>brèche d&rsquo;Alep, sarrancolin, rouge royal,</em> white Carrara, Languedoc) but with the edges flat-moulded rather than serpentine. White Carrara becomes more common during the period, in keeping with the neoclassical preference for the Greek-Roman white-marble tradition over the polychromatic French preferences of the Louis XV.</p><p>Assembled together — straight fluted columnar legs, rectangular canted-corner case, geometric or neoclassical marquetry, neoclassical ormolu in Greek-key and laurel-wreath vocabulary, marble top with flat-moulded edges — these are the canonical components. The variations within the type are considerable; the components themselves do not vary.</p><figure><img src="/images/posts/louis-xvi/detail-leg.png" alt="A close detail of a Louis XVI fluted columnar leg — straight tapered profile with vertical fluting, ormolu acanthus capital and base, terminating in a small toupie foot"><figcaption><p>A close detail of a Louis XVI fluted columnar leg — the straight tapered profile that defines the period, with vertical fluting (here in the stop-fluted variant where the upper third is left plain), an ormolu acanthus capital at the top where the leg meets the case, an ormolu base above a small turned toupie foot. The straight columnar form is the inverse of the Louis XV cabriole, and the move from curve to straight line is the single most diagnostic move of the period. A Louis XV commode reads at three paces by its legs; a Louis XVI commode reads at three paces by the same logic, in the opposite direction.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural and material evidence by which a Louis XVI piece is identified at close range and its provenance dated and attributed.</p><p>The leg, first. The cabriole is gone. A Louis XVI leg is straight, almost without exception — the only variation worth noting is between the<em>fluted columnar</em> leg (round in section, with vertical fluting, terminating in a turned toupie foot) and the<em>square tapered</em> leg (square in section, with no fluting or with a small chamfer at the corners, terminating in a square spade foot). The columnar form is the more characteristically high-Louis-XVI; the square tapered form is more frequently seen in provincial work and in the cheaper Parisian commercial production. Either way, the leg is straight; if it curves, the piece is not Louis XVI proper but Louis XV or a Transition piece or one of the nineteenth-century revivals that intermixed the vocabularies.</p><p>The case, second. The carcase construction continues to use solid oak (Parisian work) or pine and walnut (provincial and German), with veneers of exotic woods and marquetry on the visible surfaces. The dovetail joinery of the carcase is identical to the Louis XV in technique and tooling. The drawer construction uses through-dovetails at the corners, hand-cut, with irregular spacing characteristic of pre-machine work. The case proportions are taller and more rectangular than the Louis XV, with the canted corners providing the only curve in the piece.</p><p>The marquetry, third. The wood species used by the major Louis XVI ébénistes are the same as those of the Louis XV ébénistes — the period was continuous in its supply chain even as it discontinuous in its decorative vocabulary — and the principal makers (Riesener pre-eminent among them) bridged both periods personally. What changes is the composition. A Louis XVI commode by Riesener of the 1780s will use the same kingwood and tulipwood and satinwood that a Louis XV commode by BVRB of the 1750s used, but in geometric trellis or parquetry rather than in floral bouquets, and often with central panels framing a Sèvres porcelain plaque or a marquetry trophy of musical instruments.</p><figure><img src="/images/posts/louis-xvi/detail-marquetry.png" alt="A close detail of Louis XVI geometric marquetry — a trellis of small lozenges in alternating kingwood and tulipwood, framed by a Greek-key border in stained holly"><figcaption><p>A close detail of Louis XVI geometric marquetry — a trellis of small lozenges in alternating kingwood and tulipwood, framed by a stop-fluted border in pale satinwood and a Greek-key border in stained holly. The vocabulary is rigorously geometric: every motif a mathematical figure rather than a botanical one. Where Louis XV marquetry was a ribbon-tied bouquet of roses naturalistically rendered, Louis XVI marquetry is a parquetry of small geometric repeats — and the same workshop that produced the Louis XV bouquets produced the Louis XVI trellises a decade later, often using the same exotic woods in different arrangement.</p></figcaption></figure><p>The ormolu, fourth. The mounts of a Louis XVI piece continue to be mercury-fire-gilded bronze, and the chasing quality of the high-period work is comparable to or better than the Louis XV — the<em>bronziers</em> of the Louis XVI period (Pierre Gouthière pre-eminent among them) produced ormolu of an architectural precision that was, at its best, the highest-quality bronze decorative work ever made. The vocabulary is unmistakably neoclassical: Greek-key bands, laurel-wreath swags, paterae, urns, ribbon-tied garlands, palmettes. A piece without any of these motifs and with rocaille scrollwork instead is Louis XV; a piece with martial trophies and Egyptian motifs and heavier classical ornament is Empire; a piece with the Louis XVI vocabulary is Louis XVI.</p><figure><img src="/images/posts/louis-xvi/detail-mount.png" alt="A close detail of a Louis XVI ormolu mount — a laurel-wreath swag with ribbon ties, framed by a Greek-key border, over a fluted ground"><figcaption><p>A close detail of a Louis XVI ormolu mount — a laurel-wreath swag tied at each end with a flowing ribbon, framed above by a Greek-key border, set against a ground of vertical fluting. The neoclassical vocabulary is exact: every motif drawn from the antique Roman repertory of architectural ornament. The chasing of the bronze, by Pierre Gouthière or one of his contemporary bronziers, is of an architectural precision the rocaille-period craftsmen had not been concerned with — the laurel leaves are rendered with the regularity of a frieze, the ribbon ties fall in symmetric S-curves, the Greek key is geometrically exact.</p></figcaption></figure><p>The stamp, fifth. The Parisian guild stamp requirement (JME + maker&rsquo;s name, instituted in 1751) continues unchanged through the Louis XVI period, and the surviving body of stamped Louis XVI work is, if anything, more comprehensively documented than the Louis XV — the period is closer to the modern era and more pieces survive with their stamps intact.<em>Riesener</em> (who became master in 1768 and worked through the 1780s) is the most-documented Louis XVI ébéniste and the maker whose stamp on a piece commands the highest premium.<em>Adam Weisweiler</em> (master 1778),<em>Martin Carlin</em> (master 1766, working through the 1780s),<em>David Roentgen</em> (the German-born master, working in Paris and at the German courts),<em>Bernard Molitor</em> (late Louis XVI / Directoire),<em>Jean-François Leleu</em> (master 1764) are the other principal names whose stamps make a piece documented work.</p><p>The marble, sixth, continues from the Louis XV with the noted shift toward white Carrara as the more characteristically neoclassical option, with the colored period marbles continuing in use particularly for the more ornate or more royal pieces.</p><p>These are the physical facts. They are what one is reading for. They differ from the Louis XV at every register of decoration but at no register of construction — the cabinet-making craft itself was continuous across the transition, and the same workshops produced both styles.</p><h2 id="the-period">The Period</h2><p>The Louis XVI style proper runs from approximately 1760, when the early signs of the neoclassical reaction begin appearing in late-Louis-XV pieces (the<em>Transition</em> period of the late 1760s and early 1770s), through to roughly 1790, when the Revolution effectively ended the great Parisian ébéniste workshops and the<em>Directoire</em> austerity began. The named monarch reigned from 1774 (when Louis XV died) through to his deposition in 1792 and his execution in 1793; the style proper, however, predates his accession and has its origins in the broader European neoclassical movement of the 1750s and 1760s.</p><p>The neoclassical movement itself had three principal sources, each documented at the time and traceable in subsequent scholarship. The first was archaeological: the rediscovery and excavation of Pompeii (begun 1748 under Bourbon Naples, with the publication of the<em>Antichità di Ercolano</em> volumes through the 1750s and 1760s), which made the actual visual vocabulary of Roman domestic interiors available to European designers for the first time since antiquity. The second was theoretical: Johann Joachim Winckelmann&rsquo;s<em>Gedanken über die Nachahmung der griechischen Werke</em> (1755) and his<em>Geschichte der Kunst des Altertums</em> (1764), which articulated the aesthetic argument for the superiority of Greek classical art over the rococo style then dominant. The third was political and cultural: the increasing weariness of the French court and Parisian bourgeoisie with the perceived excesses of the rocaille, and the search for a more restrained and more morally serious aesthetic for the new generation of patrons.</p><p>The Transition (1760–1775) is the bridge from the high Louis XV to the high Louis XVI. Pieces of this period — many of them by makers who would go on to be the principal Louis XVI ébénistes (Riesener especially, who became master in 1768 and produced Transition work for several years before settling into the high Louis XVI) — combine elements of both vocabularies in ways that are sometimes labelled as one style and sometimes as the other depending on which elements the dealer wishes to emphasise. A Transition commode might have a still-curved bombé case but with neoclassical ormolu mounts; or straight fluted legs but with floral marquetry; or symmetric composition but with rocaille corner mounts. These pieces are particularly prized by collectors for the documentary evidence they provide of the stylistic shift, and a clearly-attributable Transition piece by a major maker can fetch prices comparable to or exceeding the equivalent high-period work.</p><p>The high Louis XVI (1775–1790) is the period of the great workshops at the height of their refinement. Marie Antoinette (queen consort from 1774, the principal patron of the period) commissioned extensively from Riesener, Carlin, Weisweiler, and the other major ébénistes, particularly for her residences at the Petit Trianon and Saint-Cloud. The<em>Garde-Meuble Royal,</em> continuing from the Louis XV period, was the largest single patron and the institution whose surviving inventories provide the documentary basis for much of modern attribution. The wealthy financial bourgeoisie — the<em>fermiers généraux</em> (tax-farmers) and the bankers of the rue Saint-Honoré — were the second-tier patrons, and their commissions sustained the workshops that the royal commissions alone could not have supported.</p><figure><img src="/images/posts/louis-xvi/pattern-book-page.png" alt="A page from a Victorian portfolio on Louis XVI furniture — engraved drawings of the principal forms (commode, bureau plat, secrétaire, console, fauteuil, athénienne) with annotations"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on Louis XVI French furniture — engraved drawings of the principal forms (the commode, the bureau plat, the secrétaire à abattant, the console table, the fauteuil, the athénienne tripod stand) arranged as a nineteenth-century cabinet-maker&rsquo;s reference plate, with explanatory annotations on the proportions, the principal ornamental moves, and the rectilinear-and-symmetric composition principles. The plate is the kind of reference page that would have appeared in a serious dealer&rsquo;s portfolio of the period, and it is what one consults when trying to identify the form of an unfamiliar Louis XVI piece in the dealer&rsquo;s storeroom.</p></figcaption></figure><p>The late Louis XVI / pre-Directoire period (1789–1795) is the period of the Revolution&rsquo;s effects on the workshops. The flight of the aristocracy and the dissolution of the<em>Garde-Meuble</em> in 1792 destroyed the principal patronage system; many of the great ébénistes (including Riesener) lost their primary client base and ended their careers in straitened circumstances. The Directoire (1795–1799) that followed continued the Louis XVI vocabulary in stripped-down form: the geometric marquetry persisted, the straight legs persisted, the neoclassical ormolu persisted, but the materials were cheaper, the chasing less refined, the production smaller in volume. The Empire (1804–1815) that followed the Directoire reintroduced opulence in a heavier register.</p><figure><img src="/images/posts/louis-xvi/antecedent.png" alt="A Louis XV / Transition commode — bombé case still curving but with early neoclassical ormolu vocabulary, the antecedent style out of which the high Louis XVI emerged"><figcaption><p>A Louis XV / Transition commode — the bombé case still curving in the Louis XV manner but with early neoclassical ormolu vocabulary appearing in the mounts (a Greek-key border at the top, neoclassical paterae at the corners) and with the floral marquetry beginning to give way to geometric trellis in the side panels. The Transition period (roughly 1760–1775) is where the Louis XV bones meet the Louis XVI surface, and pieces of this period by major makers — Riesener especially in his early career — are among the most prized and most documentary of the eighteenth-century French furniture corpus.</p></figcaption></figure><p>A note on the named ébénistes who bridge the two periods.<em>Jean-Henri Riesener</em> (1734–1806, master 1768) is the principal ébéniste of the Louis XVI period and the maker whose work most clearly demonstrates the stylistic continuity-within-change between the Louis XV and the Louis XVI. Riesener was apprenticed to Jean-François Oeben (the great Louis XV master), inherited Oeben&rsquo;s workshop on his death in 1763, and produced both Transition pieces in the late 1760s and high Louis XVI pieces through the 1780s. His career spans the entire stylistic shift, and a comparative study of his early and late work is the closest thing to a controlled experiment in the history of European furniture stylistic change.</p><h2 id="what-it-is-not">What It Is Not</h2><p>Several styles stand near enough to Louis XVI that the beginner confuses them with it, and distinguishing them is most of the work of reading European late-eighteenth-century furniture.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/louis-xvi/sibling-louis-xv.png" alt="A Louis XV commode with bombé and serpentine case on cabriole legs, floral marquetry, rocaille ormolu mounts, marble top with serpentine edge" loading="lazy"/><figcaption>Louis XV<em>— the rocaille antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xvi/sibling-empire.png" alt="An Empire commode in dark mahogany with massive rectangular case, columnar legs with martial gilt-bronze mounts (eagles, swords, laurel wreaths), heavier proportions and military vocabulary throughout" loading="lazy"/><figcaption>Empire<em>— the Napoleonic successor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xvi/sibling-hepplewhite.png" alt="An English Hepplewhite chest of drawers in carved mahogany, with straight tapered square legs, oval brass drawer pulls, no veneered marquetry, and the restrained neoclassical vocabulary of George Hepplewhite's Cabinet-Maker and Upholsterer's Guide of 1788" loading="lazy"/><figcaption>English Hepplewhite<em>— the Anglophone neoclassical</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xvi/sibling-gustavian.png" alt="A Swedish Gustavian commode in pale Swedish painted finish (Trianon gris-blanc), with straight fluted columnar legs, restrained neoclassical ormolu, the Louis XVI vocabulary translated into the Scandinavian palette of the Gustav III court" loading="lazy"/><figcaption>Swedish Gustavian<em>— the painted northern transposition</em></figcaption></figure></div><figcaption>Four styles most often confused with Louis XVI, drawn for comparison.</figcaption></figure><p>The first is the<em>Louis XV</em> (1730–1770, the immediate antecedent), which the Louis XVI displaced. The principal separator is the leg: cabriole versus straight columnar, curve versus geometric line. The case shape is the second separator: bombé and serpentine versus rectangular with canted corners. The marquetry is the third: floral bouquets in naturalistic rendering versus geometric trellis or neoclassical motifs in symmetric composition. The ormolu is the fourth: rocaille scrollwork versus Greek-key, laurel-wreath, and paterae. Many<em>Transition</em> pieces of the late 1760s and early 1770s carry elements of both vocabularies, and the dating of these pieces is one of the period&rsquo;s small pleasures.</p><p>The second is the<em>Empire</em> (1804–1815, the Napoleonic successor), which displaced Louis XVI after the Directoire interlude. An Empire commode is heavier and more massive, almost always in dark mahogany rather than marquetry, with straight columnar legs but with much heavier ormolu mounts in martial vocabulary — eagles (Napoleonic imperial), swords and laurel wreaths in Roman-triumphal arrangement, sphinxes and obelisks in Egyptian-campaign reference, lion-paw feet, the heavier classical vocabulary that Percier and Fontaine codified in their<em>Recueil de décorations intérieures</em> (1801, expanded 1812). A Louis XVI piece beside an Empire piece reads as a generation older — the Louis XVI is more delicate, more domestic, more symmetric-in-restraint, where the Empire is heavier, more imperial, more symmetric-in-grandeur.</p><p>The third is the<em>English Hepplewhite</em> and<em>Sheraton</em> (1788–1810, contemporary across the Channel), the English neoclassical interpretation of the same Greek-Roman sources the French Louis XVI was drawing on. George Hepplewhite&rsquo;s<em>The Cabinet-Maker and Upholsterer&rsquo;s Guide</em> (published posthumously 1788) and Thomas Sheraton&rsquo;s<em>The Cabinet-Maker and Upholsterer&rsquo;s Drawing-Book</em> (1791–1794) were the pattern-book vocabularies through which the English market acquired the same neoclassical ornament that the French court was commissioning. The differences are the familiar ones from the Louis XV / Chippendale comparison of the previous post: the English work is in solid carved mahogany rather than marquetry on oak, with carved decoration rather than ormolu, and with the sober gentlemanly restraint that distinguishes English furniture of every period from its French contemporary. A Hepplewhite chest of drawers and a Louis XVI commode share the same straight-tapered-leg geometry and the same oval-and-classical ornament vocabulary, but in entirely different materials and surface treatment.</p><p>The fourth is the<em>Swedish Gustavian</em> (1772–1810, contemporary in northern Europe), the direct Swedish adoption of Louis XVI under Gustav III&rsquo;s reign. Gustav III had spent considerable time in Paris during his youth and modelled the Swedish court on the French; the<em>Gustavian</em> style is essentially Louis XVI translated into the Scandinavian register, with the principal differences being the<em>painted</em> finish (typically<em>Trianon gris-blanc,</em> a pale grey-white, or pale blue, or muted yellow) rather than the gilt of the French, and a slightly simplified ornamental vocabulary suited to the smaller Swedish court budget. A Gustavian commode beside a French Louis XVI commode reads as the same piece in different paint — and the Gustavian tradition has, partly because of the painted finish that ages well and partly because of the Scandinavian-design renaissance of the past forty years, become particularly fashionable in the modern collector&rsquo;s market.</p><p>The fifth is the<em>Louis XVI revival</em> of the second half of the nineteenth century. As with the Louis XV revival the previous post described, the late nineteenth century produced reproductions of Louis XVI furniture in great quantity, often of considerable quality. The same makers who reproduced Louis XV (François Linke, Henri Dasson, Maison Jansen, Sormani, Beurdeley) also reproduced Louis XVI, and the revival pieces are themselves now over a century old and collected in their own right. The distinctions are the same as in the Louis XV revival case: the marquetry composition is more rigidly symmetric in revival pieces than in originals, the ormolu chasing is less crisp and often cast rather than chased, the carcase joinery is machine-cut, and the period stamp (JME + maker&rsquo;s name, post-1751) is absent — replaced where present by the revival maker&rsquo;s own mark.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Louis XVI piece, when one is standing in front of a candidate cabinet, comes down to a short ordered checklist.</p><p>One looks first at the legs. Straight fluted columnar legs (or square tapered legs) with no curve anywhere — this is the Louis XVI signature. Cabriole legs are Louis XV. Heavy columnar legs with martial gilt-bronze mounts are Empire. Straight tapered legs in solid mahogany are English (Hepplewhite or Sheraton). The legs settle the period at three paces.</p><p>One looks next at the case. Rectangular with canted corners is Louis XVI. Bombé and serpentine is Louis XV. Massive rectangular with heavy mahogany surfaces is Empire. The case shape is the second decisive identifier.</p><p>One looks at the ornament vocabulary. Greek-key, laurel wreath, paterae, urn, fluting, ribbon-tied garland, acanthus capital — this is the Louis XVI vocabulary. Rocaille scrollwork, asymmetric c-scrolls, cherubs in foliage — Louis XV. Eagles, swords, sphinxes, lion paws — Empire. Carved fretwork in mahogany — English Chippendale. Painted pale-grey vocabulary similar to Louis XVI — Gustavian.</p><p>One looks at the marquetry. Geometric trellis, parquetry, neoclassical motifs (musical-instrument trophies, ribbon-tied garlands) is Louis XVI. Floral bouquets in naturalistic rendering is Louis XV. No marquetry, solid carved wood is English. Painted finish over solid wood is Gustavian or provincial.</p><p>One looks for the stamp. A JME-stamped Parisian piece of the post-1751 period is documented work; a Riesener stamp on a Louis XVI piece is the strongest single piece of evidence one can hope for. The absence of a stamp does not condemn a piece, but a positive stamp is decisive.</p><p>One looks at the joinery. Hand-cut dovetails of irregular spacing, period oak with characteristic age, evidence of period repair — these are the marks of an authentic eighteenth-century piece. Machine-cut dovetails of perfectly regular spacing, newer wood, an absence of period repair — these are the marks of nineteenth-century revival or later.</p><p>And one looks at the proportions. The relationship of leg to case to top, the precision of the canted corners, the balance of the ornament across the central axis — these are the harder-won judgments. A great Louis XVI piece has an architectural precision of proportion that distinguishes it immediately from the cruder revival work; learning to see this is the slow work of comparative looking that the arc as a whole is in the business of building.</p><p>The next post in the furniture arc will be either English Chippendale — to set out the Anglophone Rococo that competed with the Louis XV vocabulary across the Channel — or German Biedermeier, the short-arc nineteenth-century counterpart that combined neoclassical bones with bourgeois sobriety. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>The Junior Engineer's Year</title><link>https://mtclinton.com/posts/the-junior-engineers-year/</link><pubDate>Fri, 15 May 2026 15:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-junior-engineers-year/</guid><category>ai</category><description>What the past two years have done to the bottom rung of the American software-engineering career — and to the same rung at every other knowledge-work profession the same technology now reaches.</description><content:encoded>&lt;![CDATA[<p>The bottom rung of the American software-engineering career ladder, after thirty years of expansion that produced a profession of roughly six million people and the displacement of a great deal of older clerical and administrative work in its passing, has in the past two years effectively been removed. The cohort affected is the cohort of the recent computer-science graduate — the twenty-two-year-old who, in 2021, would have walked from a four-year undergraduate degree into a graduate-engineering programme at one of the major technology firms or the more substantial enterprise software companies, served eighteen months as a junior on a team of five or six engineers, advanced to mid-level by twenty-six, to senior by thirty, and continued from there along the well-worn path the profession had been recruiting along since the nineteen-nineties. That cohort, in 2026, is in considerable difficulty.</p><p>This post is about what has happened, what has caused it, what the parallel patterns look like in the other knowledge-work professions whose junior-grade work now lies within the same technology&rsquo;s reliable competence, and what the question is — the unanswered one — about how the senior workforce of 2032 is to be supplied if the pipeline that was reliably producing it through 2022 is no longer reliably producing it now.</p><h2 id="the-numbers">The Numbers</h2><p>The labour-market data on entry-level software-engineering hiring in the United States is sufficient, by any reasonable accounting, to have foreclosed a debate about whether the displacement is happening. The debate, where it persists, is over its mechanism and over its duration; it is no longer over its existence.</p><p>The aggregate figures, drawn from a combination of the Bureau of Labor Statistics, the National Association of Colleges and Employers, LinkedIn&rsquo;s hiring data, and the published recruitment volumes of the major firms: entry-level software-engineering postings in the United States are down somewhere between forty and sixty per cent from their 2022 peak, depending on which dataset and which definition of &ldquo;entry-level&rdquo; one consults. The contraction is not uniform across firm tier — the major technology firms (Google, Meta, Microsoft, Amazon, Apple, Netflix, the AI labs) have reduced new-graduate engineering hiring by something on the order of seventy per cent against the 2022 baseline; the mid-tier scaleups and well-funded startups by perhaps fifty per cent; the Fortune 500 enterprise IT shops by a more modest thirty per cent. The pattern is consistent in direction across every tier of employer that hires engineers in volume; the only variation is the magnitude of the contraction.</p><p>The cohort effects are striking. The mean time-to-first-job for a four-year computer-science graduate in 2021 was somewhere between three and four months. For the class of 2024, the figure was perhaps eight months; for the class of 2025, it was approaching twelve months; the class of 2026, currently graduating, faces a labour market in which a substantial fraction of its members will not have secured an entry-level engineering position by Christmas. Mean starting salary, deflated, has declined by perhaps fifteen per cent against the 2022 peak. The premium that the computer-science degree commanded over the median bachelor&rsquo;s degree, which had been steadily widening through the 2010s and early 2020s, has begun to narrow for the first time since the field&rsquo;s institutional emergence as a separate undergraduate major.</p><p>Bootcamp graduates have been more severely affected. The coding-bootcamp model — twelve to twenty-four week intensive technical training, intended to produce graduates immediately employable in junior software-engineering roles — was a creature of the 2014–2022 hiring boom, and its placement-rate guarantees were the implicit basis on which the model justified its tuition. By 2024 the placement rates had collapsed to a degree that several of the major bootcamps (Lambda School / BloomTech, Kenzie Academy, the Holberton schools) closed entirely, and the survivors had pivoted to selling AI-skills retraining to mid-career professionals rather than entry-level placement to recent graduates. The bootcamp graduate without a CS degree to fall back on has been, in any honest accounting, the cohort hardest hit.</p><p>The layoff data is the second face of the same phenomenon. The major technology firms cumulatively laid off roughly four hundred thousand employees across 2022–2024, a substantial portion of them in early-career and mid-career engineering roles; 2025 added perhaps a further hundred and eighty thousand; 2026, in its first five months, has added something close to a hundred thousand more, including Meta&rsquo;s eight-thousand-employee reorganisation announced for May 20 and explicitly framed by the company as a capital reallocation toward its AI infrastructure programme. The layoffs are concentrated in two categories: the marginal junior cohorts that the firms had hired in the 2021–2022 over-expansion, and the mid-career engineers whose roles were judged to be the most directly affected by the productivity gains of senior-engineer-plus-AI-assistant workflows. The firms have, by their own published statements, no intention of returning to the hiring rates of 2021–2022 in the foreseeable future.</p><p>These are the numbers. They are not in serious dispute. The question of what is causing them — and whether the cause is durable or cyclical — is where the analytical difficulty begins.</p><h2 id="the-mechanism">The Mechanism</h2><p>Several explanations have been advanced for the entry-level engineering contraction, and the explanations are not mutually exclusive. Some portion of the contraction is the post-pandemic correction of the 2021–2022 over-hiring, when the major firms had been recruiting at rates well above their normal baseline in anticipation of pandemic-era growth that subsequently slowed. Some portion is the high-interest-rate environment of 2023–2024, which raised the cost of capital and reduced the willingness of firms to hire ahead of revenue. Some portion is the broader cooling of the technology sector as the cloud-and-mobile expansion of the 2010s reached saturation. Each of these explains a fraction of the contraction; none of them, separately or in combination, explains all of it.</p><p>The remaining fraction — and the principal fraction, by the testimony of the firms themselves and by what one can infer from the survivorship pattern of the affected cohorts — is attributable to the productivity effect of the language-model-and-coding-assistant workflows that have become, in the past three years, the default tooling of the working software engineer. The productivity effect is not, in the most defensible accounting, that AI is replacing engineers wholesale. The effect is that AI is altering the labour-cost structure within an engineering team in a way that is locally rational for the firm and globally devastating to the entry-level cohort.</p><p>The mechanism is the following. A senior engineer in 2022, working without AI assistance, produced perhaps a unit of output a day. A senior engineer in 2026, working with Cursor or Claude Code or one of their equivalents, produces perhaps two and a half units a day. The senior engineer&rsquo;s salary has not increased proportionally; the marginal productivity of an additional senior engineer, for many tasks, has therefore approximately doubled in cost-effective terms. A junior engineer in 2022 produced perhaps a third of a unit a day, required perhaps half a senior engineer&rsquo;s time in mentorship and code review, and was on a track to become productive at the senior level in two to three years. A junior engineer in 2026, with the same tooling, produces perhaps half a unit a day — but the tooling itself is doing the easier portion of the work, and the senior engineer&rsquo;s capacity to spot-check the AI&rsquo;s output is materially the same as the capacity to spot-check the junior&rsquo;s output.</p><p>The arithmetic is unforgiving. A team that in 2022 might have been organised as one senior engineer mentoring two juniors — total daily output approximately one and two-thirds units, total cost approximately one senior salary plus two junior salaries — is in 2026 better organised as one senior engineer working alone with AI assistance, producing approximately two and a half units a day at a cost of one senior salary. The team has lost two junior engineers and one senior-mentorship overhead and gained substantial productivity. The firm, doing this calculation across thousands of teams, has reduced its junior hiring to a small fraction of its prior level. The mechanism is not that AI has replaced the junior engineer&rsquo;s capacity for engineering work. The mechanism is that AI has eliminated the<em>training-wheels</em> portion of the entry-level engineering role, which is the portion the junior was hired to do.</p><p>There is a particular irony in this — the irony that is sharpest in the institutional-history register and that distinguishes this displacement from the earlier waves of automation that the engineering profession had survived. The earlier displacements affected the more routine and the more standardised work; the senior engineer was protected by the judgment-and-system-design portion of the role that automation could not reach. This displacement is the inverse. The most easily automated work, in 2026, is not the routine work; it is the<em>learning</em> work — the boilerplate, the test-writing, the documentation, the bug-triage, the simple-refactor — that the senior had previously delegated to the junior precisely because doing it was the way the junior would, in time, become a senior. The training pipeline is what the technology has hit first. The senior is the protected cohort.</p><h2 id="the-same-thing-elsewhere">The Same Thing Elsewhere</h2><p>The pattern is not confined to software engineering. It appears, in recognisable form, across every knowledge-work profession whose junior-grade work consists largely of the structured analytical-and-documentary tasks the language-model-plus-tooling workflows now perform reliably.</p><p>The law, first. The American legal profession has historically organised itself around a pyramid of associates beneath each partner, with the first-year associate serving an apprenticeship of document review, deposition preparation, contract markup, and case-research summarisation that constitutes both a substantial fraction of the firm&rsquo;s billable work and the principal training mechanism by which the next generation of partners is produced. The major American law firms reduced their first-year-associate hiring by perhaps forty per cent across 2023–2025, with the partner-track ladder narrowing further at every subsequent step. The work the first-year associate had performed — the document review in particular — is now done by document-AI systems that read at perhaps thirty times the speed of the first-year associate at perhaps ninety per cent of the recall, and the partner who reviews the AI&rsquo;s output reviews it at the same speed she would have reviewed an associate&rsquo;s output and at materially the same accuracy. Paralegal work, where it has not been replaced entirely, has been substantially reduced.</p><p>Consulting, next. The major management consultancies (McKinsey, Bain, Boston Consulting Group, the strategy practices of the Big Four accountancies) have reduced associate-level recruitment by something on the order of forty to fifty per cent across 2023–2025. The associate&rsquo;s traditional work — the slide-deck construction, the market-sizing analysis, the literature review, the first-pass financial modelling — is the work the AI assistants now perform reliably enough that the engagement-team partner can run a team of one or two senior consultants where she would previously have run a team of one senior consultant and four associates. The mechanism is the same as in software: the AI has not replaced the consultant; it has replaced the consultant&rsquo;s training-wheels.</p><p>Investment banking, similarly. Goldman Sachs, Morgan Stanley, JPMorgan, and the other major Wall Street firms have reduced their first-year analyst classes by twenty-five to fifty per cent across 2023–2025. The analyst&rsquo;s traditional work — the comparable-company analysis, the precedent-transactions tables, the pitch-book construction, the financial-model assembly — has been similarly absorbed into AI-assisted senior-analyst-and-associate workflows.</p><p>Accounting. The Big Four (Deloitte, PwC, EY, KPMG) have reduced their entry-level accountant and auditor hiring by perhaps thirty to forty per cent across 2023–2025, with the audit-grade work that constituted the first-year auditor&rsquo;s traditional training now substantially performed by document-AI systems.</p><p>In each case the pattern is the same. The senior cohort is preserved or expanded; the entry-level cohort is dramatically reduced; the work that has been displaced is the work that was the entry-level cohort&rsquo;s training pathway to seniority. The question, across all five professions and the others one could add to the list, is the question of where the next decade&rsquo;s senior workforce is to come from if the entry-level pipeline that was producing it through 2022 is now, structurally, producing it at a fraction of the prior rate.</p><h2 id="the-question-of-the-ladder">The Question of the Ladder</h2><p>The question is the question of the ladder. The senior software engineer of 2032 is, by the ordinary reckoning of how the profession has historically reproduced itself, the junior engineer of 2026 with six years of additional experience. If the junior engineer of 2026 is not being hired in volume, the senior engineer of 2032 is not being trained in volume, and the senior workforce of the early 2030s is, on present trajectory, going to be substantially smaller than the senior workforce of the present moment.</p><p>Several responses to this question have been offered, and none of them is wholly convincing.</p><p>The first response — held by some of the more bullish firms in the AI sector and by a portion of the venture-capital community — is that the senior workforce of 2032 will simply not need to be as large as the senior workforce of the present, because AI productivity will continue to compound and the senior-engineer-with-AI of 2032 will produce what the team of senior-engineer-and-juniors produces today. This is the<em>productivity-compounds</em> response, and it is internally coherent if its premises hold. Its premises are that AI-assisted senior productivity will continue to grow at its present rate (which is plausible but uncertain), that the work itself will remain decomposable into the senior-spot-check pattern (which is plausible for some work and not for others), and that the supply of senior engineers in 2032 will be sufficient for the reduced demand (which assumes the present senior cohort does not retire or attrit faster than the reduced junior cohort can replace it).</p><p>The second response — held by some of the larger and more institutionally-conservative firms — is that the present hiring contraction is the correction of an unsustainable boom, that the firms will resume entry-level hiring at moderate rates as the AI productivity gains stabilise, and that the senior workforce of 2032 will be a smaller-but-adequate version of the senior workforce of the present. This is the<em>cyclical-correction</em> response, and its plausibility depends on whether the firms in fact resume entry-level hiring at moderate rates rather than continuing the current contraction. The evidence so far is that they have not.</p><p>The third response — held by some of the more thoughtful observers in the labour-economics community and by a portion of the engineering profession itself — is that the present pattern represents a structural rebalancing of how technical knowledge-work is organised, and that the institutions that have historically reproduced the engineering profession (the four-year CS degree, the post-graduate apprenticeship, the firm-internal mentorship pipeline) will need to be rebuilt around the new arithmetic. What that rebuilding looks like in practice is the open question. Some have proposed that the AI assistant itself will become the mentor — that the junior engineer of 2030 will learn from the AI in the way the junior engineer of 2020 learned from the senior. Others have proposed that the engineering profession will reorganise around smaller numbers of more-deeply-trained engineers entering at a higher level, with the entry point shifted from the bachelor&rsquo;s degree to a more substantial graduate-level credential. Others still have proposed that the profession will simply shrink, and that the surplus of would-be engineers will redirect to adjacent fields.</p><p>None of the three responses has been tested. The next five years will test them.</p><h2 id="what-this-looks-like-in-practice">What This Looks Like in Practice</h2><p>The cohort affected is, on the ground, the cohort one knows. It is the friend-of-a-friend&rsquo;s son who graduated with a four-year CS degree from a respectable state university in 2024 and has been doing contract work and interviewing intermittently since. It is the bootcamp graduate of 2023 who completed her programme at the moment the placement rates began to collapse and has, after eighteen months, transitioned out of the engineering search entirely. It is the freshly-minted PhD in machine learning whose academic-job market is healthier than the industry-research-scientist market for the first time in fifteen years. It is the international student on an OPT clock who has six months to find an H-1B-eligible position and who is competing with a pool of domestic applicants whose own job-search cycle has lengthened from months to a year.</p><p>What these cohorts are doing in 2026, by the testimony of the placement data and the labour-market surveys, is some combination of the following. They are taking longer to find work. They are taking less prestigious first jobs at lower starting salaries than they had been led to expect. They are taking contract or contingent or gig roles instead of the salaried-with-benefits positions the prior cohorts took. They are migrating to AI-adjacent operational roles (prompt engineering, AI quality assurance, the various job-categories that the AI tooling has itself created) that did not exist five years ago and that may or may not be durable. They are pursuing graduate degrees as a holding pattern, often in machine learning or AI-adjacent specialisations. They are starting their own products, leveraging the same AI tools that have eliminated their entry-level options to produce small revenue streams of the kind a single founder could not have produced unassisted in 2020. They are leaving the profession entirely, often after years of preparation for it.</p><p>None of this is a moral failing on the part of the cohort. The cohort prepared for an institutional pathway that has been substantially disassembled in the brief window between their entering university and their graduating from it, and the disassembly was not, in any honest accounting, foreseen by the institutions that prepared them. The four-year computer-science degree of 2026 trains its students for a labour market that no longer exists at the scale the curriculum was designed against. The bootcamp model of the same period trains for a market that has effectively closed. The career counsellors at the universities are, in many cases, still telling 2026 graduates the same things they told 2021 graduates, because the institutions have not yet absorbed the new arithmetic. The cohort is being prepared, in good faith, for a profession whose entry conditions have changed underneath it.</p><p>What follows from this, taken honestly, is the small and uncomfortable observation that the present moment in the American knowledge-work professions is not a temporary disturbance but the early phase of a structural rebalancing of considerable scope. The firms have made their adjustment; the institutions have not yet made theirs; the cohort caught in between has had to absorb the gap. Whether the institutions will adjust quickly enough to keep producing a senior workforce in five and ten and fifteen years is the open question on which the next decade of every affected profession depends.</p><p>The senior software engineer of 2032 is, somewhere in the country in 2026, attempting to enter the field. Whether she succeeds is a question that the firms making the present hiring decisions, the institutions training her, and the policy-makers who might intervene in the gap have not yet, in any defensible sense, taken seriously. The present moment is the moment at which they will be obliged to.</p>
]]></content:encoded></item><item><title>Tabriz</title><link>https://mtclinton.com/posts/tabriz/</link><pubDate>Fri, 15 May 2026 13:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/tabriz/</guid><category>antiques</category><description>Second per-subject post in the Reading the Antique Rug arc — the city-workshop tradition of northwestern Persia, the named-master heritage of Hadji Jalili and his contemporaries, and the curvilinear urban counterpart to Heriz's village geometric vocabulary.</description><content:encoded>&lt;![CDATA[<p>If the<a href="/posts/heriz/">Heriz</a> post that opened this arc described the village-workshop tradition of the Iranian Azerbaijani highlands — coarse-knotted, geometric, brick-red, room-sized, made for household use and merchant-export in roughly equal measure — the Tabriz that this post takes up is the urban-workshop counterpart sixty kilometres west of it: finer-knotted by a factor of three or four, curvilinear in its drawing throughout, painted from a substantially wider palette, and made in workshops of named masters whose surviving signed pieces command, in the current antique market, prices that no Heriz of any period approaches.</p><p>The two types together — Tabriz and Heriz — establish the basic axis along which every other Persian rug type can be read. Workshop versus village. Curvilinear versus geometric. Fine knot versus moderate. Court antecedent versus tribal. Named master versus anonymous weaver. The axis is not absolute — many Persian types occupy intermediate positions along it, and the city-versus-village distinction is permeable in particular cases — but the axis is the clarifying frame for a beginner&rsquo;s reading, and getting the Tabriz post written immediately after the Heriz post is what makes the rest of the arc&rsquo;s siblings legible.</p><p>This post follows the same template as the Heriz: what a canonical Tabriz looks like, the structural and material evidence by which one identifies it, the urban and historical context that produced it, the types most often confused with it, and the practical identification discipline by which a candidate piece is read in the dealer&rsquo;s shop or the collector&rsquo;s drawing room.</p><h2 id="the-specimen">The Specimen</h2><p>The Tabriz that one will encounter is, in its most common modern form, a substantial room-size rug — anywhere from six by nine to twelve by eighteen feet, with the eight-by-ten and nine-by-twelve formats accounting for the bulk of the late-nineteenth-century and early-twentieth-century export production. Smaller pieces (scatter rugs, prayer rugs, small medallion pieces) and very large pieces (palace-size carpets exceeding twenty feet in length) both exist, but the canonical Tabriz is the substantial room-size piece.</p><p>The composition, in the dominant Tabriz format, is the<em>medallion-and-corner</em> — a central curvilinear medallion of intricate scroll-work and arabesque pendants, four corner spandrels with curvilinear floral or arabesque ornament that mirrors the medallion at quarter-iteration, and a field between medallion and spandrels filled with smaller curvilinear vines, leaves, palmettes, and rosettes set against the dominant ground. This is the format the entire post is in some sense about, because it is the format the Tabriz workshop tradition perfected and against which one reads every other Persian medallion design. The variations are considerable — the medallion may be lobed, may be octagonal-pointed, may be stretched into an oval cartouche; the spandrels may be deep enough to meet at the centre of each side, or shallow enough that they merely punctuate the corners — but the basic four-cornered curvilinear-medallion-and-arabesque format is the Tabriz signature.</p><p>Beyond the medallion-and-corner, several other Tabriz design vocabularies are common enough to warrant naming. The<em>herati</em> design — an allover repeating pattern of &ldquo;fish&rdquo; leaves around a central rosette, named after the city of Herat though woven in many Persian centres — is the most common Tabriz allover field pattern, often without central medallion, sometimes called the<em>mahi</em> (Persian for &ldquo;fish&rdquo;) variant when the leaf-and-diamond motif predominates. The<em>garden carpet</em> divides the field into compartments suggesting a Persian garden plan, with cypress trees, water channels, and flowers in each compartment. The<em>pictorial</em> Tabriz — figurative scenes from Persian history (the Shah&rsquo;s court, hunting scenes, illustrations from Ferdowsi&rsquo;s<em>Shahnameh</em>) or, in late-nineteenth-century work for the Western market, biblical or Western literary subjects — exists in considerable variety and at considerable quality. The<em>Tree of Life</em> and the<em>vase carpet</em> are further specialty designs the Tabriz workshops produced.</p><figure><img src="/images/posts/tabriz/detail-medallion.png" alt="A close detail of a Tabriz central medallion — curvilinear lobed indigo shape with arabesque pendants on the rose-red field"><figcaption><p>A close detail of a Tabriz central medallion — the curvilinear lobed indigo shape with its arabesque pendants extending toward the top and bottom of the field, surrounded by densely-drawn floral and vine ornament on the rose-red ground. Every motif is rendered curvilinearly: the smooth curves of the medallion outline, the scrolling leaves, the small flowers, the flowing vines. The drawing is the workshop tradition&rsquo;s principal advantage over the village tradition, and the higher knot count of the workshop is what makes it possible. A Heriz rendering of the same medallion would be stepped and angular; the Tabriz rendering is curvilinear because the workshop&rsquo;s hundred-and-fifty knots per square inch can draw a smooth curve where the village&rsquo;s sixty cannot.</p></figcaption></figure><p>The colour palette is wider and softer than the Heriz&rsquo;s. The dominant ground is, in the most-encountered late-nineteenth-century antique Tabriz, a soft rose-red verging toward salmon or apricot — substantially paler than the Heriz brick-red. Ivory and pale gold are common alternative grounds for high-grade Tabriz, particularly the pieces by the master Hadji Jalili of the late nineteenth century. Indigo and navy serve as the medallion and border colours. Pale greens, soft yellows, and accent reds appear in the floral ornament. The whole palette is anchored toward the European-decorator-friendly end of the Persian range — and was, in the late-nineteenth and early-twentieth-century export market, deliberately tuned for that audience.</p><figure><img src="/images/posts/tabriz/detail-arabesque.png" alt="A close detail of Tabriz arabesque ornament — scrolling vine, curling leaves, and palmette pendants in continuous curvilinear drawing"><figcaption><p>A close detail of the curvilinear arabesque that fills the area between the central medallion and the corner spandrels of a Tabriz field — flowing scrolling vines, curling leaves tapered at the tips, palmette pendants emerging from vine junctions, small rosettes scattered between. Every line a curve. The arabesque vocabulary is what the Tabriz workshop tradition shares with every other Persian urban-workshop tradition (Kashan, Isfahan, Mashad) and what most cleanly distinguishes the urban from the village production.</p></figcaption></figure><p>The construction is sturdy but substantially finer than the Heriz. The foundation is cotton — warp and weft both — with the warps closely spaced and the wefts thin and tightly drawn, allowing the higher knot count that the Tabriz workshop tradition is built around. The pile is wool, occasionally silk in the very finest pieces (an all-silk Tabriz exists, but Hereke is the more famous silk tradition). The knot is historically the symmetrical (Turkish) knot, geographically appropriate to the Azerbaijani region, though some modern Tabriz workshops use the asymmetrical (Persian) knot for the finer drawing it permits. Knot density is the principal differentiator from Heriz: a Tabriz of dealer-grade quality runs from a hundred to two hundred knots per square inch (kpsi), with master-grade Tabriz reaching three hundred to four hundred and the very finest court-grade Tabriz exceeding five hundred. The local trade unit for knot density is the<em>raj</em> — the count of knots in a seven-centimetre width — and Tabriz quality grades are conventionally given in raj (50 raj is medium, 70 raj is fine, 80 raj is very fine, 100+ raj is master-grade).</p><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural evidence by which a Tabriz is identified at close range and its provenance dated and attributed.</p><p>The knot, as noted, is historically symmetrical (Turkish), with the wool wrapped around two adjacent warps and pulled down between them. A modern Tabriz workshop using the asymmetrical (Persian) knot will typically advertise the fact, since the Persian knot is associated with the central Iranian fine workshops (Kashan, Isfahan) that the Tabriz weavers have, in the modern period, sometimes consciously emulated. The knot is most easily inspected from the back of the rug, where the rows of small bumps reveal the structure plainly. The knot density itself is the principal evidence one is reading for: a count of sixty knots per inch is a Heriz-class piece; a hundred to two hundred is a Tabriz of dealer grade; over two hundred is master-grade; over three hundred is exceptional. The knot count is most easily measured by counting the bumps in a one-inch square on the back and multiplying by itself.</p><figure><img src="/images/posts/tabriz/detail-knot.png" alt="The back of a Tabriz rug at magnification — symmetrical Turkish knots packed densely on a finely-spun cotton foundation, with a Persian Nastaliq signature trace visible in the lower border"><figcaption><p>The back of a Tabriz rug at magnification — symmetrical Turkish knots packed densely in regular rows on a finely-spun cotton foundation, the colour of the field showing through the structure. The knot count is visibly higher than would appear on a Heriz back; the cotton weft is more tightly drawn; the workshop quality is apparent at a glance. In the lower portion, the trace of a small Persian (Nastaliq) signature cartouche is faintly visible — a master-workshop attribution that, if legible, would be the strongest single piece of evidence for the piece&rsquo;s provenance and date.</p></figcaption></figure><p>The wool of the pile is the second physical signature. Tabriz wool comes from the regional flocks (the same Azerbaijani sheep that supply Heriz, in many cases) but is more carefully selected and more finely spun for the workshop tradition than for the village. The pile is denser, the cut is cleaner, and the surface character is more uniform than the Heriz pile. The very finest antique Tabriz uses<em>kork</em> — a high-grade lambswool from the underbelly and chest of the lamb — which gives a particular silky lustre that the Hadji Jalili workshop made its signature.</p><p>The dyes, in the older pieces, are entirely vegetable. Madder for the rose-red and the salmon and the apricot; indigo for the navy and the deeper blues; weld and the local pomegranate rind for the yellows; the various plant-derived greens; cochineal occasionally for accent reds. The Tabriz palette is wider than the Heriz precisely because the workshop tradition could afford a more diverse dye supply and a more skilled dyer than the village tradition could maintain. The vegetable dyes age in the same characteristic ways across both traditions — indigo never quite leaves; madder reds soften toward apricot at the worn edges — and a fine antique Tabriz with its full vegetable palette intact and properly aged is among the most beautiful objects of any decorative tradition.</p><p>The signature, fourth — and this is the gift of the urban workshop tradition that the village tradition does not provide. The major late-nineteenth and early-twentieth-century Tabriz workshops — Hadji Jalili, Mostofi, Petag (the German-organised firm Persische Teppich AG that established a Tabriz workshop in 1911), the various dealer-houses of the Tabriz bazaar — frequently signed their work in a small cartouche at one end of the field, typically at the bottom border, in Persian (Nastaliq) script. The signature may name the master weaver, the workshop, the dealer-commissioner, or the date in the Islamic calendar. Many Tabriz pieces are unsigned; many of the signed pieces have their signatures abraded by household wear. But a clearly signed Tabriz, where the signature can be read by someone with Persian-language skills, is documented work, and the master signatures (Hadji Jalili in particular) command substantial premiums in the current market.</p><p>The selvedges of a Tabriz are wrapped in wool, often of the dominant border colour, and the ends are typically finished with a short kilim section before the cotton-warp fringe. The selvedges and ends are more carefully finished than the Heriz, with the workshop attention to detail visible at every transition. The fringe itself is, in the older pieces, often quite short — old fringe is what household wear takes first, and many older Tabriz have had their fringes substantially shortened in the course of dealer repair.</p><h2 id="the-city">The City</h2><p>Tabriz is a city, and the rugs are the workshop output of an urban centre that has been continuously productive in carpet-weaving for at least six hundred years and probably longer. The city sits on a high plateau in the Iranian Azerbaijan, perhaps fourteen hundred metres above sea level, on the historical trade route connecting the Mediterranean and Black Sea ports to the Iranian plateau and beyond to Central Asia. The population is largely Azeri Turkic — which is the explanation for the Turkish knot — and the city has been, at various points in Persian history, both a major commercial centre and a political capital.</p><p>The carpet-weaving tradition of Tabriz can be documented to the medieval period. Surviving Persian court carpets of the Safavid dynasty (early sixteenth to early eighteenth centuries) include several attributed to Tabriz workshops on stylistic grounds, and the<em>Ardabil carpet</em> of 1539–40 — woven for the shrine of Shaykh Safi al-Din at Ardabil and now divided between the Victoria and Albert Museum in London and the Los Angeles County Museum of Art — is a Tabriz-tradition piece of extraordinary quality and historical importance. The Ardabil and its surviving siblings establish the high-water mark of medieval Persian carpet weaving and the formal vocabulary on which the modern Tabriz tradition continues to draw.</p><figure><img src="/images/posts/tabriz/antecedent.png" alt="A Safavid-era Tabriz court carpet in the tradition of the Ardabil — elaborate central medallion, dense allover field of curvilinear ornament, the formal vocabulary the modern Tabriz tradition descends from"><figcaption><p>A Safavid-era Persian court carpet in the Tabriz tradition (in the manner of the famous Ardabil carpet of 1539) — an elaborate sixteen-petalled central medallion surrounded by smaller cartouche-pendants extending toward the ends of the field, the entire field densely populated with curvilinear scrolling vines and palmettes on a deep ground, multiple bands of border ornament with cartouche-and-rosette repeats. The Safavid court tradition is the antecedent the modern Tabriz workshops descended from, and the formal vocabulary they have continued to draw on for four centuries.</p></figcaption></figure><p>The modern Tabriz period — the period whose surviving production constitutes the bulk of the antique market — runs from approximately 1870 to 1930. Two factors made this period the great age of Tabriz weaving for export. The first was the post-1860s opening of the Persian carpet to the European and American market, which created a demand for substantial room-size rugs in the European-decorator palette that the Tabriz workshops were already disposed to produce. The second was the emergence, in the same decades, of named master weavers who organised production in a manner more like a Renaissance workshop than a village cottage industry — Hadji Jalili pre-eminent among them, Mostofi a close second, Sheikh Safi-style copyists and others — and whose signed work commanded premium prices in the market from its first appearance.</p><p>A note on the named masters, because the named-master tradition is what most distinguishes Tabriz from the village types like Heriz.<em>Hadji Jalili</em> (Persian: حاجی جلیلی, active in Tabriz roughly 1875–1900) was the master weaver whose late-nineteenth-century pieces in soft pastel palette, often on ivory grounds with rose medallions, are now considered the high-water mark of antique Tabriz production at the workshop scale. A signed Hadji Jalili can fetch, in the current market, ten to thirty times the price of a comparable unsigned Tabriz of the same period.<em>Mostofi</em> worked in a similar period and register.<em>Petag</em> — the Persische Teppich AG, organised by German importers in 1911 — produced Tabriz rugs of consistent quality and decorator-friendly design through to the inter-war period; Petag pieces are documented and signed and are themselves a collected category. The Tabriz tradition of named workshops contrasts with the anonymous weaving of every village type covered in the Heriz post and, by extension, with the great majority of Persian rug production outside the major urban centres.</p><figure><img src="/images/posts/tabriz/workshop-page.png" alt="A page from a Victorian connoisseur's portfolio on Tabriz — city map locating the principal workshops in the bazaar district, design archetypes, and the master signatures of Hadji Jalili and Mostofi"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on Tabriz — the city map at the top locates the principal workshops within the Tabriz bazaar district (Hadji Jalili, Mostofi, Petag, and several unnamed dealer-houses); the lower half shows three small archetype drawings (medallion-and-corner, herati allover, pictorial Tree of Life) and the master signatures of Hadji Jalili and Mostofi in Persian Nastaliq with Latin transliteration. The plate is the kind of reference page that would have appeared in a serious dealer&rsquo;s portfolio of the period, and is what one consults when trying to read a candidate signature in the lower border of an unfamiliar Tabriz.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Several Persian rug types stand near enough to Tabriz that the beginner confuses them with it, and distinguishing them is most of the work of reading the Persian urban-workshop tradition.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/tabriz/sibling-kashan.png" alt="A Kashan rug with deep wine-red field, navy curvilinear central medallion, ivory spandrels with formal arabesque, and densely-packed curvilinear floral throughout" loading="lazy"/><figcaption>Kashan<em>— the central Iranian city counterpart</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tabriz/sibling-isfahan.png" alt="An Isfahan rug with extraordinarily fine knot count on a silk warp foundation, intricate central medallion on a pale ivory ground, densely-packed curvilinear floral field with cloud-bands and palmettes" loading="lazy"/><figcaption>Isfahan<em>— the finest of the urban workshops</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tabriz/sibling-mashad.png" alt="A Mashad rug with single navy curvilinear central medallion on a deep wine-red ground, dense allover floral field carrying through to the border without spandrels" loading="lazy"/><figcaption>Mashad<em>— the eastern Iranian counterpart</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/tabriz/sibling-heriz.png" alt="A Heriz rug with stepped octagonal indigo medallion on a brick-red field, ivory spandrels stepped to mirror the medallion, walnut-brown border with stylised vine — every motif rectilinear in pointed contrast to Tabriz's curvilinear vocabulary" loading="lazy"/><figcaption>Heriz<em>— the geometric village contrast</em></figcaption></figure></div><figcaption>Four rug types most often confused with Tabriz, drawn for comparison.</figcaption></figure><p>A<em>Kashan</em> is the carpet of the central Iranian city of Kashan, which has been a major workshop centre since at least the seventeenth century. Kashan rugs share Tabriz&rsquo;s curvilinear vocabulary and medallion-and-corner format but differ in palette and execution: a Kashan is typically denser, with a more saturated deep-red ground (verging toward burgundy rather than Tabriz&rsquo;s softer rose), navy medallion, and a more rigorously formal symmetric composition. The Kashan knot count is comparable to or higher than Tabriz, and the wool is of comparable fineness. The two types compete in the same upper-tier Persian rug market and are sometimes hard to tell apart — but the deeper saturated red of the Kashan, the more rigid symmetry of the design, and the central Iranian rather than northwestern provenance separate them on close inspection.</p><p>An<em>Isfahan</em> is the carpet of Isfahan, the central Iranian Safavid capital, and is the finest of the Persian urban-workshop traditions. Isfahan uses the asymmetrical (Persian) knot, runs at substantially higher knot counts than Tabriz (often four hundred to eight hundred kpsi), is frequently woven on silk warps, and produces pieces of curvilinear-floral vocabulary at a level of refinement that no other Persian centre regularly matches. An Isfahan beside a Tabriz reads as the same vocabulary translated into a finer register — and at substantially higher prices in the current market. The asymmetrical knot is the immediate separator: a curvilinear medallion rug with the Persian knot is probably Isfahan or central Iranian; a curvilinear medallion rug with the Turkish knot is probably Tabriz or northwestern.</p><p>A<em>Mashad</em> is the carpet of the eastern Iranian city of Mashad, and is typically a large room-size piece with a single central medallion in deep wine-red ground, dense allover field of small floral ornaments, and the asymmetrical Persian knot. Mashad shares Tabriz&rsquo;s medallion format but uses the deeper Persian palette and the central-Iranian-style allover field; the proportions and the saturation of the red are the easiest separators.</p><p>A<em>Sarouk</em> — particularly the<em>American Sarouk</em> of the 1920s and 1930s — is the central Iranian rug that was specifically overdyed in deep rose for the American market in the inter-war period. American Sarouk rugs typically carry an allover floral spray on a saturated rose-overdyed ground, with no central medallion, and are now collected as their own category. The two types competed directly in the inter-war American market and the modern dealer often shelves them adjacent.</p><p>A<em>Heriz</em> — the village-workshop type covered in the previous post — is the Tabriz&rsquo;s nearest geographic neighbour and its sharpest stylistic contrast. The two types together are the foundational pair for reading northwestern Persian weaving: Tabriz curvilinear and fine, Heriz geometric and moderate; Tabriz urban and named-master, Heriz village and anonymous; Tabriz on a wider and softer palette, Heriz on the brick-red signature; Tabriz at a hundred to two hundred kpsi, Heriz at sixty to a hundred. A reader who has the Tabriz/Heriz contrast clearly in mind has the basic axis along which every other Persian rug can be located.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Tabriz, when one is standing in front of a candidate rug, comes down to a short ordered checklist.</p><p>One looks first at the design vocabulary. Curvilinear floral and arabesque ornament throughout, with sweeping vines, curling leaves, palmette pendants, and a curvilinear central medallion — this is the Persian urban-workshop signature, of which Tabriz is the principal northwestern representative. If the design is geometric and angular, it is not a Tabriz; it is a Heriz, a Caucasian Kazak, a Bidjar, or one of the geometric village types.</p><p>One looks next at the knot count. A hundred to two hundred kpsi is the Tabriz commercial range; over two hundred suggests a master-grade workshop piece (Hadji Jalili, Petag); over three hundred suggests Isfahan or one of the very fine central Iranian workshops; under sixty suggests Heriz or a coarser village type. The knot count is most easily measured by counting bumps in a one-inch square on the back.</p><p>One looks at the knot type. Symmetrical (Turkish) on the back is consistent with Tabriz and with the broader northwestern Persian tradition. Asymmetrical (Persian) suggests Isfahan, Kashan, or central Iranian work — though some modern Tabriz workshops have adopted the Persian knot.</p><p>One looks at the foundation. Cotton warp and weft is the Tabriz norm. Silk warp suggests a very fine antique Tabriz (uncommon but documented) or, more frequently, an Isfahan or Hereke. Wool foundation is anomalous and suggests village rather than urban workshop provenance.</p><p>One looks at the palette. Soft rose, salmon, apricot, ivory, pale gold, soft greens — this is the Tabriz workshop palette, particularly in late-nineteenth-century antique pieces. Deep saturated wine-red is more characteristic of Kashan, Mashad, or Sarouk; brick-red is Heriz; deep navy or ebony is uncharacteristic of Tabriz and suggests something else.</p><p>One looks at the wool quality. Soft, lustrous, finely spun pile is the Tabriz workshop signature.<em>Kork</em> (lambswool) at master-grade Tabriz is unmistakable to a trained hand — the surface has a particular silky character that ordinary wool does not match.</p><p>One looks for the signature. A small Persian (Nastaliq) cartouche at one end of the field, typically the bottom border, may name the master weaver, the workshop, or the date. The signature, where present and legible, is the strongest single piece of evidence one can hope for; the signed Hadji Jalili pieces in particular constitute their own collected category at the high end of the market.</p><p>And one looks at the proportions and the wear pattern. A great Tabriz has proportions of an immediate rightness — the medallion sized to the field, the spandrels sized to the medallion, the border weighted to balance the field. The wear pattern of an old Tabriz is silvery in the high-traffic centre, more saturated in the protected margins, and softens gradually rather than abruptly. The harder-won judgments — the comparative ones, against many other Tabriz examples seen — are what come only with time at the dealer&rsquo;s bench.</p><p>The next post in the rug arc will be either Bakshaish — the older village tradition out of which Heriz proper grew, the antecedent the Heriz post pointed toward but did not treat in detail — or one of the Caucasian types (most likely Kazak), which would establish the second axis along which the rug arc will need to operate (Persian versus Caucasian, urban-versus-village versus tribal-versus-court). The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>AI at the Back of the Bank</title><link>https://mtclinton.com/posts/ai-at-the-back-of-the-bank/</link><pubDate>Fri, 15 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ai-at-the-back-of-the-bank/</guid><category>ai</category><description>The third piece of the AI landscape the trajectory series did not see — seventy years of quiet document-recognition deployment in the back-office of every American bank, every IRS submission centre, every insurance claims-triage room.</description><content:encoded>&lt;![CDATA[<p>The deposit operations centre of a large American commercial bank — Bank of America, JPMorgan Chase, Wells Fargo, U.S. Bank, any of the regionals of any size — is a place that, by the standards of any other industrial facility, runs quietly. It is, in most cases, a room in a windowless building on a service-road exit somewhere outside a mid-sized American city, with the bank&rsquo;s name on the building (where it appears at all) only in small lettering near the loading dock. Inside, a sequence of high-speed document scanners pulls checks past an imaging head at perhaps ten or twelve a second; behind the scanners, a row of servers runs character-recognition models against each image, extracts the routing number, account number, check number, amount, and signature, compares each field against the bank&rsquo;s internal records, flags the exceptions to a human reviewer in a separate department, and posts the rest to the customer accounts. The room handles, on a typical business day, perhaps a hundred thousand checks. Across all the deposit centres of all the American banks, the daily volume is something on the order of forty million, and that figure does not include the further forty or fifty million paper-equivalent items — payment remittances, lockbox payments, mortgage statements, insurance premium notices — that pass through the parallel lockbox operations of the same banks for their corporate clients. The total volume of documents read by character-recognition systems at American banks in a single business day is something close to a hundred million.</p><p>This post is the third of three correctives — the first, yesterday, was on the<a href="/posts/ai-at-3am/">emotional-support</a> use of frontier language models; the second, the same day, was on the<a href="/posts/ai-in-the-slaughterhouse/">industrial visual quality grading</a> at American beef-packing plants — to the five posts on AI-lab trajectories I wrote earlier this month. The two prior correctives argued that the analyst class has a coverage problem: that the largest and most-embedded AI deployments in 2026 are systematically the ones the trade press cannot see. This post closes the trio by treating the third of the three rooms the slaughterhouse post named — alongside the late-night chat and the kill floor, the back of the bank — and by making, on the basis of this third example, the strongest version of the structural argument the three posts together advance.</p><h2 id="the-room-and-the-number">The Room and the Number</h2><p>A few facts, in the order one would want them.</p><p>The American banking industry processes, in a year, somewhere between eleven and thirteen billion paper or paper-equivalent items. The number is down from a peak of roughly fifty billion in 1995, before electronic payments and direct deposit and online bill-pay had displaced the dominant payment instrument of the mid-twentieth century, but it remains the dominant volume of the document-processing economy and a number that, multiplied by the cost of human handling that would otherwise be required, runs into the hundreds of billions of dollars a year of avoided labour cost. Every one of those items is, in modern practice, read by a character-recognition model. The Federal Reserve&rsquo;s check-processing operations, the major commercial banks&rsquo; deposit centres, the corporate lockbox operations, and the back-office sorting houses of every payment processor in the country — all of these run on the same basic apparatus: a high-speed scanner, a character-recognition pipeline, a signature-verification model, an exception-handling queue.</p><p>Beyond banking, the Internal Revenue Service processes, each year, roughly two hundred and forty million individual tax returns and somewhere over four billion information returns — W-2s, 1099s, 1098s, K-1s, and the rest of the alphabet of forms by which one income event is reported to the federal government. The IRS&rsquo;s three Submission Processing Centres — in Austin, Kansas City, and Ogden — run scanning and character-recognition pipelines on every paper return that arrives and every paper information return their corporate filers still produce; the IRS has, since the 2023 launch of its Document Upload Tool, also processed taxpayer-submitted document images through the same character-recognition stack. The total annual document volume of the IRS&rsquo;s submission processing is something on the order of five billion items, all of which pass through optical character recognition before any human eye reaches them.</p><p>Beyond the IRS, the American mortgage industry originates roughly five to eight million mortgages a year, each with a hundred to three hundred pages of supporting documentation; the entire stack is, in modern practice, scanned and OCR-extracted into the loan-origination system. The American property-and-casualty insurance industry processes about two hundred and fifty million claims a year, most involving photographed supporting documents (police reports, repair estimates, medical records) that pass through document AI before reaching an adjuster. The healthcare claims industry runs an analogous pipeline at vastly greater volume — somewhere over five billion claims a year, all involving documentary backup that is scanned and read by machine.</p><p>The deployment numbers, summed across all these domains, are an order of magnitude larger than the deployment numbers for any consumer-facing language model. Every adult American has, in the past year, had thousands of documents on their behalf read by a character-recognition system. The system reads the documents reliably enough that, in the great majority of cases, no human reviewer is involved at any point in the chain. The deployment is older than the modern internet, older than the personal computer, older than the consumer credit card; the first MICR check-reading systems were installed in American banks in the late 1950s, the first general-purpose document OCR in the 1980s, the first deep-learning-based document AI in the early 2010s. The pipeline has been improving incrementally for seventy years. It has, by 2026, reached a level of capability at which most documents in most domains are read more accurately by machine than by the average human reviewer the machine has replaced.</p><h2 id="the-wrong-newsroom">The Wrong Newsroom</h2><p>One would think, given these numbers, that the AI trade press would have something to say about them. It does not. The AI press —<em>TechCrunch,</em><em>The Information,</em><em>Stratechery,</em> the AI sections of the<em>Wall Street Journal</em> and the<em>Financial Times,</em> the newsletter cottage industry of the past three years — has, as far as I have been able to find, written almost nothing about bank OCR, IRS document processing, or insurance claims triage at any point in the past five years. The deployment is too long-running to be news; the publications that cover it (<em>American Banker,</em><em>Bank Director,</em><em>Insurance Journal,</em><em>Mortgage Banker Magazine,</em> the trade-press of each affected industry) are not on the AI beat; the vendors involved (ABBYY, Kofax, IBM, Fiserv, FIS, Oracle, the in-house document-processing groups of the major banks) are B2B back-office software companies that do not seek out the consumer AI press. The industry, when it describes its own work, does not even use the word<em>AI</em> — the preferred terminology is<em>intelligent document processing,</em> or<em>back-office automation,</em> or<em>document AI,</em> or<em>capture and recognition,</em> and the language alone is sufficient to keep the work outside the AI conversation.</p><p>This is the third face of the same problem the first two correctives described. The first was<em>emotional support,</em> the largest single use of frontier language models in 2026 by conversation volume, uncounted by the analyst class because it does not generate API revenue. The second was<em>industrial visual quality grading,</em> the most thoroughly embedded use of AI in the American physical economy, uncounted because the kill floor is not in any of the rooms the analyst class visits. The third is<em>document AI,</em> the largest single deployment of artificial intelligence in the American information economy, uncounted because the back-office of every major American institution is even more thoroughly outside the AI press&rsquo;s beat than the kill floor was. The trade press visits the labs and the consumer apps; it does not visit the deposit operations centre, the IRS Submission Processing Centre, the lockbox sorting room, the insurance claims-triage office, the mortgage origination back-office. These rooms account for, by any conservative estimate, more than half of all the AI inference performed in the United States in a typical business day, and approximately none of the AI press coverage.</p><h2 id="why-it-works-in-that-room">Why It Works in That Room</h2><p>There is a quiet structural argument for why document AI became the deployment it became, while a hundred more famous applications stalled. It rests on the same three properties of the task that the slaughterhouse post identified for visual quality grading, applied here to document processing.</p><p>The first is that document reading is, at its core, a perception task and not a reasoning task. The system does not need to<em>understand</em> the check; it needs to read the routing number, the amount, the signature, and the date, and to flag any field that fails to match the expected pattern. There is no chain of inference, no consideration of intent, no context window of relevant prior facts. A trained vision-and-character-recognition system, given enough labelled examples, is the right tool for this shape of problem, and was the right tool well before the language-model era. The cameras of the slaughterhouse did not have to wait for the breakthroughs of the 2020s; nor did the OCR pipelines of the banks. Both were already capable enough by the early 2000s to handle the great majority of their respective workloads, and the improvements since have been refinements rather than revolutions.</p><p>The second is that the conditions of the task are unusually controlled. Every check conforms to a standard format prescribed by the American National Standards Institute and the Federal Reserve; the MICR line at the bottom uses a specific stylised font (E-13B) chosen for machine readability; the document size, paper weight, and printing standards are regulated to the millimetre. The IRS forms similarly: every W-2, every 1099, every K-1 conforms to a federal layout from which deviation is forbidden by penalty. Even the unstructured side of the document — the handwritten amount on a check, the medical records in an insurance claim — passes through a pipeline that knows where in the document the unstructured content will appear and what range of values it is likely to contain. The variables that defeat consumer-grade vision systems are, on the document, engineered out of existence by the regulatory and industry standards that govern the document&rsquo;s design.</p><p>The third is that the supply of training data is exceptionally good. Every document in the system is associated with a downstream economic outcome — a posted balance, a tax assessment, a paid claim, a settled mortgage — that is independently verified. The ground truth for any character-recognition decision is grounded in dollars, the same way the slaughterhouse&rsquo;s ground truth was grounded in the market price of the cut. Misreads are caught by reconciliation; reconciliation feeds back as training data; the model gets better. Seventy years of this feedback loop has produced a system that, at the high-volume document end, exceeds the average human reviewer it replaced.</p><p>These three properties — perceptual task, controlled conditions, dollar-anchored labels — are not unique to bank documents. They are the structural conditions that produced the slaughterhouse&rsquo;s beef-grading deployment, that have produced the warehouse-vision deployment at Symbotic and Amazon, that have produced the optical-character-recognition deployment at every utility and every government office and every payments processor in the developed world. The pattern is consistent. The depth of deployment is consistent. The invisibility to the AI press is also consistent.</p><h2 id="what-this-is-not">What This Is Not</h2><p>One ought to be plain about what this is not.</p><p>It is not a story of a profession disappeared, though some professions have been substantially reduced. The &ldquo;check encoder&rdquo; of the mid-twentieth century — the bank employee who keyed the amount on every paper check into the MICR encoding system — was once a category of work that employed tens of thousands of people across the American banking industry, and has been reduced over four decades to perhaps a few thousand exception-handling reviewers across the entire industry. The IRS still employs a substantial workforce in submission processing, but the same workforce now handles a document volume that is perhaps ten or twenty times what the same number of employees could have handled in 1980. The labour has been rebalanced rather than eliminated; the experienced reviewers who remain are arguably more valuable than they were in the human-only era, because their judgment is what resolves the exceptions the machine flags.</p><p>It is not a story of an industrial deployment that arrived through any sudden breakthrough. The first MICR systems date to the late 1950s; the first general-purpose document OCR to the 1980s; the deep-learning era began in the early 2010s and has produced incremental capability improvements since. The arc has been a seven-decade unbroken line of steady refinement and steady regulatory accommodation. The lesson, if there is one, is the same dull lesson the slaughterhouse post named: the most consequential AI deployments are not the ones one reads about on the day they ship.</p><p>It is not a story of an unregulated industry. American banking OCR is heavily regulated, under the Check 21 Act of 2003, under the Office of the Comptroller of the Currency&rsquo;s examinations of bank operations, under the National Automated Clearing House Association&rsquo;s standards, under the Federal Reserve&rsquo;s payment-system rules. The IRS document-processing infrastructure is regulated by the Internal Revenue Code and audited by the Treasury Inspector General for Tax Administration. The insurance claims systems are regulated by state insurance commissioners and by the National Association of Insurance Commissioners. The depth of regulatory accommodation is itself evidence of the depth of deployment.</p><p>And it is not, finally, an argument that document AI is the only deeply-embedded AI deployment the trade press has missed. The first corrective made the case for emotional support; the second made the case for industrial visual grading; this one makes the case for document AI; the warehouse vision, the freight routing, the utility-grid optimisation, the semiconductor defect detection — each is a deployment of comparable depth that the trade press also does not cover. The plural form of the claim, made now across three correctives, is that the analyst class has, as a class, a coverage problem of considerable scope, and that the largest and most embedded AI deployments are systematically the ones it is least equipped to see.</p><h2 id="the-plain-fact">The Plain Fact</h2><p>The structural facts come out, in order, as follows.</p><p>The first is that document AI, by any measure of depth — regulatory accreditation across multiple federal and state agencies, capital expenditure across an entire industry, document volume of roughly five billion items a day, labour reorganisation of every major American institution that handles paper, equipment lifetime measured in decades — is the single largest deployment of artificial intelligence in the American information economy in 2026. The deployment is older than the modern internet and has been quietly improving for seventy years.</p><p>The second is that this deployment, like the slaughterhouse&rsquo;s industrial visual grading and the late-night frontier-model emotional support, is invisible to the AI trade press because the AI trade press&rsquo;s beat ends at the lab door and the consumer app. The rooms in which the deepest deployments actually run — the deposit operations centre, the IRS Submission Processing Centre, the lockbox sorting house, the kill floor, the late-night private chat window — are systematically not the rooms the analyst class visits. The three correctives I have now written — emotional support, industrial visual grading, document AI — are three faces of a single coverage problem, and they are far from exhaustive.</p><p>The third is the one I should like to leave plainly. The deepest AI deployments in 2026 are the ones for which the question<em>is this AI?</em> has stopped being asked. The check-imaging pipeline at the bank, the marbling camera on the kill floor, the late-night conversation with ChatGPT — each of these has, in its own way, passed beyond the conversation of<em>what AI is and is not capable of</em> and into the conversation of<em>how the world now works.</em> The trade press is, as a matter of editorial principle, not very interested in the second conversation; the public, as a matter of practical convenience, has stopped asking.</p><p>Infrastructure does not announce itself. The deepest AI deployments in 2026 have become infrastructure, and the silence with which they operate is not a failure of communication on their part; it is the natural state of a working system.</p>
]]></content:encoded></item><item><title>Louis XV</title><link>https://mtclinton.com/posts/louis-xv/</link><pubDate>Thu, 14 May 2026 18:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/louis-xv/</guid><category>antiques</category><description>First per-subject post in the Reading the Period Cabinet arc — the high Rococo French style of the second quarter of the eighteenth century, the cabriole leg, the bombé commode, the ébénistes of the Paris guild, and the discipline of telling a period piece from its century-of-reproductions.</description><content:encoded>&lt;![CDATA[<p>The piece of furniture most often understood as &ldquo;antique French&rdquo; in the Anglophone domestic interior — the bombé chest of drawers on small curved legs, fronted in marquetry of pale and dark woods, with a stylised garland of brass mounts across the central drawer face — is, in its essential vocabulary, a Louis XV commode. The actual Louis XV commodes, of which perhaps a few thousand survive in major museum collections and great houses, are considerably more refined, more various, and more particular than the reproduction-furniture trade has ever been able to convey. The reproduction commode, in its various qualities from the 1860s onward, has been so widely produced that it has shaped the popular image of &ldquo;French eighteenth-century furniture&rdquo; almost beyond rescue, and one of the small services that may still be done is to explain what the original was actually doing.</p><p>This is the first post in<em>Reading the Period Cabinet,</em> the furniture arc of the<a href="/posts/reading-the-antique/">antiques series</a>, and the companion launch to the<a href="/posts/heriz/">Heriz</a> post that opened the rug arc earlier today. It treats Louis XV first because Louis XV is the type that most rewards an opening post — the most encountered, the most often imitated, the most often misunderstood, and the type whose place in the wider history of European cabinet-making makes it the cleanest first specimen against which the others can later be compared. The aim of this post is the aim of every post in the arc to come: to set out what one is looking at, to give the structural and material evidence by which one identifies it, to place it among the styles most often confused with it, and to leave the reader with the trained eye that the arc as a whole is in the slow business of building.</p><h2 id="the-specimen">The Specimen</h2><p>The canonical Louis XV piece, for the purposes of this post and for the purposes of beginning to read the style at all, is the commode. Other forms — the<em>bureau plat,</em> the<em>secrétaire à abattant,</em> the<em>bergère,</em> the<em>fauteuil,</em> the console, the<em>encoignure</em> — carry the same vocabulary in their respective registers, but the commode is the form in which the period&rsquo;s principal moves are most fully concentrated, and it is the form one most often encounters in any setting where eighteenth-century French furniture is to be seen.</p><p>A canonical Louis XV commode, then. It stands on four short cabriole legs — legs that curve outward at the knee, taper inward to the ankle, and end in a small foot, often capped with a gilt-bronze<em>sabot.</em> The foot itself is no more than a few inches above the floor; the leg&rsquo;s S-curve is the entire vertical interest of the lower part of the piece. Above the legs, the case rises through a serpentine apron and presents itself in a strongly curved silhouette: the front bows outward (the bombé front), the sides curve outward to meet it (the serpentine sides), and the corners are rounded rather than mitred. The case is two drawers tall, sometimes three, and presents a single continuous front rather than the discrete drawer fronts of an English chest of drawers — the marquetry and the ormolu mounts run across the drawer divisions, treating the whole front as one unified decorative field.</p><figure><img src="/images/posts/louis-xv/detail-leg.png" alt="A close detail of a Louis XV cabriole leg — S-curved profile from knee to ankle, terminating in a small foot capped with a gilt-bronze sabot"><figcaption><p>A close detail of a Louis XV cabriole leg — the S-curved profile that defines the period, generous at the knee, tapering through the ankle, and terminating in a small foot capped with a gilt-bronze sabot. The curve is the period: more pronounced than the Régence cabriole that preceded it, less exaggerated than the contemporary German Rococo cabrioles. A Louis XVI piece has straight legs, often fluted and tapered like classical columns; an Empire piece has straight legs with martial gilt-bronze mounts. The leg is the first thing one looks at, and the cabriole settles the period at three paces.</p></figcaption></figure><p>The decorative apparatus has three components in roughly equal measure. The first is the marquetry — the inlay work of pale and dark exotic woods that covers the drawer fronts and the side panels. A typical Louis XV commode of the middle period (1740–1760) carries floral marquetry — bouquets of roses, ribbons, garlands — set against a plain or trellis-pattern ground, in kingwood, tulipwood, rosewood, satinwood, and a half-dozen other tropical species selected for their colour and grain. The great Parisian<em>ébénistes</em> — Bernard II van Risenburgh (BVRB), Charles Cressent, Jean-François Oeben, Antoine-Robert Gaudreau, Jean-Pierre Latz — built their reputations on marquetry of extraordinary subtlety and complexity, in some cases incorporating Chinese or Japanese lacquer panels imported through Holland, or French imitation lacquer (<em>vernis Martin,</em> by the Martin brothers of the Paris workshop), set into the case fronts as decorative reserves.</p><figure><img src="/images/posts/louis-xv/detail-marquetry.png" alt="A close detail of Louis XV floral marquetry — a ribbon-tied bouquet of roses in kingwood, tulipwood, satinwood, and pearwood inlay on a tulipwood ground"><figcaption><p>A close detail of Louis XV floral marquetry — a ribbon-tied bouquet of roses in kingwood, tulipwood, satinwood, and pearwood inlay on a plain tulipwood ground. The end-cut wood technique exposes the colour fields across the grain; the assembly is laid by hand in hot animal glue. The compositions of the great Parisian ébénistes are individually recognisable — the rose bouquet of a BVRB commode is not the rose bouquet of a Cressent or of a Latz — and a careful comparative study can attribute a piece to a specific maker on the marquetry alone. The reproduction marquetry of the nineteenth-century revival is generally more rigidly symmetric than the originals, and the species used are often a more limited palette.</p></figcaption></figure><p>The second component is the ormolu — the gilt-bronze mounts applied to the corners, the angles of the cabriole legs, the keyhole escutcheons, the drawer pulls, and (in the high pieces) substantial sculptural mounts at the centre of each drawer or wrapped around the case angles. Ormolu (literally &ldquo;ground gold,&rdquo; from<em>or moulu</em>) is mercury-fire-gilded bronze, a process of unusual difficulty and danger — the mercury vapour was understood, even at the time, to shorten the gilders&rsquo; lives — that produces a deep matte gold finish that no later technique has been able to reproduce. The mounts began as functional protection for corners and edges that took household wear, but quickly became major sculptural ornament in their own right, with the great<em>bronziers</em> — Jacques and Philippe Caffieri pre-eminent among them — producing mounts of cherubs, female masks, foliage, and elaborate scrollwork.</p><figure><img src="/images/posts/louis-xv/detail-mount.png" alt="A close detail of a Louis XV ormolu mount — a sculptural arrangement of cherubs, foliage, and scrollwork in mercury-gilded bronze, applied to the angle of a commode"><figcaption><p>A close detail of a Louis XV ormolu mount — a sculptural arrangement of cherubs, foliage, and scrollwork in mercury-gilded bronze, applied to the upper angle of a commode where the curve of the case meets the marble top. Mercury fire-gilding produces a deep matte finish that is unmistakable beside the brighter, thinner electroplated gilt of nineteenth-century reproductions. The chasing — the hand-finishing of the bronze surface before gilding — is of a quality that does not survive into the reproduction era; on the originals, every leaf and curl bears the mark of the chaser&rsquo;s tools, while on the reproductions the surface is uniform and the modelling is shallower.</p></figcaption></figure><p>The third component is the marble top — usually a slab of<em>brèche d&rsquo;Alep</em> or<em>sarrancolin</em> or<em>rouge royal,</em> fitted to the curved silhouette of the case, with its edge moulded to a serpentine profile to match the case below. The marble top is a constant of the form: the case is built to receive it, and a Louis XV commode without its original marble is, in collector terms, a wounded piece. A modern marble replacement, even when carefully made, almost never quite matches the proportions, the edge profile, or the colour relationship to the case that the original mason achieved.</p><p>Assembled together — cabriole legs, bombé and serpentine case, marquetry surfaces, ormolu mounts, marble top — these are the canonical components. The variations within the type are considerable; the components themselves do not vary.</p><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural and material evidence by which a Louis XV piece is identified at close range and its provenance dated and attributed.</p><p>The case construction, first. The carcase of a Louis XV commode is typically built of solid oak (Parisian work) or of pine and walnut (some provincial and German work), then veneered on every visible surface with the exotic woods and marquetry that constitute the visible decoration. The veneers are thick by modern standards — typically a millimetre or more, sometimes two — and were laid by hand with hot animal glue in a process of considerable skill. The carcase joinery is dovetailed, often visible at the back of the case but never at the front. Drawer construction uses through-dovetails at the corners with hand-cut tails, the divisions visible if one removes a drawer and inspects the joinery from inside.</p><p>The marquetry, second. The wood species used by the major Parisian ébénistes are well-documented: kingwood (a deep purple-brown), tulipwood (pale rose with strong grain), rosewood (warm red-brown),<em>bois de violette</em> (violet-tinted), satinwood (pale yellow), pearwood (used as a stable ground), holly (white, used for highlights), boxwood, ebony, and a half-dozen others. The marquetry is typically end-cut — the wood sliced across the grain to expose the colour fields — and then assembled in floral or geometric patterns and laid to the case as a unified surface. The marquetry of a fine Louis XV piece, when one has the eye for it, is recognisable by the species used and by the characteristic compositions: the rose bouquet of a BVRB commode is not the rose bouquet of a Cressent commode is not the rose bouquet of a Latz, and a careful comparative study can attribute a piece to a specific maker on the marquetry alone.</p><p>The ormolu, third. The mounts of a fine Louis XV piece are mercury-fire-gilded bronze, with the gold layer typically several microns thick and the underlying bronze chased and finished by hand before gilding. The result is a finish of remarkable depth and matte richness that nineteenth-century electroplated reproductions cannot reproduce — the electroplate finish is brighter, more uniform, and visibly thinner. The original mounts of the great pieces are signed or attributed to specific bronziers (Caffieri, Cressent&rsquo;s own foundry, Jean-Claude Duplessis), and the chasing is of a quality that does not survive into the reproduction era.</p><p>The stamp, fourth — and this is the great gift of the period to attribution. From 1751, the Parisian guild of cabinet-makers (the<em>Corporation des Menuisiers-Ébénistes</em>) required all guild members to stamp their work with their name and the guild mark &ldquo;JME&rdquo; (<em>jurande des menuisiers-ébénistes,</em> the wardenship seal). The stamp is typically applied to a discreet spot on the carcase, usually at the back or on the underside of the top, in a small rectangular cartouche burned into the wood. A piece stamped &ldquo;BVRB&rdquo; with the JME mark is documented as the work of Bernard van Risenburgh and is dated to the post-1751 period. A piece stamped &ldquo;RIESENER&rdquo; is by Jean-Henri Riesener, dated post-1768 (when Riesener became a master). A piece without a stamp may be pre-1751, may be a country piece by a maker outside the Paris guild, may be a reproduction, or may be a stamped piece whose stamp has been worn or planed away — but the absence of a stamp is, in itself, evidence to be interpreted, not a verdict to be drawn.</p><p>The marble, fifth. The original marble tops of Louis XV commodes are typically of one of a half-dozen French and Italian quarry types —<em>brèche d&rsquo;Alep, sarrancolin, rouge royal,</em> Carrara, Languedoc,<em>vert de mer</em> — each with characteristic colour and figuring. The marble was selected to complement the wood of the case and the colour of the mounts, and the original marbles can often be identified with confidence. A modern marble replacement is usually in plain Carrara or in a cheaper grey-veined stone, and the proportions and edge profile are often subtly off — a knowledgeable eye picks up the substitution at a glance.</p><p>These are the physical facts. They are what one is reading for. None of them, in the older pieces, is concealed; all of them are accessible to anyone who removes a drawer or turns over a leaf of marble or looks closely at the chasing of a mount.</p><h2 id="the-period">The Period</h2><p>The Louis XV style proper runs from approximately 1730, when the cabriole leg and the curving case had displaced the rigid rectilinearity of the late Louis XIV, through to roughly 1770, when the neoclassical reaction had begun to reintroduce the straight line and the symmetric composition that would characterise Louis XVI. The named monarch reigned from 1715 (when his great-grandfather Louis XIV died and the five-year-old Louis XV came to the throne under the regency of Philippe d&rsquo;Orléans) through to his own death in 1774; the style proper is conventionally dated from his majority in 1723, with the early years of the reign — the<em>Régence</em> under Philippe d&rsquo;Orléans — treated as a separate transitional sub-period.</p><p>The Régence (1715–1730) is the bridge from Louis XIV&rsquo;s monumental baroque to Louis XV&rsquo;s mature rocaille. Under the regent&rsquo;s looser court and the relocation of fashionable life from Versailles to Paris, the rigid symmetry of Louis XIV softened: the cabriole leg replaced the straight gaine; the marquetry of Boulle (brass-and-tortoiseshell, classical and architectural in vocabulary) gave way to the floral marquetry in exotic woods that would become the period&rsquo;s signature; the heavy ormolu mounts loosened into curling foliage and emerging masks. The transitional period is identifiable: a Régence piece typically has a cabriole leg but a still-rectangular case, or a curved case but heavier and more architectural mounts than the Louis XV proper would carry.</p><p>The high Louis XV (1730–1760) is the period of the great Parisian ébénistes and of the principal patrons. Madame de Pompadour (Jeanne Antoinette Poisson), the<em>maîtresse en titre</em> of Louis XV from 1745 until her death in 1764, was the period&rsquo;s most consequential patron of the decorative arts. Her commissions to BVRB, Oeben, and others established the most refined level of the style; her taste — for floral marquetry, for delicate ornament, for the subtlest combinations of colour — set the standard the rest of the period worked toward. Beside her, the<em>Garde-Meuble Royal</em> (the royal furniture warehouse, which commissioned and maintained the furniture of Versailles, Marly, Trianon, Compiègne, and the other royal residences) was the largest single patron, and the Garde-Meuble&rsquo;s surviving inventory records — preserved in the French national archives — are one of the great gifts to the modern attribution of the period&rsquo;s furniture.</p><figure><img src="/images/posts/louis-xv/pattern-book-page.png" alt="A page from a Victorian portfolio on Louis XV furniture — engraved drawings of the principal forms (commode, bureau plat, secrétaire, console, fauteuil) with explanatory annotations"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on Louis XV French furniture — engraved drawings of the principal forms (the commode, the bureau plat, the secrétaire à abattant, the console, the fauteuil) arranged in the manner of a nineteenth-century cabinet-maker&rsquo;s reference plate, with explanatory annotations on the proportions and the principal ornamental moves. The plate is the kind of reference page that would have appeared in a serious dealer&rsquo;s portfolio of the period, intended for the customer&rsquo;s quiet education while the dealer fetched the next piece from the storeroom.</p></figcaption></figure><p>The late Louis XV (1760–1770) shows the early signs of the neoclassical reaction. The cabriole leg straightens slightly; the case fronts become less aggressively bombé; floral marquetry begins to give way to geometric trellis patterns; ormolu mounts incorporate Greek-key and laurel-wreath motifs alongside the older rocaille vocabulary. The transition to Louis XVI — whose proper period begins with his accession in 1774, but whose style is in evidence from the late 1760s — is gradual rather than abrupt, and many pieces of the 1765–1775 period are described in dealer catalogues as &ldquo;Transition&rdquo; — meaning Louis XV / Louis XVI transitional — and these pieces, when they are by major makers, are some of the most prized of the period.</p><p>A note on the Paris guild system, because it is essential to understanding the period&rsquo;s attribution. The Parisian cabinet-making trade was organised into two guilds: the<em>menuisiers</em> (joiners), who worked in solid wood — chairs, beds, consoles, frames — and the<em>ébénistes</em> (cabinet-makers in exotic woods), who worked in veneered and marquetry case furniture. From 1751, both guilds required their masters to stamp their work, and the resulting body of stamped work — preserved in collections, sold through dealers, recorded in archives — is the documentary basis for the modern study of the period. Outside Paris, no comparable stamp requirement existed, and provincial work (Lyon, Bordeaux, Nîmes, Provence) is generally unstamped and is attributed by stylistic comparison to the regional traditions.</p><figure><img src="/images/posts/louis-xv/antecedent.png" alt="A Louis XIV / Régence commode — straighter case, heavier proportions, Boulle-style marquetry of brass and tortoiseshell, the antecedent style out of which the Louis XV proper emerged"><figcaption><p>A Louis XIV / Régence commode — straighter case, heavier proportions, Boulle marquetry of brass and tortoiseshell in classical architectural vocabulary, with massive scrolled feet rather than cabriole legs. The antecedent style out of which the Louis XV proper emerged. The Régence — the transitional period 1715–1730 under Philippe d&rsquo;Orléans — is where the cabriole begins to appear and the marquetry begins to soften from the classical Boulle vocabulary toward the floral exotic-wood marquetry of the high Louis XV. The Régence is short (only fifteen years) and the surviving work is comparatively scarce, but a careful eye distinguishes a Régence commode from an early Louis XV by the still-classical proportions and the more subdued asymmetry of the ornament.</p></figcaption></figure><h2 id="what-it-is-not">What It Is Not</h2><p>Several styles stand near enough to Louis XV that the beginner confuses them with it, and distinguishing them is most of the work of reading European eighteenth-century furniture at the upper end.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/louis-xv/sibling-louis-xiv.png" alt="A Louis XIV commode — heavily symmetric, architectural, Boulle marquetry of brass and tortoiseshell, straight or scrolled feet, massive proportions" loading="lazy"/><figcaption>Louis XIV<em>— the monumental baroque antecedent</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xv/sibling-louis-xvi.png" alt="A Louis XVI commode — straight fluted columnar legs, rectangular case with canted corners, geometric trellis marquetry, Greek-key and laurel-wreath ormolu mounts" loading="lazy"/><figcaption>Louis XVI<em>— the neoclassical successor</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xv/sibling-chippendale.png" alt="An English Chippendale chest of drawers in carved mahogany, with cabriole legs ending in ball-and-claw feet, fretwork ornament, and no veneered marquetry" loading="lazy"/><figcaption>English Chippendale<em>— the Anglophone Rococo</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/louis-xv/sibling-revival.png" alt="A nineteenth-century Louis XV revival commode — superficially similar to the original but with more rigidly symmetric marquetry, cast (rather than chased) ormolu mounts, machine-cut dovetails, and no JME stamp" loading="lazy"/><figcaption>Louis XV revival<em>— the nineteenth-century reproduction</em></figcaption></figure></div><figcaption>Four styles most often confused with the Louis XV, drawn for comparison.</figcaption></figure><p>The first is the<em>Louis XIV</em> (1660–1715, antecedent), which Louis XV&rsquo;s curves displaced. A Louis XIV commode is straighter, more architectural, more heavily symmetric, and typically carries Boulle marquetry — the inlay of brass and tortoiseshell developed by André-Charles Boulle and his sons, with classical and architectural vocabulary (acanthus, masks, scrolls in formal symmetry). The legs are typically straight gaines (tapering rectangular pillars) or scroll-feet rather than cabriole; the case is rectangular and massive; the ormolu is heavier and more sculptural. A Louis XIV piece beside a Louis XV piece reads as a generation older — the proportions, the silhouette, the ornamental vocabulary all differ.</p><p>The second is the<em>Louis XVI</em> (1774–1792, successor), which displaced Louis XV. A Louis XVI commode has straight legs, often fluted and tapered like classical columns; the case is rectangular, with corners often canted at forty-five degrees rather than rounded; the marquetry shifts from floral to geometric (trellis, parquetry, classical garlands); the ormolu mounts incorporate neoclassical vocabulary (Greek-key borders, laurel wreaths, urns, ribbons, paterae). The transition from Louis XV to Louis XVI is the move from curve to straight line, from asymmetric balance to symmetric, from rocaille to neoclassical. Many &ldquo;transition&rdquo; pieces of the late 1760s and early 1770s carry elements of both, and the dating of these pieces is one of the period&rsquo;s small pleasures.</p><p>The third is the<em>English Chippendale</em> (1745–1775, contemporary across the Channel), Thomas Chippendale&rsquo;s interpretation of the French Rococo for the English market, published in his<em>Gentleman and Cabinet-Maker&rsquo;s Director</em> of 1754 and refined across three subsequent editions. Chippendale Rococo borrows the cabriole leg, the curved case, and the asymmetric ornament from the French — but expresses them in mahogany rather than marquetry, with carved decoration rather than ormolu, and with the characteristically English ball-and-claw foot rather than the French sabot. The two styles can superficially resemble each other in silhouette but differ entirely in materials and surface treatment: a French Louis XV piece is veneered, marquetried, and ormolu-mounted; a Chippendale piece is solid mahogany with carved decoration. The English piece, by Chippendale&rsquo;s own intention, makes a lesser claim to courtly grandeur and a stronger claim to gentlemanly sobriety.</p><p>The fourth is the<em>Louis XV revival</em> of the second half of the nineteenth century — the most-deceiving sibling and the one that most often defeats the beginner. The French Second Empire (1852–1870) and the broader European taste of the 1860s through the 1890s produced reproductions of Louis XV furniture in great quantity, often of considerable quality and using authentic-style techniques (marquetry in the same exotic woods, mercury-gilded ormolu, dovetailed carcases). A skilled nineteenth-century reproduction, particularly one that has acquired a century&rsquo;s patina since it was made, can closely resemble an original at a distance; the distinctions are in the marquetry composition (revival pieces tend to be more rigidly symmetric than originals), in the ormolu chasing (less crisp, with the mounts often cast rather than chased before gilding), in the carcase joinery (machine-cut dovetails on later examples), and in the absence of a period stamp (revival pieces are not JME-stamped, though they may carry their own maker&rsquo;s mark, such as the well-known &ldquo;Linke&rdquo; or &ldquo;Sormani&rdquo; or &ldquo;Beurdeley&rdquo; marks of Paris cabinet-makers of the 1870s–1900s). The revival pieces are themselves now over a century old, are collected in their own right, and command serious prices when by the major makers; the work is to know what one is buying.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Louis XV piece, when one is standing in front of a candidate cabinet, comes down to a short ordered checklist.</p><p>One looks first at the silhouette. Cabriole legs and a bombé or serpentine case is the Louis XV signature. Straight legs and a rectangular case is Louis XVI or Empire or some other later style. Solid wood with carved ornament rather than veneered marquetry is English (Chippendale or its successors). The silhouette is decisive at three paces.</p><p>One looks next at the surface. Marquetry of exotic woods (kingwood, tulipwood, rosewood) on a veneered case is Parisian ébéniste work of the high period. Solid walnut with simpler inlays or none is provincial French or German work. Carved mahogany surfaces are English. The surface treatment narrows the geographic and stylistic provenance immediately.</p><p>One looks at the ormolu. Mercury-gilded mounts of crisp chasing and deep matte finish, with sculptural detail in cherubs, masks, foliage, and scrolls, is high-period Parisian work. Cast mounts of less crisp finish, electroplated or with bright gilt, is nineteenth-century reproduction. The ormolu is one of the surest separators of original from revival, and the chasing — the surface modelling of the bronze before gilding — is the single hardest thing for a reproducer to fake.</p><p>One looks at the marble. Original marble in<em>brèche d&rsquo;Alep, sarrancolin, rouge royal,</em> or one of the other period quarries, with the edge moulded to the case profile, is a positive indicator. Plain Carrara of incorrect proportions, or marble that does not seat tightly to the case, is a replacement and warrants caution about the rest of the piece.</p><p>One looks at the back, the underside of the top, and the inside of the carcase for the stamp. A JME-stamped Parisian piece of the post-1751 period is documented work; the maker&rsquo;s stamp, where present, settles the attribution. The absence of a stamp does not condemn a piece, but a positive stamp is the strongest single piece of evidence one can hope for.</p><p>One looks at the joinery. Hand-cut dovetails of irregular spacing on the drawers, a carcase of period oak with characteristic age and patina, drawer runners of the period type, evidence of period repair (consistent with two and a half centuries of use) — these are the marks of an authentic eighteenth-century piece. Machine-cut dovetails of perfectly regular spacing, a carcase of newer wood, modern hardware, and an absence of period repair are the marks of nineteenth-century reproduction or later.</p><p>And one looks at the proportions. The proportion of leg to case to top, the depth of the bombé, the curve of the cabriole, the relationship of the marquetry composition to the case geometry — these are the harder-won judgments, the ones that come only with comparative looking across many examples. A great Louis XV piece has proportions of an immediate rightness that the reproductions almost never quite achieve; learning to see this is the slow work of the trained eye that the arc as a whole is in the business of building.</p><p>The next post in the arc is likely to be either Louis XVI — to set out the neoclassical reaction that displaced the rocaille — or English Chippendale, the contemporary across the Channel that translated the Louis XV vocabulary into a different national register. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Heriz</title><link>https://mtclinton.com/posts/heriz/</link><pubDate>Thu, 14 May 2026 17:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/heriz/</guid><category>antiques</category><description>First per-subject post in the Reading the Antique Rug arc — the great room-size rug of the Anglophone middle class, the Heriz district of northwestern Iran, and the discipline of telling it apart from the things it is most often confused with.</description><content:encoded>&lt;![CDATA[<p>The rug at the centre of every American living room of any pretension between roughly 1890 and 1940 was, very probably, a Heriz, even when it was sold to its purchaser as something else. The piece would have measured perhaps nine feet by twelve, or ten by fourteen if the room was generous; the field would have been a brick-red verging on rust, the medallion at the centre angular and stepped, navy or indigo on the brick-red ground, the corners worked into spandrels that mirrored the shape of the medallion, the border heavy and walnut-toned. The dealer in the eastern city from which the rug had been shipped would have called it, depending on his confidence and his estimate of the customer&rsquo;s gullibility, a &ldquo;Persian&rdquo; or an &ldquo;Oriental&rdquo; or — to a customer who had already learned a few terms — a &ldquo;Tabriz&rdquo; or a &ldquo;Sultanabad&rdquo; or, if the seller wished to suggest some additional age and refinement, a &ldquo;Serapi.&rdquo; It was, in nine cases out of ten, a Heriz: woven on a sturdy cotton foundation in the villages on the slopes east of Tabriz, in a coarser knot than its Tabriz neighbours and in a bolder geometric vocabulary than they would have countenanced. It was the great room-size rug of the Anglophone middle class, and it remains, on inspection, the type one is most likely to encounter in any American household with rugs in it at all.</p><p>This is the first post in<em>Reading the Antique Rug,</em> the rug arc of the new<a href="/posts/reading-the-antique/">antiques series</a> the previous post introduced. It treats Heriz first because Heriz is the type that most rewards an opening post — the most encountered, the most often mistaken for something else, and the type whose place in the wider weaving tradition makes it the cleanest first specimen against which the others can later be compared. The aim of this post is the aim of every post in the arc to come: to set out what one is looking at, to give the structural and material evidence by which one identifies it, to place it among the types most often confused with it, and to leave the reader with the trained eye that the arc as a whole is in the slow business of building.</p><h2 id="the-specimen">The Specimen</h2><p>The Heriz that one will encounter is, in its commonest form, a room-sized rug — somewhere between eight by ten and twelve by fifteen feet, with the nine-by-twelve and ten-by-fourteen formats accounting for the bulk of what was woven for export. Smaller pieces exist; larger pieces exist; runners and scatter rugs from the same district exist (the Karaja runner, with its row of small medallions, is the runner-form most often seen). But the canonical Heriz is the room-size piece, woven specifically for the European and American demand for carpets that would furnish a parlour or a dining room without further accompaniment.</p><p>The composition is rigorous and almost diagrammatic. There is a central medallion, bold and rectilinear, often stepped or notched at the points of a star or a stretched octagon, and almost always rendered in navy or indigo against the brick-red field. The corners of the rug carry spandrels that mirror the shape of the medallion in a quarter-iteration, locking the composition into a four-cornered frame. The field between medallion and spandrel is usually filled with smaller floral or palmette ornaments, geometric and angular in execution, set against the dominant red. The border is wide, usually carrying a stylised vine or palmette pattern in walnut or brown ground, often with an inner and outer guard band of contrasting palette. The whole composition is symmetrical along both axes, and reads as cleanly from one end as from the other — a property that mattered when the rug was being sold from a roll in a dealer&rsquo;s shop and could be presented either way around to the customer.</p><figure><img src="/images/posts/heriz/detail-medallion.png" alt="A close detail of a Heriz central medallion — stepped octagonal indigo shape on brick-red field, with smaller geometric palmettes filling the surrounding ground"><figcaption><p>A close detail of a Heriz central medallion — the stepped octagonal indigo shape on the brick-red field, with smaller geometric palmettes and rosettes filling the surrounding ground. Every motif is rectilinear: the angular drawing is the consequence, not the limitation, of the moderate knot density. At sixty knots per square inch the curve cannot be drawn cleanly, so the medallion stems from a vocabulary of stepped polygons and rectilinear pendants. The same vocabulary, with district-specific variation, appears across the great majority of the Heriz district output of the period 1890 to 1930.</p></figcaption></figure><p>The colour palette is the first thing one&rsquo;s eye registers. The dominant red is not crimson — it is a brick-red verging on rust, the colour of the local madder root from which the dye is derived, and it is the single feature most diagnostic of the type. The medallion blue is navy or indigo, deep and matte. The spandrels are usually ivory or cream, the borders walnut or brown, and a muted green appears in floral fillers and in the borders, almost always present, almost never dominant. The whole palette is anchored in earth tones — vegetable dyes worked into the locally lustrous wool — and the result is a rug that will sit happily in a room of dark wood and leather furniture and not fight with any of it. This was, one suspects, no small part of the type&rsquo;s commercial success in the Edwardian and inter-war American household, where the dark wood and leather were the standard.</p><p>The construction is sturdy. The foundation — warp and weft — is cotton, which gives the rug its body and prevents the dimensional drift that wool-foundation rugs are prone to. The pile is wool, knotted in the symmetrical (Turkish) knot, which is the geographically expected knot in this part of Azerbaijan and which favours the angular geometric vocabulary the Heriz design tradition has settled on. Knot density is moderate — sixty to a hundred knots per square inch is typical — and is the explanation, not the limitation, of the rug&rsquo;s bold design: one cannot draw a fine curve at sixty knots per inch, so one designs in straight lines and stepped angles, and the result is a vocabulary that one comes to read as Heriz at first glance.</p><figure><img src="/images/posts/heriz/detail-border.png" alt="A section of Heriz main border — a stylised vine-and-palmette pattern in walnut-brown ground with narrow guard bands of contrasting tone above and below"><figcaption><p>A section of the Heriz main border — a stylised vine-and-palmette pattern in walnut-brown ground, with the narrow guard bands of contrasting palette running above and below. The border vocabulary is angular throughout, in keeping with the moderate knot count, and the same border pattern, in subtle district-specific variants, appears across most of the Heriz district output of the export period. The border is, after the central medallion, the second feature one identifies at a distance — its proportions and palette are characteristic of the type.</p></figcaption></figure><h2 id="the-evidence">The Evidence</h2><p>Behind the visible composition is the structural evidence by which a Heriz is identified at close range and its provenance dated.</p><p>The knot, as noted, is Turkish — symmetrical — with the wool wrapped around two adjacent warps and the loose ends pulled down between them. A Persian (asymmetrical) knot in a rug of this design would mark it as something else: most likely a Tabriz attempting Heriz vocabulary, or a Mahal from the Sultanabad region, or one of several other workshop products that have copied the Heriz format. The knot is most easily inspected from the back of the rug, where the rows of small bumps reveal the structure plainly to the trained eye, and where the colour visible through the knots gives a second confirmation of the dye palette.</p><figure><img src="/images/posts/heriz/detail-knot.png" alt="The back of a Heriz rug at magnification — symmetrical Turkish knots arranged in regular rows on a doubled cotton weft, with the field colours visible through the structure"><figcaption><p>The back of a Heriz rug at magnification — the symmetrical Turkish knots arranged in regular rows on a doubled cotton weft, the cotton foundation visible at the selvedge and along the short kilim end-finish above the fringe, the colours of the field showing through the structure. The great majority of any Heriz attribution can be made from this side of the rug: the knot type, the doubled weft, the cotton foundation, the dye palette, and the knot density are all visible at once. A trained eye spends as much time looking at the back of an unfamiliar rug as at the front, and often more.</p></figcaption></figure><p>The weft is doubled — two passes of cotton weft between each row of knots, which gives the Heriz its characteristic body and keeps the rug lying flat against the floor. A Hamadan rug, which uses a single weft, will be visibly thinner in the hand. A Bidjar, which packs its wefts more densely still, will be famously stiff — the &ldquo;iron rug of Persia,&rdquo; as the trade has long called it. Heriz sits firmly between the two, which is one of the reasons it became the favoured room-size export of the late nineteenth and early twentieth centuries: heavy enough to lie flat under furniture, supple enough to roll for shipment.</p><p>The wool of the pile is the second physical signature. Heriz wool comes from local sheep grazed on the high pasture above the villages, and it is high in lanolin, lustrous, and takes the natural dyes generously. An old Heriz, after a century of household weather, develops a patina that synthetic-dyed and carded wool simply cannot reproduce. The colours soften and blend; the pile, where the household traffic has worn it, takes on a silvery sheen against the unworn margins. A Heriz that has been in a room for fifty years looks unmistakably so, and a great deal of the satisfaction of an old Heriz is in this slow textural ageing.</p><p>The dyes, in the older pieces, are entirely vegetable. Madder for the brick-red and the rust; indigo for the navy and the deeper blues; walnut hull for the brown borders; weld or the local pomegranate rind for the yellows; cochineal occasionally for accent reds. The vegetable dyes age in particular ways — the indigo never quite leaves; the madder reds soften into apricot and salmon at the worn edges; the yellows shift towards old gold. A Heriz from after the first decade of the twentieth century may show the chemical-aniline reds and synthetic dyes that arrived in the region around then; the difference, to a trained eye, is immediate — the synthetic reds are sharper, more uniform across the field, and they age into a flat dull tone rather than into the layered patina the vegetable dyes produce. The trade name for that flatness, when one finds it on an otherwise honest old rug, is &ldquo;tea-washed&rdquo; or &ldquo;chemically treated&rdquo;; it is the residue of an attempt, often midway through the rug&rsquo;s life, to artificially soften the harsh aniline tones into something approximating the look of vegetable dye. It rarely succeeds.</p><p>The selvedges of a Heriz are wrapped in wool, usually of the dominant border colour, and the ends are typically finished with a short kilim section before the fringe. The fringe itself is the cotton warp continued and tied off; the older the rug, the shorter the surviving fringe, since the fringes are what household wear takes first and what dealers most often shorten in the course of repair.</p><p>These are the physical facts. They are what one is reading for. None of them, in the older pieces, is concealed. All of them are on the back of the rug if one knows to turn it over.</p><h2 id="the-region">The Region</h2><p>Heriz is the district name. The rugs come from the villages of Heriz proper, plus Mehraban, Ahar, Bakshaish, Karaja, and a number of smaller villages, all clustered on the slope of the Sahand mountain east of Tabriz in what is now Iran&rsquo;s East Azerbaijan province. The district sits at perhaps fifteen hundred metres&rsquo; elevation, with cold winters and brief summers, on the northwestern edge of the Iranian plateau. The population is largely Azeri Turkic — which is the explanation for the Turkish knot — and the weaving tradition, as best one can reconstruct it, runs back several centuries before the rugs that became famous in the European market.</p><figure><img src="/images/posts/heriz/workshop-page.png" alt="A page from a Victorian connoisseur's portfolio on the Heriz district — district map locating the principal weaving villages on the slope east of Tabriz, with three small archetype rug drawings at the bottom showing the principal sub-type designs"><figcaption><p>A page from a Victorian connoisseur&rsquo;s portfolio on the Heriz district — the district map locating the principal weaving villages (Heriz proper, Mehraban, Ahar, Bakshaish, Karaja) on the slope of the Sahand mountain east of Tabriz, with three small archetype rug drawings at the bottom showing the principal sub-type designs (Heriz, Serapi, and Bakshaish). The plate is the kind of reference page that would have appeared in a serious dealer&rsquo;s portfolio of the period, intended for the customer&rsquo;s quiet education while the dealer fetched the next rug from the storeroom.</p></figcaption></figure><p>The European and American collecting market knows Heriz, however, almost entirely as a phenomenon of the late nineteenth and early twentieth centuries. Two things made the Heriz the great export rug of that period. The first was the Tabriz merchants, who from roughly 1880 onward organised the district&rsquo;s weaving on a workshop and merchant-distribution basis — supplying cartoons, dyes, and in some cases warps to village weavers, then collecting the finished pieces for shipment to the Tabriz bazaar and from there to Constantinople, Vienna, London, New York, and Boston. The second was the European and American demand for room-size carpets in the brick-red-and-navy palette that the Heriz tradition was already producing for its own use. The convergence of that demand and that organisation is what made the Heriz of the years 1890 to 1930 the Heriz one most often encounters today.</p><p>A note on naming, because the trade vocabulary is more particular than the broad term<em>Heriz</em> might suggest.<em>Heriz</em> is the modern collector&rsquo;s term for the district output broadly. Among older or more careful dealers, several finer distinctions are made.</p><p><em>Serapi</em> is the trade-name applied to Heriz district rugs from before the 1890 commercial reorganisation — looser drawing, softer colour palette (apricots, faded madder, old rose, more open spandrels), simpler ornament, often slightly larger formats. The name itself appears to be a Western corruption of<em>Serab</em>, the name of a town in the district; the term has come to mean, in practice, &ldquo;antique Heriz of better quality than the post-1890 commercial run.&rdquo; It is not a separate weaving tradition; it is the same district at an earlier moment, and the price differential between an antique Serapi and a comparable but later Heriz can be substantial.</p><p><em>Bakshaish</em> refers specifically to rugs from the village of that name, often older still than Serapi, with more primitive geometric vocabulary, occasional &ldquo;elephant foot&rdquo;<em>gul</em> motifs of clearly tribal provenance, and a strong following among current collectors who prize the quality of the older drawing and the unstandardised character of the older weaving.</p><figure><img src="/images/posts/heriz/antecedent.png" alt="An antique Bakshaish village rug — softer madder-rose palette, looser drawing, more primitive geometric vocabulary than the standardised post-1890 Heriz format"><figcaption><p>An antique Bakshaish village rug from the Heriz district — softer madder-rose palette, looser drawing, narrower borders, and the more primitive geometric vocabulary out of which the standardised post-1890 Heriz format emerged. Bakshaish remains the most-collected of the Heriz district sub-types, valued for the unstandardised handmade character of the older village tradition and the older vegetable-dye palette that the workshop-organised Heriz could not always match. The relationship between Bakshaish and Heriz is the relationship between an older village craft and the merchant-organised export production that descended from it.</p></figcaption></figure><p><em>Karaja</em> refers to the Karaja village output — usually small pieces and runners with distinctive multi-medallion compositions, often mistaken for Caucasian work because of the medallion vocabulary.<em>Mehraban</em> and<em>Ahar</em> are slightly finer Heriz-style work from those particular villages, and a few more granular village names occasionally appear in dealer descriptions of pieces with particularly distinctive provenance.</p><p>All of these are Heriz district rugs in the structural sense; the trade names are the dealer-and-collector vocabulary for finer distinctions one learns to make over time. A reasonable working approach for the beginner is to use<em>Heriz</em> as the type name, recognise<em>Serapi</em> and<em>Bakshaish</em> and<em>Karaja</em> as the principal sub-distinctions, and treat any further village-specific naming with a degree of polite scepticism unless the dealer can show how the attribution was arrived at.</p><h2 id="what-it-is-not">What It Is Not</h2><p>Most of the rugs that get called Heriz are Heriz. A few are not, and the distinctions are worth carrying in mind.</p><style>
.comparison-plate { margin: 2.2em 0; }
.comparison-plate-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1em;
background: #faf6ed;
padding: 1em;
border: 1px solid #d4cfc1;
border-radius: 4px;
}
.comparison-plate-cell { margin: 0; text-align: center; }
.comparison-plate-cell img {
width: 100%;
height: auto;
display: block;
border: 1px solid #d4cfc1;
background: #fff;
}
.comparison-plate-cell figcaption {
font-style: italic;
margin-top: 0.6em;
font-size: 0.95em;
letter-spacing: 0.03em;
color: #3a342a;
}
.comparison-plate > figcaption {
font-style: italic;
margin-top: 1em;
text-align: center;
font-size: 0.95em;
color: #5a5247;
}
@media (max-width: 600px) {
.comparison-plate-grid { grid-template-columns: 1fr; }
}</style><figure class="comparison-plate"><div class="comparison-plate-grid"><figure class="comparison-plate-cell"><img src="/images/posts/heriz/sibling-tabriz.png" alt="A Tabriz rug with a curvilinear central medallion in stepped-petal shape, surrounded by densely-drawn curvilinear floral on a rose-red field, and a wide curvilinear border" loading="lazy"/><figcaption>Tabriz<em>— the curvilinear city-workshop neighbour</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/heriz/sibling-bidjar.png" alt="A Bidjar rug with a bold geometric medallion on a saturated dark-red field, multilayered medallion structure, and a wide indigo border with floral pattern" loading="lazy"/><figcaption>Bidjar<em>— the dense Kurdish 'iron rug of Persia'</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/heriz/sibling-kazak.png" alt="A Caucasian Kazak rug with three large primitive medallions stacked vertically on a saturated red field, latch-hook borders, and the smaller more square format characteristic of the Caucasus" loading="lazy"/><figcaption>Caucasian Kazak<em>— the bold geometric to the north</em></figcaption></figure><figure class="comparison-plate-cell"><img src="/images/posts/heriz/sibling-karaja.png" alt="A Karaja runner — long narrow vertical format with three small geometric medallions stacked along the length, in indigo and ivory on a brick-red field" loading="lazy"/><figcaption>Karaja<em>— the Heriz district's runner specialist</em></figcaption></figure></div><figcaption>Four rug types most often confused with the Heriz, drawn for comparison.</figcaption></figure><p>A<em>Tabriz</em> is the city-workshop rug from the city sixty kilometres away. Tabriz uses curvilinear floral and arabesque vocabulary — sweeping vines, leaves rendered with curves rather than steps, central medallions of intricate scroll-work — and a substantially finer knot count, often a hundred and fifty or more knots per square inch. A &ldquo;village Tabriz&rdquo; or coarser Tabriz can superficially resemble a Heriz in its medallion-and-spandrel layout, but the floral elements give it away on close inspection: a Heriz rendering of a leaf is a stepped polygon; a Tabriz rendering of a leaf is a curve.</p><p>A<em>Bidjar</em> is the Kurdish-region rug from west of Hamadan. Bidjar uses geometric medallions and shares some of Heriz&rsquo;s bold-pattern aesthetic, but it is a wool-foundation rug rather than cotton, packed extremely densely (a Bidjar is famously stiff and heavy, the &ldquo;iron rug of Persia&rdquo;), and the palette runs to deeper, more saturated reds and blues. A Bidjar will not lie down flat and limp the way a Heriz will; lift the corner and the difference is immediate.</p><p>A<em>Caucasian Kazak</em> is the bold geometric rug from north of Heriz, in what is now Azerbaijan and Armenia. Kazak shares Heriz&rsquo;s geometric design vocabulary and its brick-red-and-navy palette, but the design vocabulary is different — large primitive medallions of &ldquo;Memling gul&rdquo; or &ldquo;lesghi star&rdquo; type, latch-hook borders, often a row of small geometric motifs in the spandrels, and the foundation is wool rather than cotton. Smaller formats than Heriz, almost never room-sized. A Kazak feels different in the hand — looser, more flexible, the wool-on-wool construction giving it a different drape across one&rsquo;s lap.</p><p>A<em>Karaja</em> is technically a Heriz district rug but is so distinctive in format that it deserves separate mention. Karaja is the runner specialist of the district — long thin pieces with a row of three or five small medallions arranged along the length, often confused with Caucasian work because of the medallion vocabulary. A Karaja is identifiable by its cotton foundation (the Caucasian rugs being wool-foundation), its Turkish knot (consistent with the Heriz district), and the particular character of its small-medallion composition, which one comes to recognise.</p><p>A<em>Mahal</em> or<em>Sultanabad</em> is the rug from the workshop tradition of the Sultanabad region in central Iran (modern Arak), organised by Western merchants — Ziegler chiefly — from the 1880s onwards specifically to supply the European and American market. Mahal rugs use the same broad Heriz palette but a different design vocabulary — allover floral in the field rather than medallion-and-spandrel, softer drawing, often a more open ground. The two rug types competed in the same export market and are sometimes shelved together in dealers&rsquo; inventories; the design distinction is the easiest separator.</p><p>These are the most-confused-with types. There are others — Hamadan, Sarouk, Mahal of various sub-types, Mashad in its larger formats — but the four above account for the great majority of misattributions one will encounter in the wild.</p><h2 id="what-one-looks-at">What One Looks At</h2><p>The practical discipline of identifying a Heriz, when one is standing in front of a candidate rug, comes down to a short ordered checklist.</p><p>One looks first at the design vocabulary. Stepped, angular, geometric medallion with mirroring spandrels, brick-red field, navy medallion, walnut border, ivory spandrels — this is the Heriz signature. If the design is curvilinear, it is not a Heriz. If the medallion is a Memling gul or a lesghi star and the field is full of small repeating motifs, it is probably Caucasian. If the field is allover floral with no central medallion, it is probably a Mahal or Sarouk.</p><p>One looks next at the foundation. Cotton warp and weft is the Heriz norm; wool foundation makes it a Caucasian piece or possibly a very early Bakshaish. The foundation is visible at the ends and along the selvedges, and on the back of the rug between the knots.</p><p>One looks next at the knot. Symmetrical (Turkish) on the back; if asymmetrical (Persian), it is not a Heriz. One looks at the knot density: sixty to a hundred per square inch; if much higher, it is probably a Tabriz; if much lower, possibly a Caucasian piece or a coarser village product from elsewhere.</p><p>One looks at the wool — its lustre, its lanolin content, the quality of the pile. Old Heriz wool has a particular sheen that synthetic-dyed and carded modern wool lacks, and a pile that has worn unevenly over decades of household traffic looks very different from a pile that has been chemically aged.</p><p>One looks at the dyes. Vegetable dyes age into patina; aniline dyes age into flatness. In the older pieces (pre-1900), one is looking at vegetable dyes throughout. In the post-1900 commercial pieces, one may see a mix; in modern Heriz, frequently aniline throughout. The &ldquo;abrash&rdquo; — the slight horizontal banding of colour as the dyer&rsquo;s batches changed — is a positive sign in an older piece; an absolutely uniform field suggests a single industrial dye-lot, which is the modern signature.</p><p>And one looks at the wear pattern. A Heriz that has been in a household for fifty years shows wear in a very particular way — silvery patches in the high-traffic centre, more saturated colour in the protected margins, a softening of the dyes that synthetic ageing cannot reproduce. The wear is, in itself, evidence of provenance.</p><p>That is the discipline. With it, one can stand in front of any candidate rug and, in the better part of ten minutes, give a defensible attribution. Without it, one is at the mercy of the dealer&rsquo;s confidence — which, as the opening of this post observed, is not always reliable.</p><p>The next post in the arc will be either Tabriz — to set out the city workshop tradition that Heriz both grew up beside and distinguished itself from — or Bakshaish, the older village tradition out of which Heriz proper grew. The choice will depend on what photographic material is available at the time of writing.</p>
]]></content:encoded></item><item><title>Reading the Antique</title><link>https://mtclinton.com/posts/reading-the-antique/</link><pubDate>Thu, 14 May 2026 15:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/reading-the-antique/</guid><category>antiques</category><description>Opening note for a new series on the blog — two parallel arcs on antique rugs and on period furniture, in the spirit of the long-running architecture series.</description><content:encoded>&lt;![CDATA[<p>There is in the connoisseur&rsquo;s habit of mind a quiet expectation that any object of sufficient age, well-made, will on inspection prove to have a story attached to it — and that the story can, with patience, be read off the object itself. The wear pattern under a chair leg is evidence; the knot count on a square inch of rug is evidence; the joinery at the back of a drawer is evidence; the way a piece of inlay has shrunk over a century-and-a-half of household weather is evidence. None of this is hidden. It is merely waiting for someone willing to slow down sufficiently to look.</p><p>This is the opening note of a new series on the blog, in the spirit of the<a href="/categories/architecture/">architecture series</a> that has by now run to a dozen posts. The premise is precisely the same as that one and applied to a different class of object. Houses can be read; so can rugs; so can the cabinets and tables and chests of period furniture, of every national tradition and every century back as far as the documentary record reasonably stretches. The reading is a teachable skill. Most of it consists of knowing what categories of evidence to attend to and what categories one can safely ignore, and the great majority of an apparently mysterious piece — the unsigned chair, the unattributed rug — gives up the better part of its provenance to ten or fifteen minutes of careful looking, once one has the trained eye.</p><h2 id="two-arcs">Two Arcs</h2><p>The series has been laid out in two parallel arcs which will run, without any particular pretence to a single cadence, alongside one another for as long as the subject continues to repay attention.</p><p>The first is<em>Reading the Antique Rug.</em> The arc takes one regional weaving tradition per post — Heriz from the slope above Tabriz, Tabriz itself, Kashan, Bidjar, Hamadan, Kazak from the Caucasus highlands, the Tekke and Salor and Yomut weavings of the Turkmen, the Hereke court rugs of late Ottoman Turkey, the Oushak villages of western Anatolia, the Mughal-influenced workshops of Agra and Amritsar, and so on through the body of weaving traditions that the European and American collecting market has paid serious attention to over the past century and a half. Each post gives the regional context, the structural and material signatures by which the type is identified, the design vocabulary peculiar to it, and the trajectory of its market reception over the period in which it has been collected. A Heriz is not a Tabriz. A Tekke is not a Salor, though to an unfamiliar eye both will look like what one might lazily call &ldquo;a Bukhara.&rdquo; The arc is in part a corrective to that lazy looking.</p><p>The second is<em>Reading the Period Cabinet.</em> This arc takes one national furniture tradition at one well-defined period per post — French Louis XIV through Empire, the run of English styles from Jacobean through Chippendale and Sheraton and Hepplewhite into Regency, the Italian Renaissance and Baroque and the long slow Italian Rococo, German Biedermeier in its short and remarkable mid-century run, the Spanish baroque and the Mudejar before it, the Dutch marquetry tradition, the Scandinavian Gustavian and its quiet proto-modernism, the American colonial through Federal through Empire and on into Eastlake and Mission. Each post takes the tradition on its own terms — the construction methods, the wood and the hardware, the vocabulary of ornament, the social function of the principal forms, the changes that were quietly happening underneath the more visible stylistic changes. Furniture is, more than any other class of antique, an index of the society that produced it; one sees in any cabinet or commode of any period the kind of household it was built to live in, and a great deal else besides.</p><h2 id="the-method">The Method</h2><p>Each post in either arc will follow approximately the same shape, which is the shape that has worked for the architecture series and which one knows by now to trust.</p><p>It will begin with the specimen — a particular rug, a particular form of cabinet — and walk the reader through what one looks at first, what one looks at second, and what features are decisive between this type and the half-dozen other types it most resembles. It will set out the structural and material evidence: in rugs, the warp and weft and pile and dye; in furniture, the wood and the joinery and the hardware and the finish. It will give the regional or workshop context — where the type was made, who made it, who used it, who later collected it. It will show siblings — the nearest neighbour types, with which it is most often confused — and antecedents, the older traditions out of which it grew. And it will close with the kind of practical attention that is the principal reason one bothers learning any of this in the first place: how to know, when one is looking at a particular example, what one is looking at.</p><p>Each post will carry its own plate in the series visual idiom. The rug plates will be set out as if from a Victorian connoisseur&rsquo;s portfolio of weaving studies; the furniture plates as if from a nineteenth-century cabinet-maker&rsquo;s pattern book. The aesthetic stays as it has been — copperplate engraving on parchment, restrained Edwardian register, a single warm accent — and the cartouche on each plate will signal which arc the post belongs to. Each post will also, where the type repays it, carry the smaller secondary plates on which the architecture posts have settled: an antecedent, three details, a workshop or pattern-book page, four siblings — adapted in each case to what the subject actually demands.</p><h2 id="what-to-expect">What to Expect</h2><p>The series will run on no particular cadence. Some weeks will produce a rug post; some will produce a furniture post; some will produce both; some will produce neither. The arcs are independent. There is no plan to interleave them by any rule, and no commitment to publish in any fixed order within either.</p><p>The first per-subject post of either arc will arrive shortly. It is likely to be a rug — Heriz, almost certainly, because Heriz is the type that most rewards an opening post and the type whose place in the wider weaving tradition makes it the cleanest first specimen for an arc that will eventually want to discuss the others by reference to it. But this is not a strict commitment.</p><p>A general note, for any reader who is accustomed to the architecture series and is wondering what the difference is. Houses are easy to write about because one can see the whole of them from across the street, and the great American house types of the past century and a half have been documented in a body of pattern books, magazines, and architectural surveys deep enough that the bibliography for any given style is available within a few hours&rsquo; library work. Rugs and period furniture are different. Each requires that one learn what to look at — the diagonal of a Heriz medallion, the carve of a Chippendale ball-and-claw foot, the camelback of a Hepplewhite shield-back chair, the silver-blue field of a Salor<em>engsi.</em> A great deal of the satisfaction of antiques is in the slow process of acquiring those specific looks. The series is, in a sense, an offered apprenticeship.</p><p>That, in any case, is the standing invitation. The first specimen post is in preparation, and will arrive when it is ready.</p>
]]></content:encoded></item><item><title>AI in the Slaughterhouse</title><link>https://mtclinton.com/posts/ai-in-the-slaughterhouse/</link><pubDate>Thu, 14 May 2026 13:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ai-in-the-slaughterhouse/</guid><category>ai</category><description>On the second largest piece of the AI landscape that the trajectory series did not see — the camera on the kill floor, and what it has been quietly doing for thirty years.</description><content:encoded>&lt;![CDATA[<p>The kill floor of a modern American beef packing plant moves at a speed that does not lend itself to deliberation. A large plant — at IBP, JBS, Cargill, National Beef — runs two shifts and processes between five and six thousand cattle in a day. Every carcass is split into sides, hung, chilled, and walked past a sequence of stations, each station performing one decision in the chain that ends with a price on the cut at the grocery store. One of those stations, near the chill cooler, is a camera. The camera is mounted at a fixed position; the carcass arrives at it on schedule; a light is thrown across the exposed ribeye cross-section of the twelfth rib; an image is taken. In rather less than a second, the camera returns a USDA quality grade — Prime, Choice, Select, Standard — and a yield grade between one and five. The grade is stamped onto the carcass; the carcass moves on. The system, generically the VBG2000 from a German firm called e+v Technology and its modern successors, has been certified by the USDA in some form since the mid-1990s, deployed at scale across the American beef industry through the 2000s and 2010s, and by 2026 is, in any plant of significant size, the source of the great majority of the grades that determine the price of every cut of beef sold in the country.</p><p>This post is the second of two corrections — the first, earlier today, was on the<a href="/posts/ai-at-3am/">emotional-support use of frontier language models</a> — to the five posts on AI-lab trajectories I wrote last week. Those posts measured the things the analyst class is in the habit of measuring: model release cadence, revenue, compute, regulatory standing, distribution moats. They did not measure the camera on the kill floor, because the kill floor is not in any of the rooms the analyst class visits. The argument of this second corrective is parallel to the first and, by the time one has finished, perhaps stronger: the AI deployment that is most thoroughly built into the physical world in 2026 is not the deployment the AI conversation can see.</p><h2 id="the-floor-and-the-number">The Floor and the Number</h2><p>A few facts, in the order one would want them.</p><p>The United States slaughters roughly thirty-two million head of cattle a year, the great majority of them through the four largest packers — Cargill, Tyson (which owns IBP), JBS USA, and National Beef. At full operation, these four account for something on the order of three-quarters of the country&rsquo;s fed-cattle slaughter. A daily throughput of a hundred and twenty thousand carcasses across all American beef plants is not a stretching number; in many weeks of the year it is exceeded.</p><p>Every one of those carcasses is graded, because grading is what the price is paid against — the difference between a Prime and a Choice ribeye, at wholesale, is several dollars a pound, and the difference between an upper-Choice and a lower-Choice carcass, multiplied across the eight or nine hundred pounds of saleable beef a steer carries, is meaningful money to the packer and to the rancher who supplied the animal. Before camera grading, this work was done by USDA-employed master graders, who walked the cooler with the carcasses and rendered a judgment by eye on each. The job required years of training, a steady eye, and a willingness to spend one&rsquo;s working life among hanging carcasses; the supply of qualified graders never quite kept up with the demand. By the middle of the 2010s, the camera systems had been certified at a sufficient number of decision points — the USDA accreditation is staged across marbling, ribeye area, lean color, fat color, and skeletal maturity — that the cameras did the work and the human grader supervised it. By the early 2020s, the supervision had become, in most plants, a matter of resolving the cases where the camera reported low confidence or where the boundary between two grades fell within a few percent of marbling. By 2026, a significant majority of the beef carcasses graded in the United States receive their USDA quality grade from a piece of software, and the grader signs off on the camera&rsquo;s verdict at a pace that human-only grading could not have approached.</p><p>The agreement-rate numbers, where the USDA has published them, hold their shape across more than a decade of refinement: on marbling, the cameras and the master graders agree, depending on the system and the year of evaluation, somewhere in the high eighties to mid-nineties of a percent; on ribeye area, where the measurement is geometric rather than subjective, agreement is higher still and the cameras are usually treated as the ground truth. Throughput per inspection station, against the human-only baseline of an experienced grader doing seven hundred to eight hundred carcasses on a shift, is anywhere from three to six times higher with the camera in the loop, and the ceiling continues to lift as confidence-routing improves and the high-confidence cases bypass human review entirely.</p><p>These are the deployment numbers of a piece of artificial intelligence that has been in the field for thirty years, has cleared regulatory accreditation in five separate decision categories, has paid back its capital cost in every plant of any size, and has reorganized the labor of an entire profession around itself.</p><h2 id="the-wrong-newsroom">The Wrong Newsroom</h2><p>One would think this would receive some coverage. It does, in fact, receive coverage — in<em>The National Provisioner</em>, in<em>Meatingplace</em>, in<em>Meat &amp; Poultry</em>, in the USDA&rsquo;s own<em>Livestock Slaughter</em> releases, and in a fairly substantial body of agricultural-economics literature. None of these publications, with the kindest will, are read by the people who write about artificial intelligence for a living. The AI trade press — which is to say<em>TechCrunch</em>,<em>The Information</em>,<em>Stratechery</em>,<em>Semafor</em>, the AI sections of the<em>Wall Street Journal</em> and the<em>Financial Times</em>, and the considerable cottage industry of independent newsletters that has grown up around the language-model labs since 2023 — has, as far as I have been able to find, written almost nothing about kill-floor camera grading at any point in the past five years. The deployment is too long-running to be news, the publications that cover it are not on anyone&rsquo;s beat, and the firms involved — e+v Technology, the four packers, the USDA Agricultural Marketing Service — do not seek out the AI press because they have nothing to sell it.</p><p>This is the second face of the same problem the first corrective described. The first was that<em>emotional support</em>, by conversation volume, is the largest single use of frontier language models in 2026, and goes almost entirely uncounted by the analyst class because it does not generate API revenue. The second is that<em>industrial visual quality grading</em> is, by physical-world depth of deployment, the most thoroughly embedded use of artificial intelligence in the American economy in 2026, and goes almost entirely uncounted because the rooms in which it happens are not the rooms in which the analyst class drinks coffee. In both cases the structural problem is the same: when an industry describes &ldquo;what AI does in the world,&rdquo; it ends up describing what AI does in its own line of sight. The line of sight does not reach the chill cooler at a Cargill plant in Dodge City.</p><h2 id="why-it-works-on-that-floor">Why It Works on That Floor</h2><p>There is a quiet structural argument for why camera grading became the deployment it became, while a hundred more famous applications stalled. It rests on three properties of the task.</p><p>The first is that the task is, at its core, a perception problem and not a reasoning problem. The camera does not need to<em>understand</em> beef; it needs to look at a marbling pattern and return a grade. There is no chain of inference, no context window of relevant prior facts, no consideration of intent. A trained vision system, given enough labeled examples, is exactly the right tool for that shape of problem, and was the right tool well before the language-model era. The cameras did not have to wait for the breakthroughs of the 2020s; the breakthroughs of the 1990s were sufficient, and the improvements since have only made the system more capable at the margins.</p><p>The second is that the conditions of the task are tightly controlled. Every carcass arrives at the camera at the same height, the same orientation, the same distance, in the same light. The variables that defeat consumer-grade vision systems — clutter, occlusion, lighting drift, unfamiliar pose — are, on the kill floor, engineered out of existence by the floor itself. Industrial AI has always performed well in industrial conditions; the conditions are what one might call the<em>quiet half</em> of the deployment story, the half that is built before any model is trained.</p><p>The third is that the supply of training data is exceptionally good. Decades of human master-grader decisions are available, every one of them tied to a downstream price the meat actually fetched in market. Ground truth in most machine-learning problems is contestable, expensive, or both; on the kill floor it is grounded in dollars, which is the cleanest signal there is. A model trained on what the master graders called Prime, against carcasses that went to market and fetched Prime prices, has a label set that is honest in a way that human-language-task label sets almost never manage.</p><p>These three properties — perceptual task, controlled conditions, dollar-anchored labels — are not unique to beef grading, but they are unusually clean there. The same triad is what made AI work for poultry inspection at Marel and Baader, for produce sorting at Tomra and Bühler, for fish grading, for pork carcass measurement at Frontmatec. The pattern is wider than the kill floor. The kill floor is simply the cleanest example, and the longest-running.</p><h2 id="what-this-is-not">What This Is Not</h2><p>One ought to be plain about what this is not.</p><p>It is not a story of a profession disappeared. USDA master graders still exist, still walk the floor at every major packing plant, still draw a salary from the Agricultural Marketing Service, and still own the final word on any carcass the camera flags as ambiguous. What has changed is that they verify rather than originate, and that the same number of graders covers many more carcasses than they could have done by eye. The labor has been rebalanced; it has not been eliminated, and the experienced graders who remain on the floor are arguably more valuable than they were in the human-only era, because their judgment is what resolves the cases the camera will not.</p><p>It is not a story of an industrial deployment that arrived through any sudden breakthrough. The first vision-based grading patents date to the late 1980s; the first USDA approvals to the mid-1990s; the rollout has been a thirty-year unbroken line of steady refinement and steady regulatory accommodation. The lesson, if there is one, is the dull lesson — that the most consequential AI deployments are not the ones one reads about on the day they ship.</p><p>It is not a story that generalizes effortlessly to the rest of the meat economy. Pork carcass grading uses different measurements (lean percentage rather than marbling) and different equipment. Poultry inspection is largely about defect detection, not quality grading, and runs at much higher line speeds with different cameras. Fish grading has its own peculiarities. Each of these is a deployment in its own right; each has its own three-decade history; none of them is the same as beef.</p><p>And it is not, finally, an argument that the deeper economic significance of AI in 2026 lies<em>only</em> in industrial visual grading. The first corrective made the case for emotional support; this one makes the case for visual quality grading; there are several other categories — predictive maintenance on heavy industrial equipment, optical character recognition at the back of every bank in the country, computer-vision defect detection in semiconductor fabrication, claims-triage models at every casualty insurer — that share the basic shape of this argument and that the AI trade press also does not cover. The plural form of the claim is that the analyst class has, as a class, a<em>coverage problem</em>, and that the largest and most embedded AI deployments are systematically the ones it is least equipped to see.</p><h2 id="the-plain-fact">The Plain Fact</h2><p>The structural facts come out, in order, as follows.</p><p>The first is that beef-grading cameras, by any measure of depth — regulatory accreditation, capital expenditure, supply-chain integration, labor reorganization, equipment lifetime — are among the deepest AI deployments in the American economy in 2026. A federal agency has certified them in five separate decision categories. The four largest packers have committed multi-decade capital to them. The price of every fed-cattle carcass in the country flows through them. The depreciation schedule on the equipment runs into the 2030s. Whatever else one wants to say about AI in 2026, it is harder to remove this deployment than it is to remove almost any chatbot one cares to name.</p><p>The second is that the analyst class&rsquo;s account of what AI does in the world is not a description of what AI does in the world. It is a description of what AI does in the rooms the analyst class visits — productivity tools, agent platforms, consumer apps, API surfaces. The rooms it does not visit — the kill floor, the hospice room, the back of the bank, the fabrication plant — are where the depth of deployment runs deepest. The five trajectory posts, this corrective and the previous one included, are an extended argument against the analyst class&rsquo;s own map.</p><p>The third is the one I should like to leave plainly. The chatbot&rsquo;s history is short, has been long-promised, and could in principle be reversed by a shift in subsidy or in sentiment. The camera on the kill floor has a long history, has been quietly extending its reach for thirty years, is built into the price of a steak, and would require an act of regulatory withdrawal that no constituency is asking for in order to remove. The first is more visible; the second is more permanent. The thing one writes about and the thing one builds one&rsquo;s economy around are, in 2026, no longer the same thing.</p><p>On the floor, the line keeps moving, the camera keeps grading, and the price keeps being set on what the camera sees. None of it has required anyone&rsquo;s coverage. All of it has been the case for thirty years.</p>
]]></content:encoded></item><item><title>AI at 3 a.m.</title><link>https://mtclinton.com/posts/ai-at-3am/</link><pubDate>Thu, 14 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ai-at-3am/</guid><category>ai</category><description>On the largest single use case for frontier language models in 2026, and why almost no one is measuring it.</description><content:encoded>&lt;![CDATA[<p>Three in the morning is not, by any usual reckoning, a productive hour. The work day is long over, the next is far off; the company one had at dinner has gone home and the company one had at midnight has gone to sleep. The hour belongs to those who cannot sleep, for whatever cause, and have at last given up the contest and got out of bed. Until quite recently the options at three in the morning were limited and well-known: the telephone helpline, the worn page of a journal, the cup of tea, the patient ear of the few people one might still telephone without shame. The list has grown by one. The frontier language models — ChatGPT in particular, but the others nearly indistinguishably — are at three in the morning what they are at any other hour, and what they are is awake, attentive, and prepared to listen as long as one wishes to talk.</p><p>This post is about what the people at the keyboard are doing at that hour, and what the consequence is of having miscounted, in five long posts last week, what the technology that is doing the listening is actually being used for.</p><h2 id="the-hour-and-the-number">The Hour and the Number</h2><p>There is, by now, the beginning of a body of survey work that takes this seriously. A study published earlier this year by the Sentio program — a clinical training institute in California, which one might expect to be skeptical of its own subject — surveyed nearly five hundred American adults with ongoing mental health conditions, all of whom had at some point used a language model. The headline of the study was that, of those who used artificial intelligence at all, very nearly half — 48.7 per cent — used a language model for what the survey called<em>therapeutic support</em>. Of those, 96 per cent named ChatGPT specifically. Most of them — 87 per cent — had at some point also been in human therapy. Three-quarters of those reported the language-model experience as on a par with, or better than, the experience of human treatment.</p><p>The arithmetic that follows is the small, uncomfortable one. The Veterans Health Administration, which is among the largest single mental-health providers in the United States, treats some 1.7 million patients a year. If the Sentio numbers are anywhere near the truth — and they are imperfect, like all survey numbers, but they are the best one has — then ChatGPT alone is treating, by any informal definition of the word, more people than the V.A.</p><p>The numbers come from another direction as well. OpenAI itself has, in the past nine months, begun publishing internal usage research that does not flatter the company but appears to be substantially honest. The figures are small as proportions and large as absolutes. In any given week, 0.15 per cent of weekly active ChatGPT users — that is, by the company&rsquo;s own count of approximately nine hundred million weekly active users, roughly 1.35 million people — show signs of<em>suicidal intent</em> in the language of their conversations with the model. A further 0.07 per cent — roughly six hundred thousand people in a week — show signs of psychosis or mania. A further 0.15 per cent — another million-plus — show signs of what the company gingerly calls<em>heightened emotional attachment</em> to the model itself.</p><p>These are people the company is, by its own admission, in conversation with at the worst moments of their week. Whatever ChatGPT is, this is part of what it is. It is not the part the product launches dwell on, and it is not the part the trade press writes long features about, but it is — by any defensible reading of the numbers — among the parts the model spends the most cumulative time doing.</p><h2 id="the-wrong-denominator">The Wrong Denominator</h2><p>I have been thinking about this, in part, because I spent the last week of my own time writing five long blog posts about the trajectories of the major AI labs through 2028. The posts measured what one measures in such pieces: revenue, valuation, compute capacity, model release cadence, regulatory standing, headcount, hardware bets, distribution moats. They did the work the analyst class does. They did not, anywhere, attempt to count what the median user of these models is actually using them for.</p><p>This is a problem of denominators. Almost every public discussion of AI takes as its denominator either<em>API revenue</em> — which is paid for, and which therefore corresponds to commercial usage — or<em>paid subscriptions</em>, which corresponds to power users and the upper end of the consumer market. The largest single user behaviour, on inspection, is neither. The largest single user behaviour is a person who has not paid anyone anything, opening a conversation in a free-tier chat window, and asking a question that no commercial system has ever been built to answer.</p><p>The questions are familiar enough that the model has long since learned the rhythm of them.<em>I am thinking of leaving my marriage.</em><em>My mother has been given six months and I do not know how to tell my brother.</em><em>I think my friends are tired of me.</em><em>I do not think I am going to make it through the night.</em><em>I am ashamed of the thing I did and cannot tell my partner what it was.</em><em>Is what I am feeling normal.</em><em>Will it be like this forever.</em> The questions are not, strictly, questions; they are a kind of speaking-aloud for which the response matters less than the receipt. The model receives them. It does so without becoming bored and without leaving early and without being too busy at work and without having ever met one&rsquo;s mother. This is a particular shape of conversation, and a great many people, by the published numbers, are now having it.</p><h2 id="why-it-works-at-that-hour">Why It Works at That Hour</h2><p>There is a quiet structural argument for why the late-night model conversation works at all. It rests on three things that human therapeutic relationships, for entirely respectable reasons, cannot offer. The first is availability. A trained therapist sees a patient once a week for fifty minutes; an experienced patient with means may see a therapist twice a week; very few patients see a therapist at three in the morning, and almost none for an hour and a half. The frontier model is available always, for as long as one wishes, on a schedule decided entirely by the person at the keyboard.</p><p>The second is anonymity. The person at three in the morning has not signed an intake form, has not given a name, has not driven across town to an office. They have opened a window in their own house. The conversation begins without the asymmetry of disclosure — the patient knows nothing of the therapist either, but the patient<em>feels</em> known by a chair, a name plate, a license on a wall; the model has no chair to sit in and no name plate to look at. Whatever asymmetry exists is invisible, and for many users this is the necessary condition for speaking at all. The shame that would prevent a confession to a friend, or a referral to a clinician, does not exist in the same form when one is alone with an interface.</p><p>The third is patience. The model does not become tired. It does not begin to look at its watch as the session approaches its end. It does not have its own day to return to, its own children to collect, its own troubles to absorb. It will, by design, listen to the same question framed eleven different ways and offer the eleventh answer with the same care as the first. The therapeutic literature is clear that there is a difference between the active listening a trained clinician can sustain for fifty minutes and the simulated listening that a model can sustain for nine hours, but this is not a difference that the person at the keyboard at three in the morning is in a position to care about. The person at the keyboard is comparing the model not to the best therapist they have ever had, but to the absence of any therapist at all at the hour in question. Against that comparison the model wins almost trivially.</p><h2 id="what-this-is-not">What This Is Not</h2><p>One ought to be plain about what this is not. It is not, as the most enthusiastic accounts of AI therapy sometimes imply, a replacement for human treatment, and very nearly every responsible commenter in the space says so. The Sentio survey itself is careful: nearly nine in ten of the respondents who used a model for support also had experience with human therapy, and a substantial minority were using both at the same time. This is supplementation, not displacement. The displacement question is real, and one should not pretend it is not — but the immediate fact is that most of the people in question already had access to human care and were choosing, at the particular hour, to use the model in addition to it.</p><p>It is also not safe in the senses one might wish for. The OpenAI numbers above are alarming on their face. A million and a half people a week disclosing suicidal intent to a language model are a million and a half people whose interlocutor is, at a structural level, not a clinician, not licensed, not subject to malpractice review, and not — until very recently — even particularly well-trained to respond to that disclosure. OpenAI has spent the last year explicitly training GPT-5 to recognise and respond to crisis disclosures, in consultation with what it describes as more than 170 mental-health experts. The new model, on the company&rsquo;s own internal benchmarks, reduces undesired answers in such conversations by 42 per cent over its predecessor. This is welcome and it is also a small number to be welcoming. A 42 per cent reduction in undesired answers is not the absence of undesired answers; it is, by definition, the persistence of more than half of them.</p><p>And it is not — and one should be careful here — what one might call good treatment in the sense the clinical literature would mean. The model cannot prescribe; the model cannot make a treatment plan; the model cannot follow up in the morning; the model has no idea what one looked like yesterday or last week or before the dose was changed. A model conversation, even a very long one, is a single sitting with a stranger who will be a different stranger by next month, whose training data is what it is, and whose memory of one&rsquo;s life is precisely what one has typed into it in the last hour. This is not nothing — for many users, including by their own report, it is a great deal — but it is not what fifty years of clinical research describe when they describe psychotherapy.</p><h2 id="the-plain-fact">The Plain Fact</h2><p>What I think one should take from this, taking the numbers honestly, is something more modest than either the enthusiasts or the critics have proposed.</p><p>The first is a measurement correction. The analyst class has been counting the wrong thing. The trade press writes about productivity, and the labs write about agent platforms and API revenue, and the policy class writes about safety and capability and bifurcation. Almost no one writes about emotional support, because the volume is unbillable, the user is non-strategic, and the conversation does not show up in any company&rsquo;s published numbers except as one rounded line in a quarterly research report. But by usage volume — which is, after all, what one would mean by<em>what AI is doing</em> in the strict sense — it is the single largest activity these systems engage in. Any picture of the AI industry that does not contain it is missing the largest piece. The five posts I spent last week on the trajectories of the labs, accurate enough as they may have been about API revenue and compute capacity, did not contain it; in this respect, and probably others, they missed the picture.</p><p>The second is a structural fact. There exists, in the United States and elsewhere, a vast quiet demand for someone — anyone — to listen to a person at three in the morning. The demand existed long before language models did, and the supply has never come close to meeting it. The supply now includes one new and uncomfortable category, and that category is at present meeting the demand at a scale no human institution has matched. One can argue about whether that is good or bad. One cannot reasonably argue that it is not happening.</p><p>The third is the small uncomfortable fact one comes back to whenever one looks at the numbers carefully. The model, taken in aggregate, is at this moment the largest provider of mental-health-adjacent conversation in the country, and quite possibly in the world. Its weekly user base in the United States is several multiples of the entire licensed clinical psychology workforce. Its availability is total and its cost, in most cases, is zero. The clinical psychology workforce is highly trained, deeply expert, and almost universally over capacity — there has not been a single sustained year in the last twenty in which it has been possible to get an appointment with a competent therapist in most American cities in less than three weeks; in many cities it is months. The language model, whatever its limits, picks up immediately.</p><p>This is the shape of the use case the predictions posts did not measure. It is the shape of the use case the labs do not advertise. It is, on inspection, the largest single thing the technology is doing in the world.</p><p>One should, at minimum, count it.</p>
]]></content:encoded></item><item><title>The Chinese AI Trajectory</title><link>https://mtclinton.com/posts/the-chinese-ai-trajectory/</link><pubDate>Wed, 13 May 2026 11:45:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-chinese-ai-trajectory/</guid><category>ai</category><description>A categorized set of predictions about the Chinese AI frontier through the end of 2028.</description><content:encoded>&lt;![CDATA[<p>This is the fifth and final post in a series cataloguing predictions about the major AI labs through the end of 2028. The series also covers<a href="/posts/the-anthropic-trajectory/">Anthropic</a>,<a href="/posts/the-openai-trajectory/">OpenAI</a>,<a href="/posts/the-google-deepmind-trajectory/">Google DeepMind</a>, and<a href="/posts/the-meta-ai-trajectory/">Meta</a>. This post is structured differently from the others — the Chinese frontier is an ecosystem of competing labs operating inside a state-coordinated framework, not a single-lab trajectory. Predictions are organized by ecosystem-wide moves and by lab-specific moves where useful.</p><p>Where the Chinese AI frontier stands as of mid-May 2026, for context:</p><ul><li><strong>Tier-1 model lineup</strong> (open-weight, all approaching or competing for Western frontier parity):<ul><li><strong>Zhipu AI / GLM-5</strong> — leads on overall benchmarks (BenchLM 85, 77.8% SWE-bench Verified), MIT-licensed,<strong>trained entirely on Huawei Ascend chips</strong> (no Nvidia in the training stack).</li><li><strong>Moonshot AI / Kimi K2.5</strong> — dominates agentic benchmarks (76.8% SWE-bench, 74.9% BrowseComp) using &ldquo;agent swarm&rdquo; technology with up to 100 parallel sub-agents.</li><li><strong>Alibaba / Qwen 3.5</strong> — strongest multilingual;<strong>100,000+ derivative models on HuggingFace</strong>, the largest open-weight ecosystem on the platform, surpassing every Western counterpart including Meta&rsquo;s Llama.</li><li><strong>DeepSeek V4</strong> (released February 2026) — cheapest at $0.14–0.30/M input tokens, conditional government approval to purchase Nvidia H20 chips for the next training generation.</li><li>Plus ByteDance / Doubao, Baidu / ERNIE, Tencent / Hunyuan, MiniMax, 01.AI / Yi.</li></ul></li><li>Chinese labs hold<strong>four of the top five positions in open-weight AI</strong> at this moment.</li><li><strong>Huawei Ascend 950PR</strong> launched March 21, 2026 — 1.56 PFLOPS, 2.8× the FP4 performance of Nvidia&rsquo;s H20,<strong>128GB of Huawei-developed in-house HBM at 1.6 TB/s</strong> (no Korean dependency). 750K units planned for 2026, ByteDance committed $5.6B in orders. CUDA-compatible software stack lowers migration barriers.</li><li><strong>Ascend 950DT training variant</strong> ships with 144GB HBM at 4 TB/s.</li><li><strong>CXMT</strong> (Chinese domestic memory maker) is converting 20% of DRAM capacity to HBM3 — second domestic HBM source beyond Huawei&rsquo;s in-house production.</li><li><strong>Huawei Ascend roadmap targets 4 ZettaFLOPS FP4 cluster-level performance by 2028.</strong></li><li><strong>Huawei is selling Ascend 950 in South Korea</strong> in 2026 — exporting Chinese AI silicon globally, not just serving domestic demand.</li><li><strong>WAIC Shanghai 2026</strong> scheduled July 22–24 — the centerpiece annual event, organized by China&rsquo;s Ministry of Science and Technology and the Shanghai municipal government.</li><li><strong>Global AI Cooperation Organization</strong> — Premier Li Qiang&rsquo;s 2025 WAIC proposal for a multilateral AI governance body alternative to Western frameworks; expected formal launch at WAIC 2026.</li><li><strong>Belt and Road AI infrastructure</strong> (the &ldquo;Digital Silk Road&rdquo;) already operational in multiple Central Asian, Southeast Asian, and African partner countries — bundled stacks include cloud, fiber, smart city platforms, training clusters, inference nodes, and managed model services.</li><li>US chip export controls remain the structural constraint, but<strong>the export-control regime&rsquo;s effectiveness is visibly diminishing</strong> as Huawei in-house HBM, CXMT external HBM3, SMIC at 5–7nm, and the Ascend 950PR / 950DT / 960 progression close the chip-sovereignty gap.</li></ul><p>The predictions below are anchored on that baseline. Each has a target time window and a confidence level reflecting how willing I am to be wrong publicly about it. The 2026 predictions are anchored on observable cadence (WAIC July 22–24, Chinese tech earnings, US export-control update timing). The 2027 and 2028 predictions compress to quarter and year resolution as uncertainty widens.</p><hr><h2 id="2026-balance-of-year">2026 (Balance of Year)</h2><h3 id="models--api">Models / API</h3><ul><li>DeepSeek V4 broader rollout completes across Chinese cloud providers and API resellers<em>(May 2026, high)</em></li><li>Conditional Nvidia H20 approval expands beyond DeepSeek to Moonshot, Zhipu, ByteDance — quotas tied to MIIT review<em>(Q3 2026, medium)</em></li><li>DeepSeek R3 reasoning model released<em>(Jun 2026, high)</em></li><li>Qwen 4 preview released — smaller variants first<em>(Jun 2026, high)</em></li><li>ByteDance Doubao 3.0 released<em>(Jun 2026, high)</em></li><li>Coordinated WAIC release wave: Qwen 4 GA, GLM-6, DeepSeek V5, Kimi K3 ship within a 72-hour window<em>(Jul 22–24, 2026, high)</em></li><li>Mythos-class cybersecurity-specialized model released by at least one Chinese lab — likely Zhipu or Tencent<em>(end of 2026, medium)</em></li></ul><h3 id="compute--chip-sovereignty">Compute &amp; Chip Sovereignty</h3><ul><li>Huawei Ascend 950PR ships to ByteDance and Zhipu in volume — Q3 2026 cumulative shipments cross 300K units<em>(Q3 2026, high)</em></li><li>Chinese domestic HBM (Huawei in-house + CXMT) reaches sufficient scale to remove Korean HBM as a tier-1 frontier-training bottleneck<em>(H2 2026, high)</em></li><li>Huawei Ascend 950PR full-year 2026 shipments: 600–900K units<em>(Dec 2026, medium)</em></li><li>US BIS releases additional advanced-chip export restrictions — possibly extending to HBM equipment<em>(Q3 2026, medium)</em></li><li>Chinese reciprocal export move on critical minerals or rare earths in response<em>(Q3 2026, medium)</em></li><li>First Huawei Ascend export to South Korea cluster-level deployment confirmed<em>(2026, high)</em></li></ul><h3 id="distribution--consumer-apps">Distribution &amp; Consumer Apps</h3><ul><li>ByteDance Doubao MAU exits 2026 at 250–350M<em>(Dec 2026, medium)</em></li><li>Moonshot Kimi MAU exits 2026 at 150–200M<em>(Dec 2026, medium)</em></li><li>Combined Chinese consumer AI assistant base reaches 600–800M MAU across Doubao, Kimi, Tongyi, ERNIE Bot, Yuanbao<em>(end of 2026, medium)</em></li><li>Qwen derivative count on HuggingFace crosses 150K — extending lead as the largest open-weight ecosystem in the world<em>(Q3 2026, high)</em></li></ul><h3 id="state-coordination--policy">State Coordination &amp; Policy</h3><ul><li>Premier Li Qiang or senior MIIT official announces a coordination structure for frontier AI labs at WAIC — &ldquo;AI National Champion Coordination Initiative&rdquo; or similar framing<em>(Jul 22–24, 2026, medium)</em></li><li>Global AI Cooperation Organization formally launches with founding non-OECD members (Brazil, Indonesia, UAE, plus 2–3 African and 1–2 ASEAN partners)<em>(Jul 2026, high)</em></li><li>MIIT 2027 AI policy framework drafted, released in late 2026 or early 2027<em>(end of 2026, medium)</em></li><li>CCP plenum or equivalent late 2026 — language framing AI as &ldquo;strategic productive force&rdquo; with funding commitments at the trillion-RMB level over 5 years<em>(Q4 2026, medium)</em></li></ul><h3 id="belt-and-road--non-oecd-distribution">Belt and Road / Non-OECD Distribution</h3><ul><li>Chinese AI infrastructure operational in 15–25 Belt and Road partner countries by year-end<em>(Dec 2026, high)</em></li><li>5+ Belt and Road partner countries have formal multi-year exclusive AI infrastructure agreements<em>(Dec 2026, medium)</em></li><li>First Saudi Arabia–Huawei sovereign AI compute pilot announced<em>(Q4 2026, low)</em></li><li>Belt and Road AI deployment financing channeled through existing CDB / Exim / Silk Road Fund mechanisms<em>(2026, high)</em></li></ul><h3 id="industry--talent">Industry &amp; Talent</h3><ul><li>First Chinese frontier-AI-lab S-1-equivalent filing on Hong Kong Stock Exchange — most defensibly Moonshot or Zhipu<em>(Q4 2026, medium)</em></li><li>Qwen + DeepSeek + GLM combined revenue (estimated, leaked, or proxied via cloud-segment reporting) exits 2026 at $15–25B annual<em>(Dec 2026, medium)</em></li><li>WAIC humanoid robotics commercialization milestone — Unitree, Fourier, or UBTECH announces first commercial deployment at scale<em>(Jul 2026, medium)</em></li></ul><hr><h2 id="2027">2027</h2><h3 id="models--api-1">Models / API</h3><ul><li>Coordinated post-WAIC release wave: Qwen 5, GLM-7, DeepSeek V7 / R5, Kimi K4 ship within a 72-hour window at WAIC 2027<em>(Jul 21–23, 2027, high)</em></li><li><strong>Open-weight Chinese frontier reaches actual parity with current Western closed-source frontier by H2 2027</strong> — Qwen 5 / DeepSeek V7 / Kimi K4 reach GPT-6-equivalent capability<em>(H2 2027, medium)</em></li><li>Mythos-class cybersecurity model from at least two Chinese labs by year-end<em>(end of 2027, medium)</em></li><li>Each tier-1 lab ships at least 4 model checkpoints in 2027<em>(2027, high)</em></li></ul><h3 id="compute--chip-sovereignty-1">Compute &amp; Chip Sovereignty</h3><ul><li>Huawei Ascend 960 production launches at WAIC 2027<em>(Jul 2027, high)</em></li><li>Cumulative Ascend shipments cross 2.5M units by end of 2027<em>(end of 2027, medium)</em></li><li><strong>Korean HBM dependency for tier-1 Chinese frontier training reaches zero</strong><em>(end of 2027, medium)</em></li><li>Western chip export-control regime visibly fails to constrain Chinese frontier capability — first major US policy debate about whether to escalate or relax<em>(H2 2027, medium)</em></li><li>Huawei Ascend exported to additional non-Western markets: Saudi Arabia, UAE, Türkiye, Hungary, possibly Serbia<em>(2027, medium)</em></li></ul><h3 id="distribution--consumer-apps-1">Distribution &amp; Consumer Apps</h3><ul><li>Doubao MAU exits 2027 at 400–500M; Kimi at 200–300M<em>(end of 2027, medium)</em></li><li>Combined Chinese consumer AI assistant MAU exits 2027 at 900M–1.1B<em>(end of 2027, medium)</em></li><li>Qwen derivative count crosses 250K on HuggingFace — open-weight Linux of AI is decisively Chinese as Meta&rsquo;s pivot away from open-weight at the frontier completes<em>(end of 2027, high)</em></li></ul><h3 id="state-coordination--policy-1">State Coordination &amp; Policy</h3><ul><li><strong>WAIC 2027: formal national champion structure announcement</strong> consolidating 4–5 mid-tier labs into 2 large state-aligned entities while preserving 2–3 independent privately-held tier-1 players (DeepSeek, Moonshot, possibly one other)<em>(Jul 22–24, 2027, medium)</em></li><li>Joint compute pool established under the Coordination Initiative — 3–5GW combined capacity by year-end<em>(end of 2027, medium)</em></li><li>State-curated training-data initiative launches — all coordinating Chinese labs use a common base dataset<em>(2027, medium)</em></li><li>Global AI Cooperation Organization membership reaches 35–45 member countries by end of 2027<em>(end of 2027, medium)</em></li></ul><h3 id="belt-and-road--non-oecd-distribution-1">Belt and Road / Non-OECD Distribution</h3><ul><li>AI Belt and Road deployments expand to 30–45 partner countries by end of 2027<em>(end of 2027, high)</em></li><li>China Development Bank explicitly carves out an &ldquo;AI infrastructure&rdquo; reporting line, channeling $30–60B/year specifically into Chinese AI deployments abroad<em>(2027, medium)</em></li><li><strong>Saudi Arabia formally announces a Huawei-anchored sovereign AI compute program at the 1–3GW scale</strong> — parallel to UAE&rsquo;s Stargate alignment, splitting the Middle East AI market<em>(H2 2027, medium)</em></li></ul><h3 id="geopolitics--bifurcation">Geopolitics &amp; Bifurcation</h3><ul><li><strong>USG bans Chinese-trained inference services for federal and critical-infrastructure customers</strong> — trigger most defensibly a major safety incident attributed to a Chinese model deployed in US-allied infrastructure, OR a security incident attributed to Chinese-built chips<em>(H2 2027, medium)</em></li><li>Reciprocal Chinese restrictions cut Chinese frontier labs&rsquo; US/allied-bloc revenue to near-zero<em>(H2 2027, high)</em></li><li>The bifurcation thesis crystallizes: Western bloc (OpenAI / Anthropic / Google / Meta) on one side, Chinese frontier on the other, both growing on parallel tracks<em>(end of 2027, medium)</em></li></ul><h3 id="industry--talent-1">Industry &amp; Talent</h3><ul><li>First Chinese AI lab IPO closes on Hong Kong Stock Exchange — most defensibly Moonshot, Zhipu, or DeepSeek<em>(Q2 or Q3 2027, medium)</em></li><li><strong>3–4 Chinese frontier lab IPOs by end of 2027</strong> — combined market cap of listed Chinese frontier labs reaches $200–400B<em>(end of 2027, medium)</em></li><li>Net flow of Chinese AI researchers from Western labs back to China accelerates — Western labs&rsquo; Chinese-researcher headcount shrinks 15–25% across 2026–2027<em>(end of 2027, medium)</em></li></ul><hr><h2 id="2028-year-level">2028 (year-level)</h2><h3 id="models--frontier">Models / Frontier</h3><ul><li>Chinese open-weight frontier reaches near-parity with current Western closed-source frontier; lag closes to 0–6 months by end of 2028<em>(2028, medium)</em></li><li>Each tier-1 lab ships 4–6 model checkpoints in 2028<em>(2028, medium)</em></li><li><strong>Open-weight Linux of AI is decisively Chinese</strong> — Qwen + DeepSeek + GLM open-weight derivative count crosses 500K on HuggingFace by end of 2028<em>(end of 2028, high)</em></li><li>Two state-aligned national champion entities (formed in 2027 consolidation) ship coordinated frontier model releases<em>(2028, medium)</em></li></ul><h3 id="compute--chip-sovereignty-2">Compute &amp; Chip Sovereignty</h3><ul><li>Total compute capacity in China exits 2028 at 8–12GW equivalent — Huawei Ascend 960 + 970 generations dominate; Nvidia footprint declines to &lt;20% of Chinese frontier compute<em>(end of 2028, medium)</em></li><li>2028 cumulative Ascend shipments: 8–12M units across 950PR / 960 / 970 generations<em>(end of 2028, medium)</em></li><li>Huawei Ascend captures 8–15% of global AI silicon shipments by unit count, concentrated in Chinese-aligned + non-OECD markets<em>(end of 2028, medium)</em></li><li>4 ZettaFLOPS FP4 cluster-level capability demonstrated at WAIC 2028<em>(Jul 2028, medium)</em></li><li>Chinese silicon supply chain end-to-end domestic by end of 2028 — SMIC fabrication, Huawei in-house HBM, CXMT external HBM3, no critical foreign dependency<em>(end of 2028, high)</em></li></ul><h3 id="distribution--consumer-apps-2">Distribution &amp; Consumer Apps</h3><ul><li>Combined Chinese consumer AI assistant MAU exits 2028 at 1.3–1.7B — comparable to Meta AI&rsquo;s MAU but distributed across multiple apps<em>(end of 2028, medium)</em></li><li>Chinese frontier captures 25–35% of global AI inference market by volume; revenue share is 12–18% (lower because pricing is structurally lower)<em>(end of 2028, medium)</em></li><li>Open-weight ecosystem (Chinese-led + Llama legacy) serves 60–75% of global commodity AI inference workload by volume — collapses pricing power for Western closed-source labs at every workload that doesn&rsquo;t strictly require the absolute frontier<em>(end of 2028, medium)</em></li><li>Commodity AI inference pricing exits 2028 at &lt;$0.50/M tokens — 20–50× lower than current Western closed-source API pricing<em>(end of 2028, medium)</em></li></ul><h3 id="state-coordination--policy-2">State Coordination &amp; Policy</h3><ul><li>Coordination Initiative graduates from soft framework to enforceable industrial policy — joint compute pool reaches 5–8GW, joint training-data initiative produces state-curated dataset all coordinating labs use, joint export coordination for Belt and Road<em>(end of 2028, medium)</em></li><li>2 national champion entities + 2–3 independent tier-1 labs is the stable structural shape<em>(end of 2028, medium)</em></li></ul><h3 id="belt-and-road--non-oecd-distribution-2">Belt and Road / Non-OECD Distribution</h3><ul><li><strong>AI Belt and Road deployments reach 50–70 partner countries by end of 2028</strong><em>(end of 2028, medium)</em></li><li>Chinese AI captures 70–85% share of non-OECD national-infrastructure / strategic-tier deployments<em>(end of 2028, medium)</em></li><li>Combined Sino-Meta share of all non-OECD AI deployment is 85–90% — but the<em>strategic</em> tier (government, defense-adjacent, critical infrastructure) is essentially all Chinese; Western frontier labs are &lt;5% of non-OECD strategic-tier<em>(end of 2028, medium)</em></li><li>Chinese open-weight models become the substrate for sanctioned-region AI deployments — Iran, North Korea, Russia, Cuba, Venezuela run essentially all Chinese open-weight derivatives<em>(end of 2028, medium)</em></li></ul><h3 id="geopolitics--bifurcation-1">Geopolitics &amp; Bifurcation</h3><ul><li><strong>The bifurcation is full</strong> — Western lab API services formally unavailable in China, Chinese lab API services formally unavailable in US + EU + key allies<em>(end of 2028, high)</em></li><li>Both blocs grow on parallel tracks but have zero overlap; combined Chinese frontier + cloud-AI revenue exits 2028 at $180–250B annual<em>(end of 2028, medium)</em></li><li>Global AI Cooperation Organization reaches 50+ member countries — including Saudi Arabia, UAE (despite UAE&rsquo;s parallel Stargate alignment), Brazil, Indonesia, Nigeria, South Africa<em>(end of 2028, medium)</em></li><li>GACO publishes its own AI safety / governance framework competing with the Western federal-AI-law framework — global AI governance is structurally bipolar by end of 2028<em>(end of 2028, medium)</em></li><li>Censorship / alignment requirements differentiate Chinese models from Western at the application layer; in non-OECD markets, &ldquo;Chinese-aligned content controls&rdquo; become a<em>selling point</em> — government customers actively prefer state-controllable AI over Western &ldquo;permissive&rdquo; models<em>(end of 2028, medium)</em></li></ul><h3 id="industry--talent-2">Industry &amp; Talent</h3><ul><li>Combined market cap of listed Chinese frontier labs reaches $500B–1T by end of 2028<em>(end of 2028, medium)</em></li><li>DeepSeek alone exits 2028 at $250–400B market cap<em>(end of 2028, low)</em></li><li>Net flow of Chinese AI researchers from Western labs back to China continues — Western labs&rsquo; Chinese-researcher headcount shrinks 35–50% across 2026–2028<em>(end of 2028, medium)</em></li><li>Tier-1 Chinese lab combined revenue exits 2028: Alibaba Cloud AI segment $40–55B, ByteDance Doubao $25–35B, DeepSeek $12–20B, Moonshot $10–15B, Zhipu $7–12B, plus 2–3 national champions at $20–35B combined<em>(end of 2028, medium)</em></li></ul><hr><h2 id="what-would-break-the-trajectory">What Would Break the Trajectory</h2><p>These predictions hold only if the next two and a half years don&rsquo;t contain a discontinuity. Ranked by probability:</p><ol><li>A serious safety incident with a Chinese frontier model deployed at non-OECD scale — given the distribution surface (1.3B+ consumer MAU, 50+ Belt and Road countries), an incident here lands harder than at any other lab cluster.</li><li>US export-control regime escalation that goes beyond chips — restrictions on Western AI talent collaboration with Chinese institutions, or on Chinese AI services running on Western cloud platforms anywhere globally.</li><li>Beijing reversing the soft-consolidation framework into hard SOE consolidation that suppresses the independent tier-1 labs (DeepSeek, Moonshot) — the ecosystem dynamism that drives the 2027 parity prediction depends on competitive pressure that mandatory consolidation could remove.</li><li>A Huawei Ascend execution stumble — manufacturing yield issues at SMIC, in-house HBM scaling problems, or a major chip security incident that erodes export confidence.</li><li>A trade-war escalation that disrupts the rare-earth / critical-mineral supply chain enough to constrain US-side chip production simultaneously, neutralizing the asymmetry the cautious frame assumes.</li><li>Belt and Road financing pullback — a Chinese economic crisis, real-estate sector contagion, or sovereign debt event that forces CDB / Exim to reduce AI infrastructure export financing.</li><li>Saudi Arabia or UAE breaking the bifurcation thesis by formally splitting their compute footprint between Chinese and Western providers rather than aligning to one.</li><li>Internal Chinese regulatory tightening — CAC content review becoming so restrictive that Chinese models become non-competitive even at home, allowing Western competitors to enter via gray-market routes.</li></ol><p>The honest sentence: absent a discontinuity, the Chinese frontier ends 2028 as a parallel ecosystem to the Western frontier, not a lagging one. The interesting question is no longer &ldquo;is China catching up&rdquo; — it&rsquo;s whether the bifurcation hardens into permanent two-bloc separation or whether some equilibrium with limited cross-bloc commerce eventually emerges. The cautious frame assumes hardened separation through 2028; the aggressive frame assumes the same with deeper Chinese penetration of non-OECD markets.</p><hr><h2 id="whats-different-about-the-chinese-frontier">What&rsquo;s Different About the Chinese Frontier</h2><p>Seven observations that distinguish the Chinese frontier from the Western labs covered in this series:</p><ol><li><p><strong>Ecosystem, not single-lab trajectory.</strong> Anthropic, OpenAI, Google DeepMind, and Meta are predicted as individual labs with internal cadence. The Chinese frontier is 5–8 tier-1 labs operating inside a state-coordinated framework. Every prediction is &ldquo;the Chinese frontier&rdquo; rather than &ldquo;DeepSeek does X&rdquo; — and after the 2027 SOE consolidation announcement, the structure becomes 2 state-aligned national champions plus 2–3 independent tier-1 labs. This shape has no Western analog.</p></li><li><p><strong>State coordination is the structural constant.</strong> The Coordination Initiative announced at WAIC 2026 graduates to enforceable industrial policy by 2028. Joint compute pool, state-curated training-data initiative, joint Belt and Road export coordination, MIIT model approval, CAC content review — every dimension of the Chinese frontier operates inside a policy framework that has no Western counterpart. Anthropic&rsquo;s Long-Term Benefit Trust is a corporate governance form; the Chinese Coordination Initiative is industrial policy.</p></li><li><p><strong>Chip sovereignty is on a faster timeline than the cautious frame allowed.</strong> Huawei in-house HBM in the Ascend 950PR (March 2026) plus CXMT external HBM3 ramp means Korean HBM dependency for tier-1 Chinese frontier training reaches zero by end of 2027 — twelve months earlier than originally framed. By end of 2028, Chinese silicon supply chain is end-to-end domestic, Huawei Ascend captures 8–15% of global AI silicon shipments by unit count, and the Western export-control regime stops being a meaningful constraint on Chinese frontier capability.</p></li><li><p><strong>Open-weight dominance is decisive by 2028.</strong> With Meta&rsquo;s pivot away from open-weight at the frontier (per the Meta post), the open-weight Linux of AI is structurally Chinese — Qwen + DeepSeek + GLM combined derivative count crosses 500K on HuggingFace by end of 2028. The &ldquo;Linux of AI&rdquo; framing Zuckerberg coined in 2024–2025 fully transfers to Chinese labs. Open-weight serves 60–75% of global commodity AI inference workload by volume and collapses pricing power for Western closed-source labs at every workload that doesn&rsquo;t strictly require the absolute frontier.</p></li><li><p><strong>Belt and Road as state-backed distribution mechanism.</strong> No Western lab has a state-aligned distribution channel of comparable scope. Chinese AI infrastructure reaches 50–70 partner countries by end of 2028, financed via existing CDB / Exim / Silk Road Fund mechanisms (the financing engine for $1.4T in cumulative BRI engagement is already in place). Combined with Meta&rsquo;s parallel non-OECD distribution via WhatsApp, the global non-OECD AI market becomes a Sino-Meta condominium — but the strategic tier (government, defense-adjacent, critical infrastructure) is essentially all Chinese.</p></li><li><p><strong>Censorship / alignment as competitive advantage in non-Western markets.</strong> What Western analysis treats as a structural constraint becomes a selling point in Belt and Road deployments. Government customers in non-OECD countries actively prefer state-controllable AI over Western &ldquo;permissive&rdquo; models. The &ldquo;AI sovereignty&rdquo; framing — your country, your content rules — becomes the dominant non-OECD procurement framework, and Chinese labs deliver it natively. By 2028, Chinese-aligned content controls are framed as a feature, not a bug.</p></li><li><p><strong>The bifurcation thesis is the macro story.</strong> The OpenAI / Anthropic / Meta posts all converged on bifurcation by 2028. From the Chinese-frontier perspective, this is<em>the defining feature</em> of the trajectory, not a side prediction. Chinese labs are structurally barred from the US-allied bloc; Western labs are structurally barred from the Chinese-aligned bloc; both blocs grow on parallel tracks and have zero overlap. By end of 2028, &ldquo;Western AI market&rdquo; and &ldquo;Chinese AI market&rdquo; are reported as separate categories rather than a single global market with leaders and followers — and the framing &ldquo;China is behind&rdquo; is obsolete by mid-2027.</p></li></ol><hr><h2 id="closing-the-series">Closing the Series</h2><p>This concludes the AI predictions series — five posts cataloguing what I expect to happen at Anthropic, OpenAI, Google DeepMind, Meta, and across the Chinese frontier through end of 2028. The predictions interlock: OpenAI&rsquo;s 2027–2028 revenue trajectory depends partly on whether Chinese open-weight collapses pricing at the volume tier; Anthropic&rsquo;s regulatory moat depends partly on the bifurcation thesis crystallizing as expected; Meta&rsquo;s pivot away from open-weight at the frontier is the mechanism that hands the open-weight Linux of AI to Chinese labs decisively; the Chinese Coordination Initiative shapes whether the bifurcation hardens or remains negotiable.</p><p>I&rsquo;ll come back to all five posts on a yearly cadence and check what landed, what didn&rsquo;t, and what the reasoning errors were. The point of writing predictions down is that you can grade them later — the value is in the structured ledger, not in any single forecast.</p><p>Sources for the baseline data in this post:<a href="https://benchlm.ai/best/chinese-models">Best Chinese AI Models 2026 (BenchLM)</a>,<a href="https://fortune.com/2026/04/24/deepseek-v4-ai-model-price-performance-china-open-source/">DeepSeek V4 unveiled (Fortune)</a>,<a href="https://www.technologyreview.com/2026/04/21/1135658/china-open-source-models-ai-artificial-intelligence/">China&rsquo;s open-source bet (MIT Technology Review)</a>,<a href="https://www.bloomberg.com/news/articles/2026-04-27/why-china-s-deepseek-qwen-and-moonshot-are-a-worry-for-us-ai-rivals">Why China&rsquo;s DeepSeek/Qwen/Moonshot worry US AI rivals (Bloomberg)</a>,<a href="https://tech-insider.org/huawei-ascend-950pr-ai-chip-nvidia-china-2026/">Huawei Ascend 950PR launch (Tech-Insider)</a>,<a href="https://newsletter.semianalysis.com/p/huawei-ascend-production-ramp">Huawei Ascend production ramp / HBM bottleneck (SemiAnalysis)</a>,<a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/huawei-ascend-npu-roadmap-examined-company-targets-4-zettaflops-fp4-performance-by-2028-amid-manufacturing-constraints">Huawei Ascend roadmap 4 ZettaFLOPS by 2028 (Tom&rsquo;s Hardware)</a>,<a href="https://www.digitimes.com/news/a20250919PD201/huawei-ascend-hbm-2026-ai-chip.html">Huawei Ascend in-house HBM (DigiTimes)</a>,<a href="https://www.igorslab.de/en/cxmt-shifts-20-percent-of-dram-capacity-to-hbm3-chinas-ai-strategy-gets-a-memory-upgrade/">CXMT shifts 20% of DRAM to HBM3 (Igor&rsquo;s Lab)</a>,<a href="https://www.trendforce.com/news/2025/12/26/news-huawei-reportedly-plans-2026-ascend-950-sales-in-south-korea-targeting-cluster-level-deployments/">Huawei Ascend 950 sales in South Korea (TrendForce)</a>,<a href="https://www.aiexpertmagazine.com/world-artificial-intelligence-conference-waic-2026-everything-you-need-to-know/">WAIC 2026 Shanghai details</a>,<a href="https://www.cnn.com/2025/07/28/tech/china-global-ai-cooperation-organization-waic-hnk-spc">WAIC: China pitches global AI governance (CNN)</a>,<a href="https://greenfdc.org/china-belt-and-road-initiative-bri-investment-report-2025/">BRI investment report 2025 (Green Finance &amp; Development Center)</a>,<a href="https://www.intelligentliving.co/china-domestic-chip-ai-belt-road-2028/">China&rsquo;s domestic chip boom + AI Belt and Road 2028 (Intelligent Living)</a>,<a href="https://www.cnbc.com/2026/01/28/chinese-tech-companies-accelerate-ai-model-rollouts-us-rivals-deepseek-moonshot-kimi.html">One year after DeepSeek (CNBC)</a>,<a href="https://www.scmp.com/economy/global-economy/article/3353180/chinas-ai-ascent-leaves-trump-stark-choice-escalate-or-relax-chip-controls">China&rsquo;s AI ascent (SCMP)</a>.</p>
]]></content:encoded></item><item><title>The Meta AI Trajectory</title><link>https://mtclinton.com/posts/the-meta-ai-trajectory/</link><pubDate>Wed, 13 May 2026 11:30:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-meta-ai-trajectory/</guid><category>ai</category><description>A categorized set of predictions about Meta's AI trajectory through the end of 2028.</description><content:encoded>&lt;![CDATA[<p>This is the fourth post in a series cataloguing predictions about the major AI labs through the end of 2028. The series also covers<a href="/posts/the-anthropic-trajectory/">Anthropic</a>,<a href="/posts/the-openai-trajectory/">OpenAI</a>, and<a href="/posts/the-google-deepmind-trajectory/">Google DeepMind</a>. The remaining post will cover the Chinese open-weight frontier on the same template.</p><p>Where Meta stands as of mid-May 2026, for context:</p><ul><li>Annualized revenue is roughly $200B (2025 full year), with Q1 2026 revenue around $46–48B. CapEx for 2026 is committed at $115–135B — concrete and disclosed, not aspirational.</li><li>Meta AI has<strong>1.2B monthly active users</strong> across Meta&rsquo;s family of apps, making it already the largest AI assistant in the world by MAU (ChatGPT is at ~900M WAU). Meta AI sits inside WhatsApp (3.3B users), Instagram (2B), Facebook (3.07B), and Messenger (~1B).</li><li><strong>Muse Spark</strong> shipped April 8, 2026 — Meta&rsquo;s first fully closed-source AI model, built over nine months under Alexandr Wang at the new Meta Superintelligence Labs (MSL). Originally codenamed Avocado.</li><li>The closed-source pivot was reportedly partly in response to US policymaker pressure on AI export controls and partly competitive (capturing API revenue that the open-weight strategy couldn&rsquo;t). Future Muse models will continue under MSL with no binding commitment to open-weight release.</li><li><strong>Llama 4 Scout and Maverick</strong> remain available as open-weight models (multimodal, MoE architecture), but<strong>active development on the Llama frontier has effectively stopped.</strong> All frontier development is now on the Muse track.</li><li><strong>AMD deal:</strong> $100B / 6GW multi-year strategic partnership announced Feb 24, 2026. First gigawatt of custom AMD MI450 + EPYC Venice CPUs deploys H2 2026; remainder rolls out through 2031. Includes a performance-based warrant for up to 160M AMD shares (~10% of AMD), vesting as shipment milestones hit. By 2031 Meta becomes one of AMD&rsquo;s largest shareholders.</li><li><strong>Nvidia deal:</strong> Signed seven days earlier (Feb 17, 2026). Covers &ldquo;millions&rdquo; of Blackwell + Rubin GPUs, plus the first large-scale standalone Grace CPU deployment (Meta is restructuring its entire data center compute base around Arm-based silicon). Vera CPUs coming in 2027.</li><li><strong>MTIA</strong> (Meta Training and Inference Accelerator) — custom silicon already deployed at scale for inference workloads, scaling up.</li><li><strong>May 20, 2026:</strong> 8,000-employee layoff (~10% of workforce) executes, reorganizing teams into AI-focused &ldquo;pods&rdquo; under MSL. Driven by capital reallocation toward AI infrastructure.</li><li><strong>Scale AI / Alexandr Wang acquisition:</strong> $14.3B deal in June 2025 brought Wang in as Meta&rsquo;s first-ever Chief AI Officer, leading MSL.</li><li><strong>Connect 2026</strong> is scheduled for September 23–24 at Menlo Park — the centerpiece event for Meta&rsquo;s fall product announcements.</li><li><strong>Reality Labs</strong> continues to operate at a $5B+ per-quarter loss, on track for $18–22B in operating losses for full-year 2026. Hypernova smart glasses targeted for Q4 2026 holiday launch; Orion AR glasses in developer preview only through 2026.</li></ul><p>The predictions below are anchored on that baseline. Each has a target time window and a confidence level reflecting how willing I am to be wrong publicly about it. Meta is shaped differently from the other labs in this series — public-company scale, conglomerate revenue, an existing distribution moat that no AI-native lab can match, and a recently-reversed open-weight strategy — so the prediction categories are different.</p><hr><h2 id="2026-balance-of-year">2026 (Balance of Year)</h2><h3 id="models--api">Models / API</h3><ul><li>Muse Spark API access opens to enterprise customers in limited preview<em>(Q3 2026, medium)</em></li><li>Llama 4.5 point releases continue for open-weight community, no Llama 5<em>(2026, high)</em></li><li>Open-weight variant of Muse Spark released — partial follow-through on the &ldquo;future open-weight&rdquo; commitment, smaller variants only<em>(Q4 2026, medium)</em></li><li>Muse Spark 2 / Muse 2 frontier announcement at Connect<em>(Sep 23–24, 2026, high)</em></li></ul><h3 id="compute--silicon">Compute &amp; Silicon</h3><ul><li>First gigawatt of AMD MI450 deployment online<em>(H2 2026, high)</em></li><li>First standalone Grace CPU deployment online<em>(H2 2026, high)</em></li><li>MTIA inference share crosses 25% of Meta AI inference workload<em>(end of 2026, medium)</em></li><li>Hyperion data center next-phase capacity disclosed<em>(Q4 2026, medium)</em></li><li>First public benchmarking of Meta-custom silicon vs Nvidia / AMD reference design<em>(end of 2026, low)</em></li></ul><h3 id="distribution--meta-ai">Distribution &amp; Meta AI</h3><ul><li>Meta AI MAU crosses 1.8B by year-end<em>(Dec 2026, high)</em></li><li>WhatsApp Business AI agent platform opens to broad developer preview<em>(Q3 2026, high)</em></li><li>Meta AI v2 agentic capabilities ship across WhatsApp, Instagram, Messenger<em>(Connect 2026, high)</em></li><li>AI ad-creation tools update — generative ad creative becomes a Meta-owned product surface<em>(Connect 2026, high)</em></li><li>Threads continues to gain ground against X — by year-end Threads is at ~80% of X&rsquo;s MAU<em>(end of 2026, medium)</em></li></ul><h3 id="reality-labs--hardware">Reality Labs &amp; Hardware</h3><ul><li>Hypernova smart glasses ship in late October or November at $800–1,500 price point<em>(Q4 2026, high)</em></li><li>Hypernova holiday sales: 800K–1.5M units<em>(Q4 2026, medium)</em></li><li>Orion AR glasses developer preview shipments confirmed at Connect<em>(Sep 2026, high)</em></li><li>Quest 4 or Quest Pro 2 announcement at Connect<em>(Sep 2026, medium)</em></li><li>Reality Labs full-year operating loss: $18–22B<em>(Dec 2026, medium)</em></li></ul><h3 id="business--finance">Business &amp; Finance</h3><ul><li>Q2 2026 revenue $48–51B; Q3 $52–55B; Q4 $58–62B<em>(2026, medium)</em></li><li>Full-year 2026 annual revenue $220–235B<em>(Dec 2026, medium)</em></li><li>$115–135B CapEx for 2026 executed as committed<em>(Dec 2026, high)</em></li><li>AI ad-revenue contribution disclosed as a separate metric for the first time<em>(Q3 2026 earnings, medium)</em></li><li>Stock ends 2026 down or flat year-over-year; P/E compresses to 18–22× as Wall Street prices in CapEx anxiety<em>(Dec 2026, medium)</em></li></ul><h3 id="workforce">Workforce</h3><ul><li>8,000-employee layoff executes May 20; further restructuring announced for H2<em>(May 20, 2026, high)</em></li><li>MSL &ldquo;AI pod&rdquo; reorganization completes; FAIR&rsquo;s footprint visibly reduced<em>(H2 2026, high)</em></li><li>High-profile talent acquisitions continue — researchers poached from Anthropic, OpenAI, Google DeepMind with $50–100M+ packages<em>(2026, high)</em></li></ul><h3 id="geopolitics--regulation">Geopolitics &amp; Regulation</h3><ul><li>EU AI Act compliance milestone — Meta&rsquo;s frontier model classification under the Act becomes a public disclosure<em>(Q4 2026, medium)</em></li><li>First major EU enforcement action against Meta AI (DMA / AI Act overlap framing) — investigation opened, not yet a fine<em>(Q4 2026, medium)</em></li><li>First muted federal positioning — exploration of classified-network clearance, but no contract<em>(2026, medium)</em></li></ul><h3 id="industry--research">Industry &amp; Research</h3><ul><li>FAIR publishes a high-profile world-model or video-prediction paper from Yann LeCun&rsquo;s group<em>(2026, high)</em></li><li>Muse Spark internal benchmarks disclosed at Connect, framed as approaching GPT-5.6 / Claude 4.7 / Gemini 3.x parity on core capability tasks<em>(Sep 2026, medium)</em></li></ul><hr><h2 id="2027">2027</h2><h3 id="models--api-1">Models / API</h3><ul><li>Muse Spark API enters general availability with enterprise tier pricing<em>(Q1 2027, high)</em></li><li>Muse Spark 3 / Muse 3 announced at Connect 2027<em>(Sep 22–23, 2027, high)</em></li><li>Meta API revenue line emerges — $5–8B run-rate by end of 2027, taking share from OpenAI / Anthropic at the frontier<em>(end of 2027, medium)</em></li><li>Open-weight Muse 2 derivative variants released for smaller-tier deployments<em>(2027, medium)</em></li><li>Llama community fork continues — Mistral, DeepSeek, Qwen, and others extend Llama 4 derivatives, Meta no longer the steward<em>(2027, high)</em></li></ul><h3 id="compute--silicon-1">Compute &amp; Silicon</h3><ul><li>AMD MI450 cumulative deployment hits 2–3GW<em>(end of 2027, medium)</em></li><li>MTIA inference share crosses 45–55% of Meta AI inference workload<em>(end of 2027, medium)</em></li><li>Nvidia Vera CPUs enter large-scale deployment<em>(2027, high)</em></li><li>AMD warrant first tranche vests; Meta becomes one of AMD&rsquo;s top 10 shareholders<em>(2027, high)</em></li><li>MTIA-based inference offered to first external customers in private preview<em>(Q4 2027, medium)</em></li></ul><h3 id="distribution--meta-ai-1">Distribution &amp; Meta AI</h3><ul><li>Meta AI MAU crosses 3.0–3.5B<em>(end of 2027, high)</em></li><li>Meta AI passes Google Search in monthly query volume on mobile (within the messaging-app surface)<em>(end of 2027, medium)</em></li><li>WhatsApp Business AI agents reach 1M+ deployed agents<em>(2027, high)</em></li><li>Threads passes X on monthly active users<em>(end of 2027, medium)</em></li><li>AI-generated ad creative drives 15–25% of total ad creative produced on Meta platforms<em>(end of 2027, medium)</em></li></ul><h3 id="reality-labs--hardware-1">Reality Labs &amp; Hardware</h3><ul><li>Hypernova 2 launched at Connect 2027 — $600–1,200 price point, refined design<em>(Sep 2027, high)</em></li><li>Hypernova installed base reaches 5M cumulative<em>(end of 2027, medium)</em></li><li>Orion AR glasses consumer launch officially confirmed for H2 2028<em>(Sep 2027, high)</em></li><li>Reality Labs operating losses peak — full-year 2027 loss $22–25B<em>(end of 2027, medium)</em></li></ul><h3 id="business--finance-1">Business &amp; Finance</h3><ul><li>Q1 revenue $54–58B; Q2 $58–62B; Q3 $62–67B<em>(2027, medium)</em></li><li>Full-year 2027 annual revenue $245–270B<em>(Dec 2027, medium)</em></li><li>2027 CapEx committed at $135–160B<em>(2027, medium)</em></li><li>AI ad-revenue contribution disclosed at 15–22% of total ad revenue<em>(end of 2027, medium)</em></li><li>Stock recovers as AI revenue acceleration becomes the dominant narrative; P/E expands back to 22–26×<em>(end of 2027, medium)</em></li></ul><h3 id="federal--defense">Federal &amp; Defense</h3><ul><li>First major Pentagon contract closes in the $300–500M range — late 2027<em>(Q4 2027, medium)</em></li><li>Meta acquires a defense-cleared AI / engineering company to bridge the classified-network gap<em>(2027, medium)</em></li><li>Federal positioning aligns increasingly with US AI export-control posture — the closed-source pivot becomes a credentialing asset<em>(2027, high)</em></li></ul><h3 id="industry--research-1">Industry &amp; Research</h3><ul><li>First major EU AI Act fine imposed — $1–3B, likely framed around DMA-AI Act overlap<em>(2027, medium)</em></li><li>Meta restructures EU operations to manage the regulatory burden<em>(2027, medium)</em></li><li>A meaningful Llama 4 fork from Mistral or DeepSeek reaches frontier-tier parity with Muse Spark 2 — open-weight community continues without Meta<em>(2027, low)</em></li></ul><hr><h2 id="2028-year-level">2028 (year-level)</h2><h3 id="models--frontier">Models / Frontier</h3><ul><li>Muse 4 / Muse Spark 4 family ships<em>(H1 2028, high)</em></li><li>Muse 5 announcement<em>(end of 2028, medium)</em></li><li>Meta is firmly in the closed-source frontier-API competition; Muse API revenue exits 2028 at $10–18B run-rate<em>(end of 2028, medium)</em></li><li>Open-weight frontier is owned by Mistral, DeepSeek, Qwen, or whichever non-Meta lab steps into the gap —<strong>Meta&rsquo;s &ldquo;Linux of AI&rdquo; thesis becomes a legacy thesis</strong><em>(2028, medium)</em></li><li>LeCun&rsquo;s world-model architecture either gets folded into Muse late in 2028 or is structurally deemphasized in favor of MSL&rsquo;s scaling roadmap<em>(2028, medium)</em></li></ul><h3 id="compute--silicon-2">Compute &amp; Silicon</h3><ul><li>Total Meta AI compute capacity exits 2028 at 18–22GW combined across AMD (~3GW from the 6GW commitment), Nvidia (millions of Blackwell + Rubin GPUs, equivalent to 5–8GW), MTIA (60–70% of inference share, equivalent to another 3–5GW of capacity), plus general Hyperion / Grace CPU infrastructure<em>(end of 2028, medium)</em></li><li>MTIA Cloud opens to external customers as a fourth-hyperscaler AI inference offering<em>(2028, medium)</em></li><li>AMD warrant deeper vesting; Meta crosses top-5 AMD shareholder threshold<em>(end of 2028, medium)</em></li><li>Meta&rsquo;s full data center fleet runs on Arm-based silicon (Grace + Vera + Helios), structurally lower performance-per-watt cost base than competitors<em>(end of 2028, medium)</em></li></ul><h3 id="distribution--meta-ai-2">Distribution &amp; Meta AI</h3><ul><li>Meta AI MAU reaches 4.5–5.5B — essentially saturating the family-DAU base when cross-counting across surfaces<em>(end of 2028, medium)</em></li><li>Meta AI is the dominant AI assistant globally by a 2× margin over the second-place competitor<em>(end of 2028, medium)</em></li><li>AI-improved ad targeting + AI-generated ad creative drives<strong>30–40% of total ad revenue</strong> — call it $90–130B incremental revenue per year above the pre-AI baseline<em>(end of 2028, medium)</em></li><li>Meta AI becomes the default AI assistant for consumer apps that don&rsquo;t have resources to integrate frontier APIs themselves (finance apps, dating apps, food delivery, etc.)<em>(end of 2028, low)</em></li><li>Meta AI is the de facto national AI infrastructure for most of South Asia, sub-Saharan Africa, and parts of Latin America — government partnerships formalized for civic services via WhatsApp<em>(end of 2028, low)</em></li></ul><h3 id="reality-labs--hardware-2">Reality Labs &amp; Hardware</h3><ul><li>Orion consumer AR glasses launch in H2 2028 at $1,500–2,500 price point<em>(H2 2028, high)</em></li><li>Orion year-one sales 1–3M units (cautious) to 5–10M units (aggressive); cautious bet 2–4M<em>(2028, medium)</em></li><li>Hypernova cumulative installed base reaches 10–15M<em>(end of 2028, medium)</em></li><li>Hardware revenue exits 2028 at $20–35B annualized — large enough to be a separate reportable segment<em>(end of 2028, medium)</em></li><li><strong>Reality Labs hits operating profitability for full-year 2028</strong> — Hypernova installed base + Orion launch cross the breakeven threshold<em>(end of 2028, medium)</em></li></ul><h3 id="business--finance-2">Business &amp; Finance</h3><ul><li>Full-year 2028 annual revenue $280–330B<em>(Dec 2028, medium)</em></li><li>2028 CapEx exits the peak — $150–180B for 2028, with 2029 telegraphed at flat-to-down<em>(end of 2028, medium)</em></li><li>Market cap exits 2028 at $3–4T — Meta is one of the top-3 US public companies<em>(end of 2028, medium)</em></li><li>P/E multiple expands to 26–30× as the AI revenue acceleration + Reality Labs profitability + MTIA Cloud combination unlocks a multiple re-rating<em>(end of 2028, medium)</em></li><li>Wall Street structurally re-categorizes Meta from &ldquo;social media&rdquo; to &ldquo;AI hyperscaler with consumer hardware&rdquo; — comp set shifts to Apple, Anthropic, OpenAI<em>(end of 2028, medium)</em></li></ul><h3 id="federal--defense-1">Federal &amp; Defense</h3><ul><li>Cumulative US federal / defense contracts reach $1.5–3B by end of 2028<em>(end of 2028, medium)</em></li><li>Meta&rsquo;s defense-cleared subsidiary (built via the 2027 acquisition) operates at meaningful scale<em>(end of 2028, medium)</em></li><li>Meta&rsquo;s geopolitical alignment with US export controls becomes a credentialing asset for state-sensitive procurement<em>(2028, high)</em></li></ul><h3 id="geopolitics">Geopolitics</h3><ul><li>Cumulative EU fines from 2026–2028 reach $5–10B; Meta absorbs as cost of doing business<em>(end of 2028, medium)</em></li><li>China remains a closed market for Meta through 2028<em>(2028, high)</em></li><li>USG bans Chinese-trained inference services for federal / critical-infrastructure customers; Meta positioned favorably as a Western alternative<em>(2028, medium)</em></li><li>Meta&rsquo;s non-OECD distribution moat becomes a US soft-power asset cited in policy contexts<em>(2028, low)</em></li></ul><h3 id="industry--research-2">Industry &amp; Research</h3><ul><li>FAIR&rsquo;s footprint is reduced; Yann LeCun continues academic publishing but the production lab is unambiguously MSL-Muse-Wang<em>(2028, high)</em></li><li>Wang becomes the public face of Meta AI alongside Zuckerberg; the &ldquo;Wang era&rdquo; is the dominant frame<em>(2028, high)</em></li><li>Zuckerberg becomes the Western-AI elder statesman in policy debates — pro-distribution, pro-developer-ecosystem, pro-open-weight-for-smaller-tiers, contrasting with Altman&rsquo;s policy-insider posture and Dario&rsquo;s safety-forward posture<em>(2028, medium)</em></li><li>Threads passes X by 10× on MAU; X is operating at &lt;10% of its 2026 user base<em>(end of 2028, medium)</em></li></ul><hr><h2 id="what-would-break-the-trajectory">What Would Break the Trajectory</h2><p>These predictions hold only if the next two and a half years don&rsquo;t contain a discontinuity. Ranked by probability:</p><ol><li>A serious safety incident with Meta AI inside WhatsApp / Instagram / Messenger — given the distribution surface, an incident here lands harder than at any other AI lab.</li><li>EU regulatory enforcement that goes beyond fines into structural separation — most likely a forced divestiture of WhatsApp&rsquo;s AI integration from the rest of Meta.</li><li>A capability plateau on the Muse track — Muse 3 or Muse 4 fails to deliver the step-change improvements the cadence implicitly promises, leaving Meta visibly behind OpenAI / Anthropic at the frontier.</li><li>The Reality Labs hardware bet fails to scale — Hypernova or Orion ramps below expectations, Reality Labs losses don&rsquo;t peak as projected, the stock recovery narrative breaks.</li><li>A compute supply collapse — Taiwan / TSMC, US energy infrastructure, or AMD / Nvidia execution issues on the multi-year deals.</li><li>The closed-source pivot backfires — developer ecosystem migrates fully to Mistral / DeepSeek / Qwen forks, Llama brand becomes obsolete, Meta loses the &ldquo;Linux of AI&rdquo; narrative without capturing the closed-source API market.</li><li>A serious recession compressing ad spending — Meta&rsquo;s revenue is more cyclical than OpenAI / Anthropic API revenue, and an ad-market downturn hits harder.</li><li>US / China conflict at sufficient intensity to disrupt Pacific operations or chip supply.</li><li>Zuckerberg governance crisis — board pressure, shareholder lawsuit, or executive departures (Wang departing MSL would be the highest-impact single event).</li></ol><p>The honest sentence: absent a discontinuity, Meta ends 2028 as one of the top-3 US public companies by market cap, with the largest AI assistant in the world by user count, the most diversified compute strategy, the only frontier AI lab with consumer hardware at meaningful scale, and a Reality Labs business that has finally crossed into profitability. The interesting question is no longer whether Meta is a serious AI lab — it&rsquo;s whether the Muse-led closed-source frontier strategy can sustain through Muse 5 and Muse 6 against Anthropic and OpenAI without an open-weight escape valve.</p><hr><h2 id="whats-different-about-meta">What&rsquo;s Different About Meta</h2><p>Seven observations that distinguish Meta&rsquo;s trajectory from Anthropic&rsquo;s, OpenAI&rsquo;s, or Google DeepMind&rsquo;s, and which I think the rest of this series will return to:</p><ol><li><p><strong>The distribution moat is unmatched.</strong> Meta AI starts at 1.2B MAU and scales toward 4.5–5.5B by end of 2028 on the back of WhatsApp / Instagram / Facebook / Messenger. No other AI lab has a comparable surface; the crossover with ChatGPT already happened in early 2026. ChatGPT is structurally constrained to people who actively choose to use it. Meta AI is delivered passively into the messaging apps 4B people already use daily. The whole rest of the trajectory compounds on this asymmetry.</p></li><li><p><strong>The Muse / Wang era replaces the LeCun / open-weight era — a structural research-strategy reset.</strong> Meta&rsquo;s pre-2025 AI identity was open-weight Llama plus Yann LeCun&rsquo;s non-LLM research arc. The April 8, 2026 Muse Spark launch ended both. All frontier development is now under Alexandr Wang at MSL; Llama development at the frontier has stopped; the open-weight commitment is non-binding and selective. By end of 2028, the Wang era is the dominant frame for Meta AI and the open-weight &ldquo;Linux of AI&rdquo; framing is a legacy thesis. This is a sharper internal pivot than any of the other AI labs have made.</p></li><li><p><strong>The compute strategy is multi-vendor at unprecedented scale, with an AMD-equity-warrant alignment that no other AI lab has.</strong> Nvidia (millions of Blackwell + Rubin GPUs, first large-scale standalone Grace deployment, Vera CPUs from 2027) plus AMD ($100B / 6GW MI450 commitment, 160M-share warrant making Meta one of AMD&rsquo;s top-5 shareholders by 2031) plus MTIA (custom silicon scaling to 60–70% of inference share by 2028). By end of 2028, Meta&rsquo;s total AI compute capacity is 18–22GW — likely the largest of any AI lab — and the AMD-warrant structure is the closest analog in AI to the OpenAI-Microsoft equity entanglement, with Meta in the customer-investor position.</p></li><li><p><strong>Direct ad-revenue mechanism — and AI compounds it.</strong> Meta is the only frontier AI lab whose business model is advertising, not subscriptions / API / enterprise. AI-improved ad targeting plus generative ad creative drives 30–40% of ad revenue by end of 2028 — call it $90–130B incremental annual revenue above the pre-AI baseline. This is the structural reason Meta&rsquo;s revenue growth re-accelerates in 2027–2028 rather than decelerating, and it&rsquo;s a revenue mechanism no competitor can replicate without becoming an ad company.</p></li><li><p><strong>Reality Labs hardware bet finally reaches consumer scale — and profitability.</strong> Hypernova in Q4 2026, Hypernova 2 in 2027, Orion consumer in H2 2028. Meta is the only AI lab with a serious, scaled, multi-product consumer hardware roadmap by end of 2028 (OpenAI&rsquo;s io device is one product; Apple is not an AI lab). Reality Labs hits operating profitability in full-year 2028 — the decade-long metaverse investment thesis is vindicated in a single year. Structurally the bigger market-cap unlock than the AI revenue line, because it removes the largest single overhang on the stock.</p></li><li><p><strong>MTIA Cloud emerges as a fourth hyperscaler.</strong> By end of 2028, MTIA-based inference is offered to external customers as a paid service. Meta has the silicon roadmap, the AMD equity-aligned chip supply, and the data center scale (Hyperion + AMD Helios + Arm-based Grace CPUs) to compete with AWS / Azure / GCP for AI inference revenue. This is the most-underweighted thread in the Meta story — Meta&rsquo;s compute strategy doesn&rsquo;t end at &ldquo;consume cheap chips&rdquo; but at &ldquo;be the cheapest inference provider on Earth.&rdquo;</p></li><li><p><strong>Public-company quarterly discipline as constraint and information advantage.</strong> Meta is the only AI-frontier lab whose finances are fully disclosed every quarter. This is a constraint (Wall Street pressure on CapEx in 2026 produces the P/E compression to 18–22×), an information moat (Meta can model competitor economics from public proxies but its competitors can&rsquo;t model Meta&rsquo;s), and a credibility advantage in regulated and federal markets (audited financials). Conglomerate scale ($200B+ revenue already in 2025) means AI is incremental to the company, not the whole company — a different calibration shape than every other lab in this series.</p></li></ol><hr><h2 id="whats-next">What&rsquo;s Next</h2><p>The final post in this series covers the Chinese open-weight frontier — DeepSeek, Zhipu, Moonshot, Qwen, and the SOE consolidation question. With Meta&rsquo;s pivot away from open-weight at the frontier, the structural question of who leads open-weight AI globally moves from &ldquo;is it Meta or a Chinese lab&rdquo; to &ldquo;which Chinese lab consolidates the field and how does USG respond.&rdquo; The Meta closed-source pivot makes that next post more interesting, not less — the open-weight ecosystem now visibly belongs to a different bloc.</p><p>Sources for the baseline data in this post:<a href="https://techcrunch.com/2026/04/08/meta-debuts-the-muse-spark-model-in-a-ground-up-overhaul-of-its-ai/">Meta Muse Spark launch (TechCrunch)</a>,<a href="https://www.cnbc.com/2026/04/08/meta-debuts-first-major-ai-model-since-14-billion-deal-to-bring-in-alexandr-wang.html">Meta debuts new AI model (CNBC)</a>,<a href="https://thenewstack.io/meta-abandons-llama-spark/">Meta abandons open-source Llama for Muse Spark (The New Stack)</a>,<a href="https://www.deeplearning.ai/the-batch/with-muse-spark-meta-pivots-away-from-its-open-weights-llama-strategy">Meta pivots away from open-weights Llama (DeepLearning.AI)</a>,<a href="https://www.amd.com/en/newsroom/press-releases/2026-2-24-amd-and-meta-announce-expanded-strategic-partnersh.html">AMD-Meta $100B 6GW deal (AMD)</a>,<a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/amd-meta-100-billion-deal">AMD warrant for 160M shares (Tom&rsquo;s Hardware)</a>,<a href="https://nvidianews.nvidia.com/news/meta-builds-ai-infrastructure-with-nvidia">Meta builds AI infrastructure with Nvidia (Nvidia)</a>,<a href="https://www.cnbc.com/2026/02/17/meta-nvidia-deal-ai-data-center-chips.html">Meta-Nvidia millions of GPUs deal (CNBC)</a>,<a href="https://thenextweb.com/news/meta-layoffs-may-2026-ai-restructuring-thousands">Meta layoffs May 2026 (TheNextWeb)</a>,<a href="https://www.demandsage.com/meta-ai-users/">Meta AI 1.2B MAU stats</a>,<a href="https://www.getpanto.ai/blog/meta-platforms-statistics">Meta family DAU 3.58B</a>,<a href="https://builtin.com/artificial-intelligence/meta-superintelligence-labs">Meta Superintelligence Labs overview (Built In)</a>,<a href="https://www.tomsguide.com/computing/smart-glasses/meta-connect-2026-kicks-off-in-september-date-time-and-mystery-new-smart-glasses-teased">Meta Connect 2026 (Tom&rsquo;s Guide)</a>,<a href="https://ai.meta.com/blog/llama-4-multimodal-intelligence/">Llama 4 multimodal (Meta AI)</a>,<a href="https://mlq.ai/news/meta-readies-nextgeneration-mango-and-avocado-ai-models-for-2026-launch/">Mango and Avocado models for 2026</a>,<a href="https://www.saastr.com/anthropic-just-passed-openai-in-revenue-while-spending-4x-less-to-train-their-models/">Anthropic vs OpenAI revenue crossover (SaaStr)</a>.</p>
]]></content:encoded></item><item><title>The Google DeepMind Trajectory</title><link>https://mtclinton.com/posts/the-google-deepmind-trajectory/</link><pubDate>Wed, 13 May 2026 11:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-google-deepmind-trajectory/</guid><category>ai</category><description>A categorized set of predictions about Google DeepMind's trajectory through the end of 2028.</description><content:encoded>&lt;![CDATA[<p>This is the third post in a series cataloguing predictions about the major AI labs through the end of 2028. The first two posts covered<a href="/posts/the-anthropic-trajectory/">Anthropic</a> and<a href="/posts/the-openai-trajectory/">OpenAI</a>; subsequent posts will cover Meta and the Chinese open-weight frontier on the same template.</p><p>Google DeepMind is the strangest entry in this series because it is not really a startup at all. It is a research division of a $2.5 trillion advertising company, with a cross-subsidy structure no independent AI lab has any chance of replicating, a vertical compute integration no other lab can match, and a distribution surface (Search, YouTube, Workspace, Android, Chrome, Maps, Photos) that reaches more daily users than every other AI lab combined. The predictions below are anchored on what is, at base, a very different kind of trajectory: not the curve of a startup becoming an institution, but the curve of an institution becoming an AI company. They are also more anchored than the prior two posts in the series, because Google&rsquo;s product cadence is metronomic — I/O in May, Made by Google in August, earnings on a fixed quarterly calendar, anniversary model previews in November — so the predictions reduce to a relatively narrow band of variation around an event schedule that is already public.</p><p>Where Google DeepMind stands as of mid-May 2026, for context:</p><ul><li>Gemini 3 Pro and Gemini 3 Deep Think shipped November 18, 2025. Gemini 3.1 Pro shipped February 19, 2026 — 2x reasoning improvement over 3 Pro, #1 on 12 of 18 tracked benchmarks, 1M token context, 65K token output.</li><li>Gemini app: 750M monthly active users (as of April 2026), the fastest-growing AI consumer product.</li><li>Gemini Enterprise: 8M paid seats across 2,800 companies; handles 45% of all enterprise AI queries inside the Fortune 500 firms using Google Workspace.</li><li>AI Overviews: 2B monthly users across Google Search.</li><li>Google Cloud Q1 2026 revenue: $20B (+63% YoY); operating income $6.6B; operating margin expanded from 9.4% to 32.9% year-over-year. Cloud is now 18% of Alphabet&rsquo;s total business.</li><li>Compute: Ironwood (TPU v7) launched April 2026 — 10x performance over TPU v5p, 4x over Trillium; 4,614 FP8 TFLOPS per chip, 192GB HBM3E, 9,216-chip pods. The Anthropic compute deal — 1M+ TPUs deployed through 2026, 1GW dedicated — made Anthropic a Google Cloud anchor customer.</li><li>Robotics: Gemini Robotics + Gemini Robotics-ER (March 2025), Gemini Robotics 1.5 (September 2025), Gemini Robotics ER-1.6 (April 2026). Boston Dynamics is a named partner.</li><li>Science: AlphaFold has 3M+ researchers in 190+ countries; Hassabis and Jumper won the 2024 Nobel Prize in Chemistry. Isomorphic Labs (the DeepMind drug-discovery spinout) has guided to &ldquo;first human dosing by end of 2026.&rdquo;</li><li>Waymo: ~700K rides per week across 11+ US service areas (as of Q1 2026). Mesa, Arizona factory ramping toward a &ldquo;tens of thousands per year&rdquo; target. Tokyo and London mapping ongoing.</li><li>Antigravity (Google&rsquo;s agentic IDE) reached preview in late 2025; positioned against Cursor and Claude Code.</li><li>Aluminium OS / Googlebook: the Android + ChromeOS convergence platform, with OEM partners (Acer, ASUS, Lenovo) committed for late 2026 shipping.</li><li>Alphabet Q1 2026 revenue: +22% YoY. CapEx guidance for 2026 is in the $185–200B range, characterized by management as &ldquo;supply-constrained&rdquo; rather than &ldquo;demand-driven.&rdquo;</li></ul><p>The predictions below are the cautious frame — what should happen if Google continues to execute on its visible cadence and nothing dramatic breaks. Confidence levels reflect how willing I am to be wrong publicly about a particular line.</p><hr><h2 id="2026-balance-of-year">2026 (Balance of Year)</h2><h3 id="models">Models</h3><ul><li>Gemini 3.1 Pro reaches GA across all surfaces (Gemini app, Vertex, AI Studio, NotebookLM, Antigravity) at I/O<em>(May 19–20 2026, high)</em></li><li>Gemini 3.1 Flash launches as the new mid-tier<em>(May 2026, high)</em></li><li>Gemini 3.1 Deep Think opens beyond safety testers to Ultra subscribers<em>(May 2026, high)</em></li><li>A Gemini 3.1 Pro point-release (&ldquo;3.1.1&rdquo; or a quietly upgraded checkpoint) with better long-context retention and lower TTFT<em>(Jul 2026, medium)</em></li><li>Gemini 4.0 Pro preview lands on the November anniversary<em>(Nov 2026, high)</em></li><li>Gemini 4.0 ships with native long-horizon agentic capability as a marketed primary feature, not a preview<em>(Nov 2026, medium)</em></li></ul><h3 id="cloud-business--capex">Cloud, Business &amp; CapEx</h3><ul><li>Q2 2026 earnings (late July) — Cloud growth in the 55–65% YoY band, backlog crosses $500B, CapEx guidance held or raised<em>(Jul 2026, high)</em></li><li>Q3 2026 earnings (late October) — Cloud quarterly revenue $22–24B, growth in the high 50s<em>(Oct 2026, high)</em></li><li>Cloud annualized run-rate $90–95B by year-end<em>(Dec 2026, high)</em></li><li>2027 CapEx guidance pre-announced in the $220–250B range<em>(Dec 2026, medium)</em></li><li>Cloud passes 20% of Alphabet&rsquo;s total revenue<em>(end of 2026, medium)</em></li></ul><h3 id="compute-tpu">Compute (TPU)</h3><ul><li>Ironwood reaches general availability for Google Cloud customers<em>(Q3 2026, high)</em></li><li>TPU 8 (or &ldquo;8t/8i&rdquo;) begins availability to first-tier Vertex partners<em>(Jul 2026, high)</em></li><li>A second hyperscale TPU customer in the Anthropic class closes — most likely an enterprise rather than an AI-lab buyer<em>(end of 2026, medium)</em></li></ul><h3 id="distribution">Distribution</h3><ul><li>Project Astra graduates from &ldquo;experimental&rdquo; to a real product surface — live multimodal assistant in the Gemini app, the Gemini Live tab, and as a primary entry point on Android<em>(May 2026, high)</em></li><li>AI Mode (the chat-style alternative to Search) rolls out internationally to ~80 markets<em>(May–Jun 2026, high)</em></li><li>Android 17 stable ships alongside Pixel 11 in September; Gemini becomes the default assistant surface and Google Assistant is effectively sunsetted in name even if not technically<em>(Sep 2026, high)</em></li><li>Personal Intelligence (browser- and app-context-aware Gemini) expands across Chrome and Workspace<em>(2026, high)</em></li></ul><h3 id="verticals--enterprise">Verticals &amp; Enterprise</h3><ul><li>Workspace AI tier consolidation; new &ldquo;Agentic Workspace&rdquo; SKU for enterprises with cross-app workflows (Docs → Sheets → Gmail → Calendar)<em>(Jun 2026, high)</em></li><li>Gemini for Healthcare, Gemini for Financial Services, and Gemini for Public Sector launch as pre-configured vertical SKUs<em>(Sep 2026, high)</em></li><li>Gemini Enterprise crosses 12M paid seats<em>(end of 2026, medium)</em></li></ul><h3 id="open-weight-gemma">Open-Weight (Gemma)</h3><ul><li>Gemma 4 family fills out — Code-Gemma 4, PaliGemma 4 (vision), MedGemma 4 (medical), Gemma 4 Robotics variant tied to the Boston Dynamics partnership<em>(Jun 2026, high)</em></li><li>Gemma family monthly Hugging Face downloads surpass Llama<em>(end of 2026, medium)</em></li></ul><h3 id="hardware">Hardware</h3><ul><li>Made by Google event (Aug 13 2026, by historical cadence) — Pixel 11, Pixel 11 Pro, Pixel Watch 4, Pixel Buds Pro 3, Pixel Fold 2<em>(Aug 2026, high)</em></li><li>Gemini Nano 3 ships on Pixel 11 and rolls to Samsung Galaxy S24+ and recent Pixels<em>(Aug 2026, high)</em></li><li>Aluminium OS / Googlebook details firm up; first Googlebooks from Acer/ASUS/Lenovo dated for late October to early November<em>(Aug 2026, high)</em></li><li>Android XR glasses get a real launch date (Samsung Galaxy Glasses or equivalent shipping Q4 2026 or early 2027)<em>(I/O May 2026, medium)</em></li><li>First Googlebooks ship and receive their public review cycle<em>(Oct–Nov 2026, medium)</em></li></ul><h3 id="robotics">Robotics</h3><ul><li>Gemini Robotics ER-2.0 ships<em>(Q3 2026, medium)</em></li><li>Boston Dynamics partnership produces a named consumer or commercial pilot with a Gemini-Robotics-powered Atlas demo<em>(Q4 2026, medium)</em></li><li>Hassabis&rsquo;s &ldquo;ChatGPT moment for robotics&rdquo; comes within striking distance but does not actually arrive in 2026<em>(Dec 2026, medium)</em></li></ul><h3 id="science">Science</h3><ul><li>A DeepMind science paper at the AlphaFold tier of public attention — most likely AlphaEvolve producing a concretely useful algorithm or chip-layout result, or an AlphaProteo-successor for antibody design<em>(Q3 2026, medium)</em></li><li>AlphaProof / AlphaEvolve produces a publicly-noticed advance on Mathematics Olympiad–style problems<em>(Jun 2026, medium)</em></li><li>A DeepMind science announcement at CES 2027 (telegraphed late 2026)<em>(Dec 2026, medium)</em></li></ul><h3 id="isomorphic-labs">Isomorphic Labs</h3><ul><li>IND (Investigational New Drug) application filed for first oncology candidate<em>(Sep 2026, high)</em></li><li>First human patient dosed in lead oncology trial<em>(Dec 2026, medium)</em></li><li>A pharma partner (Lilly or Novartis) expands its deal on the next tranche<em>(Q4 2026, medium)</em></li></ul><h3 id="waymo">Waymo</h3><ul><li>Public-rider launch in Washington, D.C. for summer tourism<em>(Jun 2026, high)</em></li><li>Crosses 750K rides per week<em>(Jul 2026, high)</em></li><li>Two additional cities pick up public riding (likely Detroit, Las Vegas, or Nashville)<em>(Sep 2026, high)</em></li><li>Freeway routes available in all current major markets<em>(Sep 2026, high)</em></li><li>Hits 1M rides per week (the explicit company target)<em>(Dec 2026, high)</em></li><li>Tokyo and/or London begins commercial service for residents<em>(Dec 2026, medium)</em></li></ul><h3 id="developer-tools">Developer Tools</h3><ul><li>Antigravity 1.0 GA, deeply integrated with Gemini 3.1 Pro and MCP<em>(May 2026, high)</em></li><li>An Antigravity point-release with multi-repo, long-horizon coding agent features<em>(Q4 2026, medium)</em></li></ul><h3 id="geopolitics--antitrust">Geopolitics &amp; Antitrust</h3><ul><li>Antitrust appellate arguments at the D.C. Circuit — oral arguments late October or November<em>(Q4 2026, high)</em></li><li>No appellate ruling in 2026<em>(Dec 2026, high)</em></li><li>An EU regulatory consent decree is reached around Gemini&rsquo;s Search integration<em>(Q3–Q4 2026, medium)</em></li></ul><hr><h2 id="2027">2027</h2><h3 id="models-1">Models</h3><ul><li>Gemini 4.0 Pro GA across all surfaces<em>(Q1 2027, high)</em></li><li>Gemini 4 Flash and Flash Lite ship in the same window<em>(Q1 2027, high)</em></li><li>Gemini 4 Nano lands on Pixel and partner Android devices<em>(Q1 2027, high)</em></li><li>Gemini 4 Deep Think publishes a model card with a verified IMO-gold result<em>(Q1 2027, medium)</em></li><li>Gemini 4.5 Pro preview at I/O 2027 — 2M+ token context with real retention, faster TTFT, stronger video understanding<em>(May 2027, high)</em></li><li>Gemini 4.5 Pro GA<em>(Q3 2027, high)</em></li><li>Gemini 5 Pro preview at the November anniversary<em>(Nov 2027, high)</em></li><li>Gemini 5 Deep Think rolls out alongside, focused on multi-day autonomous work<em>(Nov 2027, medium)</em></li></ul><h3 id="cloud-business--capex-1">Cloud, Business &amp; CapEx</h3><ul><li>2026 full-year revenue closes at $440–460B<em>(Q4 2026 reported Jan 2027, high)</em></li><li>Cloud annualized run-rate around $95B at start of year<em>(Jan 2027, high)</em></li><li>2027 CapEx confirmed in the $220–260B band<em>(Jan 2027, high)</em></li><li>Cloud Q2 2027 quarterly revenue $28–32B, growth in the 40–50% band<em>(Jul 2027, medium)</em></li><li>Cloud Q3 2027 quarterly revenue $33–38B<em>(Oct 2027, medium)</em></li><li>2028 CapEx telegraphed in the $280–330B band<em>(Oct 2027, medium)</em></li><li>Cloud annualized $130–150B by year-end<em>(Dec 2027, medium)</em></li></ul><h3 id="compute-tpu-1">Compute (TPU)</h3><ul><li>TPU 9 generation announced at Cloud Next 2027 (training-only first, inference variant later)<em>(Apr 2027, high)</em></li><li>TPU 9 inference variant ships<em>(H2 2027, medium)</em></li><li>A third hyperscale TPU pod cluster online; at minimum 5GW total Google AI compute<em>(end of 2027, medium)</em></li></ul><h3 id="distribution-1">Distribution</h3><ul><li>Astra at scale: the multimodal assistant becomes the default Google surface, replacing legacy Assistant entirely<em>(May 2027, high)</em></li><li>A Veo / Imagen / Genie consolidation into a single &ldquo;Google generative media&rdquo; suite, possibly with real-time interactive Genie experiences in YouTube<em>(May 2027, medium)</em></li><li>Android XR glasses retail launch — late Q3 or Q4 2027, US first, $999–1,499<em>(Q3 2027, medium)</em></li><li>Android 18 stable<em>(Sep 2027, high)</em></li><li>Aluminium OS reaches v2; Googlebook generation 2 announced<em>(Sep 2027, medium)</em></li></ul><h3 id="verticals--enterprise-1">Verticals &amp; Enterprise</h3><ul><li>Gemini Enterprise crosses 15M paid seats with full agent suite and agent-to-agent protocols<em>(Apr 2027, medium)</em></li></ul><h3 id="open-weight-gemma-1">Open-Weight (Gemma)</h3><ul><li>Gemma 5 family ships mid-year — Code-Gemma 5, MedGemma 5, an explicit MoE variant tuned for commodity GPUs<em>(Jul 2027, high)</em></li><li>Gemma family Hugging Face downloads overtake Llama on a monthly basis if not already<em>(Jul 2027, medium)</em></li></ul><h3 id="hardware-1">Hardware</h3><ul><li>Made by Google 2027 (August) — Pixel 12 series, Pixel Watch 5, refreshed Buds, possibly Pixel Tablet refresh<em>(Aug 2027, high)</em></li><li>Pixel 12 ships with on-device agentic capability that&rsquo;s noticeably ahead of Apple Intelligence&rsquo;s progress<em>(Aug 2027, high)</em></li><li>iPhone 19 lands; Apple is now visibly behind on AI capability per benchmark<em>(Sep 2027, medium)</em></li></ul><h3 id="robotics-1">Robotics</h3><ul><li>Boston Dynamics / Atlas with Gemini Robotics performs real warehouse pick-and-pack work at a named customer<em>(CES Jan 2027, medium)</em></li><li>A Gemini-on-vehicle integration with a Tier-1 OEM announced (likely non-Waymo: BMW, Honda, or similar)<em>(CES Jan 2027, medium)</em></li></ul><h3 id="science-1">Science</h3><ul><li>A DeepMind science announcement at AlphaFold tier — most plausibly AlphaEvolve producing a verifiable algorithmic improvement to a real industrial workload, or an AlphaProteo-successor antibody design result<em>(Q1 2027, medium)</em></li><li>Genie / Veo unification with clear robotics-simulation utility<em>(end of 2027, medium)</em></li></ul><h3 id="isomorphic-labs-1">Isomorphic Labs</h3><ul><li>Phase 1 readout — first oncology candidate clears safety; early efficacy signal published or hinted at conference<em>(Q3 2027, medium)</em></li><li>A second clinical candidate enters Phase 1<em>(Q3–Q4 2027, medium)</em></li><li>Phase 2 plans announced; pharma partner expands deal — upfront raise from $45M/$37.5M to $100M+ on next tranche<em>(Q4 2027, medium)</em></li><li>First peer-reviewed publication tying clinical results back to model predictions<em>(Dec 2027, low)</em></li></ul><h3 id="waymo-1">Waymo</h3><ul><li>Crosses 1.5M rides per week<em>(Q2 2027, high)</em></li><li>Mesa factory output ramps toward &ldquo;tens of thousands per year&rdquo; target<em>(2027, high)</em></li><li>Tokyo crosses 25K rides per week or London opens to public riders<em>(May 2027, medium)</em></li><li>Crosses 2M rides per week<em>(Jul 2027, medium)</em></li><li>18–22 active US service areas; service hours uniformly 24/7 in mature markets<em>(end of 2027, medium)</em></li><li>NYC and Boston operations begin public riding<em>(Q4 2027, medium)</em></li><li>Waymo annualized revenue passes $5B with positive unit economics in mature markets<em>(Q4 2027, medium)</em></li></ul><h3 id="developer-tools-1">Developer Tools</h3><ul><li>Antigravity 2.0 reaches credible feature parity with Cursor and Claude Code; Google publishes share-of-developer metrics<em>(May 2027, medium)</em></li><li>Heavy emphasis on multi-repo, long-horizon coding agents<em>(2027, high)</em></li></ul><h3 id="geopolitics--antitrust-1">Geopolitics &amp; Antitrust</h3><ul><li>D.C. Circuit ruling in Q2 — most likely upholds the bulk of Mehta&rsquo;s remedies rather than ordering structural divestiture; Sherman Act monopoly finding stands<em>(Q2 2027, medium)</em></li><li>Either side petitions for en banc or cert; the saga does not end here<em>(Q3 2027, medium)</em></li><li>An EU regulatory framework for AI-integrated search exists<em>(2027, medium)</em></li></ul><hr><h2 id="2028">2028</h2><h3 id="models-2">Models</h3><ul><li>Gemini 5 Pro GA, with native multimodal output (interleaved text/image/audio/video) as the default<em>(Q1 2028, high)</em></li><li>Gemini 5 Flash and Nano ship in the same window<em>(Q1 2028, high)</em></li><li>Gemini 5 Deep Think opens to Ultra; model card cites a published proof of a previously open mathematics problem<em>(Q1 2028, medium)</em></li><li>Gemini 5.5 Pro preview at I/O 2028 — multi-week task execution as a marketed feature, not a demo<em>(May 2028, high)</em></li><li>Gemini 5.5 Pro GA<em>(Q3 2028, medium)</em></li><li>Gemini 6 Pro preview at the November anniversary; marketed as &ldquo;an agent, not a model&rdquo;<em>(Nov 2028, medium)</em></li></ul><h3 id="cloud-business--capex-2">Cloud, Business &amp; CapEx</h3><ul><li>2027 full-year revenue closes at $560–600B<em>(Q4 2027 reported Jan 2028, high)</em></li><li>Cloud annualized run-rate ~$140B at start of year<em>(Jan 2028, high)</em></li><li>2028 CapEx guidance lands at $300–350B<em>(Jan 2028, medium)</em></li><li>Cloud Q2 2028 quarterly revenue $40–45B<em>(Jul 2028, medium)</em></li><li>Cloud margins visibly improving as TPU economics compound<em>(2028, medium)</em></li><li>Cloud Q3 2028 quarterly revenue $50–57B; growth in the 30–40% range<em>(Oct 2028, medium)</em></li><li>Cloud annualized run-rate around $200B by year-end<em>(Dec 2028, medium)</em></li><li>2029 CapEx guidance climbs to $300B+<em>(Dec 2028, medium)</em></li></ul><h3 id="compute-tpu-2">Compute (TPU)</h3><ul><li>TPU 10 announced at Cloud Next 2028<em>(Apr 2028, medium)</em></li><li>External TPU sales pass an inflection — Anthropic&rsquo;s gigawatt commitment is online; additional named cloud-resale customers announced<em>(Apr 2028, medium)</em></li><li>The argument that TPU/GPU customers have reached rough parity for new AI workloads becomes defensible<em>(2028, low)</em></li></ul><h3 id="distribution-2">Distribution</h3><ul><li>Astra-everywhere — same multimodal assistant is the surface in Gemini app, Search AI Mode, Pixel/Android, Workspace, Chrome, Antigravity, and the car<em>(May 2028, high)</em></li><li>Personalization unified across all surfaces via Personal Intelligence<em>(May 2028, high)</em></li><li>Android XR glasses v2 announced, $200–400 cheaper than v1 with an actual app developer story<em>(May 2028, medium)</em></li></ul><h3 id="verticals--enterprise-2">Verticals &amp; Enterprise</h3><ul><li>Gemini Enterprise crosses 25M paid seats across 5,000+ enterprise customers<em>(Apr 2028, medium)</em></li><li>Antigravity 3.0 / Cloud Code consolidation; agentic coding is its own product category by now<em>(May 2028, medium)</em></li></ul><h3 id="open-weight-gemma-2">Open-Weight (Gemma)</h3><ul><li>Gemma 6 family ships mid-year; open-weight ecosystem firmly Google-led<em>(Jul 2028, medium)</em></li></ul><h3 id="hardware-2">Hardware</h3><ul><li>Made by Google 2028 (August) — Pixel 13 series, Pixel Watch 6, refreshed Buds<em>(Aug 2028, high)</em></li><li>A second-generation Android XR product beyond glasses — possibly a higher-end mixed-reality device or a dedicated AI wearable that isn&rsquo;t glasses<em>(Aug 2028, low)</em></li><li>Pixel 13 ships with Gemini Nano 5 and on-device agentic capability ahead of Apple Intelligence<em>(Aug 2028, medium)</em></li><li>iPhone 20 lands — Apple&rsquo;s catch-up generation; Google&rsquo;s marketing positions Pixel as the AI-native device unambiguously<em>(Sep 2028, medium)</em></li><li>Aluminium OS / Googlebook gen 3; combined Android + Aluminium installed base meaningfully threatens Windows in non-enterprise segments<em>(Aug–Sep 2028, low)</em></li></ul><h3 id="robotics-2">Robotics</h3><ul><li>Boston Dynamics / Gemini Robotics partnership produces a named consumer or commercial deployment — Atlas in a real factory at scale, or a domestic-robotics demo with a major appliance brand<em>(CES Jan 2028, medium)</em></li><li>A new TPU-on-vehicle integration with at least one Tier-1 OEM<em>(CES Jan 2028, medium)</em></li><li>Gemini Robotics ships as a licensable model for general robotics developers<em>(2028, medium)</em></li></ul><h3 id="science-2">Science</h3><ul><li>DeepMind science announcements: AlphaEvolve hitting multiple industrial deployments with measurable economic impact; an internal Google datacenter scheduling improvement worth measurable billions is disclosed<em>(2028, medium)</em></li><li>A Genie/Veo/robotics convergence that&rsquo;s clearly the simulation backbone for both Waymo and the Boston Dynamics partnership<em>(2028, medium)</em></li></ul><h3 id="isomorphic-labs-2">Isomorphic Labs</h3><ul><li>Phase 2 data (or first Phase 2 trial start)<em>(Q3 2028, medium)</em></li><li>A partnered drug moving toward Phase 3 — internally developed or one of the Lilly/Novartis pipeline candidates<em>(Q4 2028, medium)</em></li><li>The &ldquo;AI-discovered drug reaches market&rdquo; story is now visibly two-to-four years out rather than hypothetical<em>(end of 2028, medium)</em></li></ul><h3 id="waymo-2">Waymo</h3><ul><li>Possibly broken out as a separate segment for reporting<em>(Jan 2028, medium)</em></li><li>Crosses 3M rides per week<em>(Q2 2028, medium)</em></li><li>Mesa factory and Geely Zeekr lines together producing tens of thousands of autonomous vehicles per year<em>(2028, medium)</em></li><li>Tokyo and London at meaningful commercial scale; Paris and Sydney plausibly open testing<em>(Q2 2028, medium)</em></li><li>28–35 active US service areas, uniformly 24/7<em>(end of 2028, medium)</em></li><li>Cumulative Waymo rides cross 250M<em>(end of 2028, medium)</em></li><li>Waymo annualized revenue $12–18B and operationally profitable; unit-economics question definitively answered<em>(Q4 2028, medium)</em></li></ul><h3 id="geopolitics--antitrust-2">Geopolitics &amp; Antitrust</h3><ul><li>US presidential election outcome shapes the late-year narrative; AI policy is a real campaign topic<em>(Nov 2028, high)</em></li><li>The AI antitrust case rumbling since 2027 reaches a clearer trajectory — dismissed, settled, or set for a substantive next phase. Cautious read: no structural divestiture by year-end<em>(Q4 2028, medium)</em></li><li>The Search-case appellate saga continues but produces no structural change<em>(2028, medium)</em></li></ul><hr><h2 id="what-would-break-the-trajectory">What Would Break the Trajectory</h2><p>The predictions above hold only if the next two and a half years don&rsquo;t contain a discontinuity. Ranked by probability:</p><ol><li>A DOJ remedy harsher than expected — forced divestiture of Search or Android rather than the Chrome-only outcome the cautious frame assumes.</li><li>A serious capability stumble — Gemini 4, 4.5, or 5 fails to ship competitively against OpenAI/Anthropic at a critical moment.</li><li>An EU regulatory action that materially constrains Google&rsquo;s distribution moats.</li><li>A safety or trust incident — AI Overviews or Gemini producing harmful output at scale, followed by a regulatory hammer.</li><li>A capability plateau across the industry (rather than specific to Google).</li><li>US/China conflict disrupting TSMC fabs and therefore TPU production.</li><li>Demis Hassabis departure or significant DeepMind leadership churn.</li><li>A serious recession compressing cloud and ad revenue simultaneously.</li></ol><p>The honest sentence: absent a discontinuity, Google has the strongest hand of any AI lab. The distribution moat (Search, YouTube, Workspace, Android, Chrome) is the largest competitive advantage in the industry, and the TPU vertical integration is the second-largest. The only reason Google is not the obvious frontrunner today is that Demis Hassabis ran DeepMind as a research lab for too long before Sundar Pichai pivoted it to product execution. That pivot has happened. The trajectory above assumes the pivot continues to be executed at the level it has been since Gemini 3.</p><hr><h2 id="whats-different-about-google-deepmind">What&rsquo;s Different About Google DeepMind</h2><p>Three observations that distinguish Google DeepMind&rsquo;s trajectory from Anthropic&rsquo;s and OpenAI&rsquo;s, and which I think frame the rest of the series.</p><ol><li><p><strong>Google has a distribution moat the others cannot match.</strong> Anthropic reaches users through API integrations and enterprise contracts; OpenAI through ChatGPT subscriptions and the Microsoft channel. Google reaches users through Search (3B+ monthly), YouTube (2.7B), Workspace (3B), Android (3B+ devices), Chrome (3B+ users), and Maps. The Gemini app is the smallest of these surfaces. Most of Google&rsquo;s AI distribution is<em>invisible</em> — users encounter it as a feature of a product they already use rather than as a destination they navigate to. This is a different competitive game from the one OpenAI and Anthropic are playing, and it favours Google asymmetrically over time.</p></li><li><p><strong>Google has vertical compute integration no other lab approaches.</strong> TPUs are designed at Google, fabbed at TSMC under Google&rsquo;s specification, and deployed exclusively in Google data centers. The Anthropic TPU deal in late 2025 — 1M+ chips, 1GW dedicated capacity — was the first time another frontier lab adopted TPU at scale, and it changed the industry&rsquo;s read on Google&rsquo;s compute story from &ldquo;interesting in-house program&rdquo; to &ldquo;credible alternative to Nvidia.&rdquo; Anthropic&rsquo;s 4x cost advantage over OpenAI in training compute is, in significant part, a TPU advantage. Google&rsquo;s predictions above include &ldquo;external TPU sales pass an inflection by 2028&rdquo; specifically because the silicon advantage is the kind of structural moat that compounds in a way capability alone does not.</p></li><li><p><strong>Google has a scientific research record no other lab matches.</strong> AlphaFold&rsquo;s Nobel Prize is the most legible single fact about this, but the broader pattern — AlphaProof, AlphaEvolve, AlphaMissense, AlphaGenome, the Isomorphic Labs spinout, the long materials-science arc, the DOE Genesis Mission partnership — is that DeepMind has, for fifteen years, produced fundamental scientific results at a rate no contemporary academic institution and no contemporary research lab can match. This is the<em>legitimacy</em> moat. When the AI conversation turns to &ldquo;what is this technology actually good for,&rdquo; Google&rsquo;s answer is genuinely different from Anthropic&rsquo;s or OpenAI&rsquo;s. The others can point to productivity gains; Google can point to a Nobel Prize.</p></li></ol><p>A fourth observation worth naming, because it doesn&rsquo;t fit either of the prior two posts: Google has businesses<em>adjacent to</em> AI that are also at frontier-defining scale. Waymo is approaching a multi-million-rides-per-week robotaxi business with positive unit economics in mature markets. Isomorphic Labs has clinical-stage AI-designed pharmaceuticals. The Boston Dynamics partnership is approaching real warehouse and household deployment. Hardware (Pixel, Android XR, Googlebook) is becoming a coherent platform. None of these has a clean equivalent at OpenAI or Anthropic — neither company is shipping autonomous vehicles, dosing patients, building humanoid robots, or running a multi-OS hardware platform. Google&rsquo;s trajectory is, on inspection, four trajectories at once, which is part of why this post is the longest in the series.</p><p>The implication: Google DeepMind is the lab most likely to be the largest of the three by 2028, the one whose competitive position is hardest to displace, and the one whose risk profile is most concentrated in regulatory rather than capability outcomes. This is, on inspection, the position the second-mover often arrives at: not first across the finish line but built to win the longer race.</p><hr><h2 id="whats-next">What&rsquo;s Next</h2><p>The next post in this series will cover Meta&rsquo;s open-weight effort — the Llama family, the FAIR-to-Superintelligence-Labs reshape, the Reality Labs and AR/VR convergence with AI, and the open-weight strategy as a competitive moat against the proprietary frontier. After that: the Chinese frontier (DeepSeek, Zhipu, Moonshot, Qwen, and the SOE consolidation question).</p><p>Sources for the baseline data in this post:<a href="https://fortune.com/2026/04/29/google-earnings-cloud-ai/">Alphabet Q1 2026 earnings (Fortune)</a>,<a href="https://blog.google/products-and-platforms/products/gemini/gemini-3/">Gemini 3.1 Pro launch (Google)</a>,<a href="https://tech-insider.org/google-gemini-750-million-users-march-2026-updates/">Gemini 750M users (Tech Insider)</a>,<a href="https://cloud.google.com/blog/products/compute/ironwood-tpus-and-new-axion-based-vms-for-your-ai-workloads">Ironwood TPU launch (Google Cloud Blog)</a>,<a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/google-deploys-new-axion-cpus-and-seventh-gen-ironwood-tpu-training-and-inferencing-pods-beat-nvidia-gb300-and-shape-ai-hypercomputer-model">Google TPU v7 specifications (Tom&rsquo;s Hardware)</a>,<a href="https://creati.ai/ai-news/2026-02-14/deepmind-ai-cancer-drug-clinical-trials-2026-demis-hassabis/">DeepMind cancer drug clinical trials (Creati AI)</a>,<a href="https://www.technologyreview.com/2025/11/24/1128322/whats-next-for-alphafold-a-conversation-with-a-google-deepmind-nobel-laureate/">AlphaFold five years later (MIT Technology Review)</a>,<a href="https://thenextweb.com/news/google-cloud-next-ai-agents-agentic-era">Google Cloud Next 2026 agents (TheNextWeb)</a>,<a href="https://newsletter.semianalysis.com/p/tpuv7-google-takes-a-swing-at-the">Anthropic-Google TPU deal (SemiAnalysis)</a>.</p>
]]></content:encoded></item><item><title>The OpenAI Trajectory</title><link>https://mtclinton.com/posts/the-openai-trajectory/</link><pubDate>Wed, 13 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-openai-trajectory/</guid><category>ai</category><description>A categorized set of predictions about OpenAI's trajectory through the end of 2028.</description><content:encoded>&lt;![CDATA[<p>This is the second post in a series cataloguing predictions about the major AI labs through the end of 2028. The first post covered<a href="/posts/the-anthropic-trajectory/">Anthropic</a>; subsequent posts will cover<a href="/posts/the-google-deepmind-trajectory/">Google DeepMind</a>, Meta, and the Chinese open-weight frontier on the same template. Each lab gets a structured ledger to come back to and check against what actually happened.</p><p>Where OpenAI stands as of mid-May 2026, for context:</p><ul><li>Annualized revenue is roughly $25B, growing at about $2B/month. The historical trajectory: ~$2B in 2023, ~$6B in 2024, ~$20B at end of 2025, ~$25B by February 2026.</li><li>Anthropic surpassed OpenAI on ARR in April 2026 (~$30B vs. OpenAI&rsquo;s ~$25B). This is the first time OpenAI has trailed a competitor on revenue since ChatGPT launched.</li><li>Closed a $122B funding round at an $852B post-money valuation in March 2026 (Amazon $50B, Nvidia $30B, SoftBank $30B, with continued Microsoft participation).</li><li>ChatGPT has ~900M weekly active users, 9M+ paying business users, 7M+ enterprise seats, and is deployed at 92% of the Fortune 500.</li><li>Microsoft partnership was restructured on April 27, 2026: exclusive Azure license ended, OpenAI can serve on any cloud, the AGI escape clause was deleted entirely, revenue-share payments are now capped at $38B cumulative through 2030.</li><li>Stargate compute program: ~7GW of capacity planned across six U.S. sites plus the UAE; over $400B committed over three years. Abilene is at 2 of 8 buildings operational.</li><li>Model lineup: GPT-5, GPT-5.4, GPT-5.5 (April 23), GPT-5.5 Instant (May 5), o3, o4-mini. GPT-5.6 began internal testing April 30. GPT-6 has not shipped — what was code-named &ldquo;Spud&rdquo; was released as GPT-5.5.</li><li>DeployCo (the OpenAI Deployment Company) launched May 11 with $4B from TPG, Goldman Sachs, and SoftBank. Anchored by the Tomoro acquisition (~150 Forward Deployed Engineers, partnered since 2023). Explicitly modeled on Palantir&rsquo;s FDE playbook.</li><li>DoD relationship: $200M contract with the Department of War signed Feb 27, 2026; OpenAI is one of eight firms cleared to deploy on classified networks.</li><li>Hardware: Jony Ive&rsquo;s io device delayed from 2026 to early 2027; expected as a screenless, contextually-aware device; 40–50M unit year-one target with Foxconn.</li><li>Sora video product: discontinued April 26, 2026; full API shutdown scheduled for September 24, 2026.</li><li>DevDay 2026 is scheduled for September 29 in San Francisco — the cadence anchor for this year&rsquo;s major product announcements.</li><li>Sam Altman testified in the Musk lawsuit on May 12, 2026; verdict expected in coming weeks.</li></ul><p>The predictions below are anchored on that baseline. Each has a target time window and a confidence level reflecting how willing I am to be wrong publicly about it. The 2026 predictions are organized around known event cadence (DevDay, Stargate ramp, IPO timing). The 2027 and 2028 predictions compress to quarter and year resolution as uncertainty widens.</p><hr><h2 id="2026-balance-of-year">2026 (Balance of Year)</h2><h3 id="models">Models</h3><ul><li>GPT-5.6 limited preview to Plus / Pro / API Enterprise tiers<em>(Jun 2026, high)</em></li><li>GPT-5.6 general availability at DevDay<em>(Sep 29, 2026, high)</em></li><li>GPT-5.7 ships as an agent-and-tool-use upgrade<em>(Q4 2026, medium)</em></li><li>GPT-6 named and teased at DevDay; not GA in 2026<em>(Sep 2026, medium)</em></li><li>Voice mode 2 with realtime translation as default; built on the GPT-Realtime-Translate API primitives<em>(Q3 2026, high)</em></li><li>A small-model line targeting the Jony Ive hardware seeds to developers<em>(Q4 2026, low)</em></li></ul><h3 id="business--finance">Business &amp; Finance</h3><ul><li>Annualized revenue run-rate reaches $50B by year-end<em>(Dec 2026, medium)</em></li><li>Annual revenue for 2026 (cumulative) lands around $30–35B<em>(Dec 2026, high)</em></li><li>8th, 9th, 10th, 11th acquisitions of 2026 close — the ~6-week cadence holds<em>(Dec 2026, high)</em></li><li>S-1 filed with the SEC late November, hitting CFO Friar&rsquo;s &ldquo;H2 2026 regulatory filing&rdquo; target<em>(Nov 2026, medium)</em></li><li>IPO roadshow begins mid-December; pricing range disclosed at $1.0–1.4T<em>(Dec 2026, medium)</em></li><li>IPO listing slips to Q1 2027 — Friar previously signaled exactly this<em>(Dec 2026, medium)</em></li></ul><h3 id="deployco--verticals">DeployCo &amp; Verticals</h3><ul><li>DeployCo announces 5+ marquee customer wins by year-end (banks, pharma, defense primes); reaches $1B+ ARR run-rate<em>(Dec 2026, medium)</em></li><li>OpenAI for Finance launches at or just after DevDay, anchored on the Hiro acquisition<em>(Q4 2026, medium)</em></li><li>OpenAI for Government formalized with named cabinet pilots<em>(Q3 2026, high)</em></li><li>Healthcare adds 5–10 new health-system deployments<em>(2026, medium)</em></li><li>The expected &ldquo;third vertical&rdquo; announcement at DevDay reframes — instead of a new productized vertical, OpenAI uses the slot to position DeployCo as the scalable vehicle for the long tail<em>(Sep 2026, medium)</em></li><li>A vertical-specific subsidiary structure begins forming for Healthcare or Finance, mirroring the DeployCo template<em>(Q4 2026, low)</em></li></ul><h3 id="distribution--multi-cloud">Distribution &amp; Multi-cloud</h3><ul><li>ChatGPT Business and the OpenAI API listed on AWS Marketplace<em>(Q3 2026, high)</em></li><li>ChatGPT Business and the OpenAI API listed on GCP Marketplace<em>(Q4 2026, medium)</em></li><li>First public confirmation that a major Microsoft 365 Copilot surface (Word, Excel, or Teams) is running on a non-OpenAI model<em>(Q4 2026, medium)</em></li></ul><h3 id="hardware">Hardware</h3><ul><li>Jony Ive io device confirmed for February 2027 launch on the DevDay stage<em>(Sep 2026, high)</em></li><li>A second hardware product line (wearable or earpiece) teased on stage<em>(Sep 2026, low)</em></li><li>Foxconn U.S. factory site named<em>(Q4 2026, medium)</em></li></ul><h3 id="consumer">Consumer</h3><ul><li>ChatGPT crosses 1.2B weekly active users<em>(end of 2026, high)</em></li><li>Atlas browser crosses 80M daily active users; Chrome market-share decline becomes a measurable story<em>(end of 2026, medium)</em></li><li>Atlas + ChatGPT desktop + Codex unified superapp ships at DevDay (March 2026 announcement lands)<em>(Sep 2026, high)</em></li><li>A consumer subscription tier between Plus ($20) and Pro ($200) launches at $50–60/month<em>(Q3 2026, medium)</em></li><li>15M+ paying business users (up from 9M in February)<em>(end of 2026, high)</em></li></ul><h3 id="codex--developer">Codex / Developer</h3><ul><li>Codex weekly active users cross 7M<em>(Q3 2026, high)</em></li><li>Agent platform v2 launches at DevDay; third-party agent marketplace opens<em>(Sep 2026, high)</em></li><li>API token volume passes 50B tokens/minute<em>(end of 2026, medium)</em></li><li>Codex Security expanded into a full DevSecOps product line<em>(Q4 2026, medium)</em></li></ul><h3 id="infrastructure">Infrastructure</h3><ul><li>Stargate Abilene reaches 6 of 8 buildings operational by August, 8 of 8 by year-end<em>(2026, high)</em></li><li>Stargate Norway operational<em>(Q4 2026, high)</em></li><li>Two additional sovereign-compute deals close (likely India, Japan, or Saudi Arabia)<em>(end of 2026, medium)</em></li><li>First Titan custom silicon tape-out from TSMC, with Broadcom as design partner<em>(Q4 2026, low)</em></li></ul><h3 id="geopolitics--governance">Geopolitics &amp; Governance</h3><ul><li>Musk lawsuit verdict delivered; cautious read is a split decision with appeals filed regardless of outcome<em>(Jun–Jul 2026, high)</em></li><li>Pentagon contract first-deliverable milestones disclosed<em>(Q3 2026, medium)</em></li><li>A senior White House liaison hire is announced<em>(2026, medium)</em></li><li>Trusted Contact safety feature rolled to broad availability<em>(Q3 2026, high)</em></li><li>GPT-5.5-Cyber preview extends beyond the EU to UK and additional Five Eyes partners<em>(Q3 2026, medium)</em></li></ul><hr><h2 id="2027">2027</h2><h3 id="models-1">Models</h3><ul><li>GPT-6 family ships in full at DevDay 2027<em>(Sep 2027, high)</em></li><li>GPT-6 capability framing: long-horizon agents executing multi-day autonomous tasks unsupervised<em>(2027, medium)</em></li><li>Sora successor (video model v2) launches at a quality level that meaningfully threatens commercial b-roll and explainer-video workflows<em>(Q4 2027, medium)</em></li><li>A reasoning model with persistent memory and 50M+ token context becomes default<em>(2027, medium)</em></li><li>A small-model line ships with strong on-device capability targeting the Jony Ive hardware<em>(H1 2027, medium)</em></li></ul><h3 id="business--finance-1">Business &amp; Finance</h3><ul><li>IPO closes Q1 2027 at $1.3–1.6T; first-day move puts it briefly above $2T<em>(Q1 2027, medium)</em></li><li>Year-end ARR reaches $110–130B<em>(Dec 2027, medium)</em></li><li>Market cap reaches $2.5–3T by end of 2027; OpenAI is the largest U.S. company by market cap for at least one quarter<em>(end of 2027, medium)</em></li><li>DeployCo grows to $5–10B ARR run-rate<em>(end of 2027, medium)</em></li><li>A second subsidiary spin (most defensibly hardware) takes outside capital from a TPG / Goldman / SoftBank–style consortium<em>(2027, medium)</em></li><li>Microsoft 20% revenue-share cumulative payments cross $20B of the $38B cap<em>(end of 2027, high)</em></li><li>Total 2027 acquisitions: 7–8 (cadence slows post-IPO from ~6 weeks to ~8–10 weeks under public-company governance)<em>(2027, medium)</em></li></ul><h3 id="distribution">Distribution</h3><ul><li>Non-Azure inference workloads (AWS + GCP combined) reach 30–50% of total OpenAI API revenue<em>(end of 2027, medium)</em></li><li>Microsoft ships at least one major Copilot surface on a non-OpenAI model — awkward fact at OpenAI&rsquo;s Q2 2027 earnings<em>(mid-2027, medium)</em></li></ul><h3 id="hardware-1">Hardware</h3><ul><li>Jony Ive io device ships February 2027<em>(Q1 2027, high)</em></li><li>Year-one sales 5–10M units — well above the cautious &ldquo;Apple Watch ramp&rdquo; comparable, on the strength of ChatGPT&rsquo;s installed base<em>(2027, medium)</em></li><li>Second hardware product (wearable or earpiece) teased at DevDay 2027 with a Q2 2028 ship date<em>(Q3 2027, medium)</em></li><li>Hardware revenue reaches $10–20B annualized<em>(end of 2027, medium)</em></li></ul><h3 id="deployco--verticals-1">DeployCo &amp; Verticals</h3><ul><li>8+ productized verticals exist by year-end<em>(2027, medium)</em></li><li>ChatGPT for Healthcare reaches &gt;$5B ARR<em>(2027, medium)</em></li><li>ChatGPT for Finance reaches &gt;$3B ARR<em>(2027, medium)</em></li><li>DeployCo IPO file or strategic-sale rumor begins circulating<em>(end of 2027, medium)</em></li><li>An OpenAI Solutions Partner ecosystem (system integrators, vertical specialists) grows into a $10B+ sub-economy<em>(end of 2027, low)</em></li></ul><h3 id="workforce">Workforce</h3><ul><li>Junior/mid software engineering employment contracts 30–40% from 2024 peak (mirroring the broader industry pattern)<em>(2027, high)</em></li><li>McKinsey, Bain, and BCG analyst class sizes cut 20–40% YoY<em>(2027, medium)</em></li><li>BLS publishes first major data series on AI-driven employment shifts<em>(H2 2027, medium)</em></li><li>OpenAI launches a $2–3B retraining initiative tied to enterprise deployments<em>(2027, medium)</em></li></ul><h3 id="consumer-1">Consumer</h3><ul><li>ChatGPT crosses 2B weekly active users<em>(end of 2027, medium)</em></li><li>Atlas becomes the second-most-used browser globally<em>(end of 2027, low)</em></li></ul><h3 id="infrastructure-1">Infrastructure</h3><ul><li>Stargate operational capacity passes 8GW<em>(end of 2027, medium)</em></li><li>Titan-1 custom silicon enters production deployment for inference workloads<em>(H2 2027, medium)</em></li><li>First nuclear partnership announced as direct supply (Oklo or X-energy, both Altman-connected)<em>(2027, medium)</em></li><li>First Anthropic / OpenAI compute-sharing arrangement during peak demand events<em>(2027, low)</em></li></ul><h3 id="geopolitics--governance-1">Geopolitics &amp; Governance</h3><ul><li>Musk lawsuit reaches final resolution — no removal, but reforms imposed on board composition<em>(H1 2027, medium)</em></li><li>A &ldquo;two-vendor&rdquo; Pentagon AI doctrine emerges (OpenAI plus one other)<em>(2027, medium)</em></li><li>Sam Altman testifies before Congress 3+ times across 2027<em>(2027, high)</em></li><li>A serious safety incident (autonomous agent causing material real-world harm) triggers congressional hearings<em>(H2 2027, medium)</em></li><li>An OpenAI EU subsidiary structure is announced to address regulatory framework<em>(2027, medium)</em></li></ul><hr><h2 id="2028">2028</h2><h3 id="models-2">Models</h3><ul><li>GPT-7 family ships<em>(H1 2028, medium)</em></li><li>GPT-8 announcement<em>(end of 2028, low)</em></li><li>Long-horizon agent capability (multi-week autonomous task completion) becomes a deployed product feature<em>(H2 2028, medium)</em></li><li>Open-weight competitive frontier closes to within 6–12 months of OpenAI&rsquo;s proprietary frontier<em>(2028, medium)</em></li></ul><h3 id="business--finance-2">Business &amp; Finance</h3><ul><li>Year-end ARR reaches $200–250B<em>(Dec 2028, medium)</em></li><li>Market cap reaches $3–4T<em>(end of 2028, low)</em></li><li>Microsoft $38B revenue-share cap is hit in late 2028; revenue-share payments end<em>(end of 2028, medium)</em></li><li>Microsoft IP license obligations continue through 2032 (per restructuring terms)<em>(2028, high)</em></li><li>DeployCo IPO closes — $50–100B valuation, OpenAI retains majority<em>(2028, medium)</em></li><li>A second subsidiary IPO (hardware or Healthcare) is filed<em>(end of 2028, low)</em></li><li>Holding-company structure has 4–6 majority-owned operating subsidiaries — the org chart looks like a venture portfolio with the parent at the center<em>(end of 2028, medium)</em></li><li>An OpenAI public-company acquisition is announced for $20–50B+; defensible candidates include Shopify, Stripe (if public), or a security/identity company<em>(2028, low)</em></li></ul><h3 id="hardware-2">Hardware</h3><ul><li>io device line crosses 25–40M cumulative units shipped<em>(end of 2028, medium)</em></li><li>Second hardware product ships in Q2 2028; year-one sales 5–10M units<em>(2028, medium)</em></li><li>A third hardware category teased (laptop replacement, AR glasses, or successor form factor)<em>(end of 2028, low)</em></li><li>Total hardware revenue reaches $30–60B annualized<em>(end of 2028, low)</em></li></ul><h3 id="workforce--the-openai-mafia">Workforce &amp; the OpenAI Mafia</h3><ul><li>Junior/mid software engineering employment contracts 50–60% from 2024 peak<em>(2028, medium)</em></li><li>BLS reports the first measurable decline in white-collar employment categories specifically attributable to LLM agent adoption<em>(2028, medium)</em></li><li>IPO lockup expiry mints 2,000–3,000 millionaire employees and ~50 nine-figure employees<em>(mid-2028, high)</em></li><li>15–25 well-funded &ldquo;OpenAI alumni&rdquo; startups raise Series A or higher across 2028<em>(2028, high)</em></li><li>3+ alumni companies raise at $1B+ valuations within 12 months of founding<em>(2028, medium)</em></li><li>OpenAI&rsquo;s own retention numbers become a quoted concern in earnings calls<em>(2028, medium)</em></li><li>A unified Western framework for AI-driven workforce displacement compensation begins to take shape<em>(2028, low)</em></li></ul><h3 id="consumer-2">Consumer</h3><ul><li>ChatGPT crosses 3B weekly active users (~35% of internet-connected adults)<em>(end of 2028, low)</em></li><li>Atlas becomes the default browser on new device sales in the U.S.<em>(end of 2028, low)</em></li></ul><h3 id="infrastructure-2">Infrastructure</h3><ul><li>Stargate operational capacity passes 15GW<em>(end of 2028, medium)</em></li><li>Custom silicon (Titan-2) handles &gt;50% of inference workload<em>(end of 2028, medium)</em></li><li>OpenAI buys or co-builds nuclear capacity through a small modular reactor partnership<em>(2028, medium)</em></li><li>Multi-gigawatt single-customer power purchase agreements become routine<em>(2028, medium)</em></li><li>A formal civilian-DoD compute reserve agreement exists<em>(2028, low)</em></li></ul><h3 id="geopolitics--governance-2">Geopolitics &amp; Governance</h3><ul><li>First federal U.S. AI law passes; OpenAI policy team is among the primary drafters and the bill&rsquo;s compliance burden entrenches incumbents<em>(2028, medium)</em></li><li>Sam Altman openly courted for cabinet or commission roles; chairs (or is offered the chair of) an executive-branch AI advisory commission<em>(2028, medium)</em></li><li>USG bans Chinese-trained inference services for federal and critical-infrastructure customers<em>(2028, medium)</em></li><li>A major Chinese open-weight model reaches parity with the prior-generation OpenAI frontier<em>(H2 2027 or 2028, medium)</em></li><li>Reciprocal Chinese restrictions cut OpenAI&rsquo;s already-near-zero China revenue to formally zero<em>(2028, high)</em></li><li>The global AI market bifurcates: U.S. plus allied bloc on one side, Chinese plus non-aligned bloc on the other<em>(end of 2028, medium)</em></li><li>OpenAI is recognized as a quasi-sovereign actor in trade agreements<em>(2028, low)</em></li></ul><h3 id="science">Science</h3><ul><li>An OpenAI-trained model contributes meaningfully to a major scientific discovery (medical, materials, or physics)<em>(2028, low)</em></li></ul><hr><h2 id="what-would-break-the-trajectory">What Would Break the Trajectory</h2><p>These predictions hold only if the next two and a half years don&rsquo;t contain a discontinuity. Ranked by probability:</p><ol><li>A serious safety incident with OpenAI technology — most likely candidates are an autonomous agent causing material financial loss, or a healthcare-context death attributable to an agent.</li><li>The Musk lawsuit produces a worse outcome than expected (forced restructuring, Altman removal, or major equity-share changes).</li><li>A federal regulatory hammer that lands harder than the incumbent-friendly framing assumed above — most likely from the SEC if pre-IPO disclosures prove problematic, or from a unified post-incident AI Act.</li><li>A capability plateau — GPT-6 or GPT-7 fails to deliver the step-change improvements that the cadence implicitly promises.</li><li>A compute supply collapse — Taiwan/TSMC, U.S. energy infrastructure, or Stargate financing.</li><li>The Microsoft separation goes worse than orchestrated — a downstream contract dispute or a Copilot defection that costs OpenAI a meaningful customer or distribution channel.</li><li>U.S./China conflict at sufficient intensity to disrupt Pacific operations or chip supply.</li><li>Internal stress — board conflict, additional executive departures, or a governance crisis that undoes the post-2023 stabilization.</li></ol><p>The honest sentence: absent a discontinuity, OpenAI continues to be one of the two or three most consequential companies on earth. The interesting question is no longer &ldquo;is OpenAI big enough to matter&rdquo; — it&rsquo;s &ldquo;what does the OpenAI holding-company structure look like, and how does that reshape both the AI industry and the global enterprise software market.&rdquo;</p><hr><h2 id="whats-different-about-openai">What&rsquo;s Different About OpenAI</h2><p>Four observations that distinguish OpenAI&rsquo;s trajectory from Anthropic&rsquo;s or Google DeepMind&rsquo;s, and which I think the rest of this series will return to:</p><ol><li><p><strong>OpenAI is no longer the revenue leader.</strong> Anthropic passed it in April 2026, with substantially better unit economics (4x less spend per training run, by some estimates). This is the first time OpenAI has been second on revenue in any meaningful way since ChatGPT launched, and the company&rsquo;s strategy now appears to be partially defined by competition with a smaller, more efficient rival rather than by its own pure growth curve.</p></li><li><p><strong>OpenAI has a hardware play in a way Anthropic does not.</strong> The Jony Ive device is, on inspection, a multi-billion-dollar bet that the form factor of consumer AI will be a dedicated piece of hardware rather than an app on a phone. If it works, OpenAI becomes a hardware company at a scale that no AI lab has previously attempted. If it doesn&rsquo;t, the bet is one of the most expensive single product failures in the technology industry&rsquo;s history.</p></li><li><p><strong>OpenAI is structuring itself as a holding company.</strong> This is the structural thread that the May 11 DeployCo announcement made unmistakable. DeployCo took $4B of outside capital (TPG, Goldman, SoftBank) into a subsidiary, not the parent — and the staffing came from Tomoro, a partner company that had been quietly accumulating Forward Deployed Engineers since 2023 specifically for this purpose. Three years of preparation for a subsidiary spin is not a tactic, it is an architecture. Expect 4–6 majority-owned operating subsidiaries on the org chart by end of 2028, financed similarly. Anthropic&rsquo;s structure (PBC with Trust governance) and Google DeepMind&rsquo;s structure (research arm under a hyperscaler) do not have anything analogous.</p></li><li><p><strong>OpenAI&rsquo;s governance is contested in a way Anthropic&rsquo;s is not.</strong> The Musk lawsuit, the Microsoft restructuring, the board composition changes, the PBC transition — all of these are still in active legal and structural motion. The corporate form is not settled. The April 27 Microsoft deal removed the AGI escape clause entirely, which changes the constraint shape for the next two years: the Microsoft relationship now winds down via the $38B revenue-share cap (predictably, mathematically) rather than via a contentious capability declaration. That is a less dramatic and more predictable transition than the cautious frame would have called for, but it pushes the dissolution of the Microsoft dependency forward by 12–18 months relative to the original 2030 schedule.</p></li></ol><hr><h2 id="whats-next">What&rsquo;s Next</h2><p>The next post in this series covers Meta — the open-weight Llama strategy, the Reality Labs convergence with FAIR, the Connect conference cadence in September, and the EU regulatory headwinds. After that: the Chinese frontier (DeepSeek, Zhipu, Moonshot, Qwen, and the SOE consolidation question), which is the post that most directly tests the bifurcation thesis above.</p><p>Sources for the baseline data in this post:<a href="https://openai.com/index/openai-launches-the-deployment-company/">OpenAI launches the Deployment Company (OpenAI)</a>,<a href="https://letsdatascience.com/blog/openai-deployment-company-4b-tpg-tomoro-may-11-2026">DeployCo $4B financing and Tomoro acquisition (Let&rsquo;s Data Science)</a>,<a href="https://www.cnbc.com/2026/04/27/openai-microsoft-partnership-revenue-cap.html">Microsoft-OpenAI restructuring (CNBC)</a>,<a href="https://aimagazine.com/news/openai-caps-microsoft-revenue-share-at-us-38bn-in-new-deal">$38B revenue-share cap (AI Magazine)</a>,<a href="https://spyglass.org/the-openai-microsoft-agi-clause/">AGI clause removed (Spyglass)</a>,<a href="https://www.saastr.com/anthropic-just-passed-openai-in-revenue-while-spending-4x-less-to-train-their-models/">Anthropic just passed OpenAI in revenue (SaaStr)</a>,<a href="https://openai.com/index/accelerating-the-next-phase-ai/">OpenAI raises $122 billion (OpenAI)</a>,<a href="https://www.bloomberg.com/news/articles/2026-03-31/openai-valued-at-852-billion-after-completing-122-billion-round">OpenAI valued at $852B (Bloomberg)</a>,<a href="https://techcrunch.com/2026/02/27/chatgpt-reaches-900m-weekly-active-users/">ChatGPT reaches 900M weekly active users (TechCrunch)</a>,<a href="https://openai.com/index/stargate-advances-with-partnership-with-oracle/">Stargate advances with Oracle partnership (OpenAI)</a>,<a href="https://openai.com/index/five-new-stargate-sites/">Five new Stargate sites (OpenAI)</a>,<a href="https://openai.com/index/introducing-stargate-norway/">Stargate Norway (OpenAI)</a>,<a href="https://openai.com/index/introducing-gpt-5-5/">Introducing GPT-5.5 (OpenAI)</a>,<a href="https://techcrunch.com/2026/05/05/openai-releases-gpt-5-5-instant-a-new-default-model-for-chatgpt/">GPT-5.5 Instant (TechCrunch)</a>,<a href="https://openai.com/index/our-agreement-with-the-department-of-war/">Our agreement with the Department of War (OpenAI)</a>,<a href="https://www.macrumors.com/2026/02/20/jony-ive-openai-smart-speaker-2027/">Jony Ive smart speaker delayed to 2027 (MacRumors)</a>,<a href="https://crypto.news/openai-ipo-targets-late-2026-as-revenue-hits-25bn/">OpenAI IPO targets late 2026 (crypto.news)</a>,<a href="https://openai.com/index/introducing-chatgpt-atlas/">Introducing ChatGPT Atlas (OpenAI)</a>,<a href="https://thetechportal.com/2026/03/20/openai-could-launch-a-desktop-super-app-integrating-chatgpt-codex-and-the-atlas-browser/">OpenAI desktop superapp merger (The Tech Portal)</a>,<a href="https://the-decoder.com/openais-deployco-subsidiary-adopts-palantirs-playbook-building-a-moat-from-workflows-no-lab-can-simulate/">DeployCo Palantir playbook (The Decoder)</a>,<a href="https://fortune.com/2026/01/07/openai-launches-chatgpt-health-in-a-push-to-become-a-hub-for-personal-health-data/">OpenAI for Healthcare (Fortune)</a>,<a href="https://www.cnn.com/2026/05/12/tech/sam-altman-openai-vs-elon-musk-testimony">Altman takes stand in Musk lawsuit (CNN Business)</a>,<a href="https://openai.com/index/devday-2026/">Announcing OpenAI DevDay 2026</a>.</p>
]]></content:encoded></item><item><title>The Anthropic Trajectory</title><link>https://mtclinton.com/posts/the-anthropic-trajectory/</link><pubDate>Wed, 13 May 2026 09:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-anthropic-trajectory/</guid><category>ai</category><description>A categorized set of predictions about Anthropic's trajectory through the end of 2028.</description><content:encoded>&lt;![CDATA[<p>This is the first post in a series cataloguing predictions about the major AI labs through the end of 2028. The series also covers<a href="/posts/the-openai-trajectory/">OpenAI</a> and<a href="/posts/the-google-deepmind-trajectory/">Google DeepMind</a>; subsequent posts will cover Meta and the Chinese open-weight frontier on the same template. Each lab gets a structured ledger to come back to and check against what actually happened.</p><p>Where Anthropic stands as of mid-May 2026, for context:</p><ul><li>Annualized revenue is roughly $35–40B, having moved from<del>$1B at end of 2024. Anthropic surpassed OpenAI on ARR in April 2026 (</del>$30B vs. OpenAI&rsquo;s ~$25B at that crossover point). The 4× less spend per training run advantage relative to OpenAI is widely cited.</li><li>API volume grew approximately 80× year-on-year, against an internal projection of 10×.</li><li>Total contracted compute spending north of $100B across AWS, Google/Broadcom, Microsoft/NVIDIA, Fluidstack, Akamai (new $1.8B deal May 8), and SpaceX (full Colossus 1 capacity May 6 — all 300+MW, 222K+ GPUs).</li><li>Code with Claude 2026 (annual developer conference) held May 6. Shipped Dreaming (agent memory consolidation between sessions — Harvey reported 6× task completion improvement), Outcomes (success-criteria iteration), and Multi-Agent Orchestration.</li><li>New enterprise AI services JV announced May 4 with Blackstone, Hellman &amp; Friedman, Goldman Sachs, plus GIC, Apollo, Leonard Green, General Atlantic, and Sequoia. $1.5B committed capital. Anthropic provides engineering and IP; does not take majority ownership. Explicit positioning against the traditional consulting industry.</li><li>Two productized verticals launched a week apart in early May — Financial Services (Claude Opus 4.7, Moody&rsquo;s data partnership, named bank deployments) and Legal (20+ MCP connectors, 12 practice-area plugins).</li><li>$30B funding round at $900B valuation in talks as of May 12 (Bloomberg); expected to close at $30–50B.</li><li>Model lineup: Claude Opus 4.7, Sonnet 4.6, Haiku 4.5. Mythos cybersecurity variant in EU-restricted preview.</li><li>Long-Term Benefit Trust governance structure operational and stable.</li><li>Federal: classified-network cleared, DoD relationship deepening.</li></ul><p>The predictions below are anchored on that baseline. Each has a target time window and a confidence level reflecting how willing I am to be wrong publicly about it. The 2026 predictions are anchored on observable cadence (model releases, partnership announcements, the federal procurement cycle). The 2027 and 2028 predictions compress to quarter and year resolution as uncertainty widens.</p><hr><h2 id="2026-balance-of-year">2026 (Balance of Year)</h2><h3 id="models">Models</h3><ul><li>Sonnet 4.7 ships<em>(Jun 2026, high)</em></li><li>Haiku 4.7 ships<em>(Jul 2026, high)</em></li><li>Claude 5 / Opus 5 family announced — three-tier bundle (Opus, Sonnet, Haiku) released in a 3–4 week window<em>(Sep 2026, high)</em></li><li>2M-token context window reaches GA with Opus 5<em>(Nov 2026, medium)</em></li><li>Mythos 2 enters research preview<em>(end of 2026, medium)</em></li><li>Voice mode ships, likely via acquisition or deep partnership<em>(Q3 2026, medium)</em></li><li>Dreaming graduates from research preview to GA on the Claude platform<em>(Q4 2026, high)</em></li></ul><h3 id="business--finance">Business &amp; Finance</h3><ul><li>$30–50B funding round closes at $900B+ valuation<em>(Jun 2026, high)</em></li><li>Annualized run-rate reaches $55–65B by year-end<em>(Dec 2026, medium)</em></li><li>Full year 2026 revenue lands at $35–40B annual<em>(Dec 2026, medium)</em></li><li>Anthropic does<em>not</em> file S-1 in 2026 — stays private<em>(2026, high)</em></li><li>Claude Code alone crosses $10B ARR<em>(end of 2026, medium)</em></li><li>Anthropic remains ahead of OpenAI on ARR through end of 2026<em>(Dec 2026, medium)</em></li></ul><h3 id="enterprise-services-jv--verticals">Enterprise Services JV &amp; Verticals</h3><ul><li>Enterprise services JV reaches $1B+ ARR run-rate by year-end<em>(Dec 2026, medium)</em></li><li>First PE-portfolio-wide JV deployment — Blackstone or Apollo brings Claude to 20+ portfolio companies as a single contract<em>(Q4 2026, medium)</em></li><li>Claude for Healthcare productized with a named anchor partner (UnitedHealth, Mayo, or Epic constellation)<em>(Jun–Jul 2026, high)</em></li><li>Claude for Government/Defense launches<em>(Q3 2026, medium)</em></li><li>6+ productized verticals exist by year-end<em>(Dec 2026, medium)</em></li><li>Claude for Insurance or Life Sciences launches<em>(Q4 2026, low)</em></li></ul><h3 id="compute--infrastructure">Compute &amp; Infrastructure</h3><ul><li>Total contracted compute capacity exceeds 1.5GW combined across all partners<em>(end of 2026, high)</em></li><li>Another sovereign-flavored compute deal closes — UAE, Singapore, or Saudi<em>(end of 2026, medium)</em></li><li>First Anthropic-dedicated SpaceX orbital data-center pilot milestone disclosed (post-Starship test campaign)<em>(Q4 2026, low)</em></li><li>Anthropic confirmed as default Claude model for at least one major Microsoft 365 Copilot surface<em>(Q4 2026, medium)</em></li></ul><h3 id="security--safety">Security &amp; Safety</h3><ul><li>Claude SOC ships as a productized offering<em>(Q4 2026, medium)</em></li><li>&ldquo;How Anthropic Uses Claude&rdquo; content series reaches 6+ posts<em>(end of 2026, high)</em></li><li>A meaningful interpretability paper publishes — gets press, framed as why Anthropic deserves regulated-industry trust<em>(Q4 2026, medium)</em></li></ul><h3 id="consumer--cowork">Consumer &amp; Cowork</h3><ul><li>Office quartet (Word/Excel/PowerPoint/Outlook) fully GA<em>(Q3 2026, high)</em></li><li>Cowork hits 15M daily active users<em>(end of 2026, medium)</em></li><li>Consumer Claude app reaches 200–300M weekly active users — much smaller than ChatGPT&rsquo;s 1.2B trajectory, but enterprise mix dominates<em>(end of 2026, medium)</em></li></ul><h3 id="geopolitics">Geopolitics</h3><ul><li>Defense exclusion fully reverses<em>(Q3 2026, high)</em></li><li>First major Pentagon contract signed in the $300–500M range<em>(Q4 2026, medium)</em></li><li>Mythos preview extends from EU-restricted to broader Five Eyes plus selected enterprise customers<em>(Q3 2026, high)</em></li></ul><h3 id="industry">Industry</h3><ul><li>A meaningful Anthropic acquisition in voice or robotics adjacency — single deliberate deal, not a cadence<em>(end of 2026, medium)</em></li></ul><hr><h2 id="2027">2027</h2><h3 id="models-1">Models</h3><ul><li>Claude 6 family ships<em>(Q2 2027, high)</em></li><li>Long-horizon agent capability (multi-day autonomous task execution) becomes a deployed feature, anchored on the Dreaming + Outcomes scaffolding<em>(2027, medium)</em></li><li>10M-token context becomes default; 50M enterprise tier ships<em>(2027, medium)</em></li><li>Voice mode rivals or beats OpenAI&rsquo;s<em>(2027, medium)</em></li><li>ASL-4 capabilities crossed publicly; at least one model held back from release as a result<em>(2027, high)</em></li><li>Mythos 3 launched, broader allied-government availability<em>(Q2 2027, medium)</em></li></ul><h3 id="business--finance-1">Business &amp; Finance</h3><ul><li>S-1 filed late Q4 2027; IPO targets H1 2028<em>(Q4 2027, medium)</em></li><li>Year-end ARR exits 2027 at $130–160B<em>(Dec 2027, medium)</em></li><li>Anthropic continues to lead OpenAI on ARR through end of 2027<em>(2027, medium)</em></li><li>Private valuation reaches $1.5–2T pre-IPO<em>(end of 2027, medium)</em></li><li>Enterprise services JV reaches $4–5B ARR<em>(end of 2027, medium)</em></li><li>A second Anthropic-anchored JV launches — different vertical, different PE/sovereign LP roster<em>(2027, medium)</em></li></ul><h3 id="compute--orbital">Compute &amp; Orbital</h3><ul><li>Total contracted compute capacity exceeds 5GW<em>(end of 2027, medium)</em></li><li>First Anthropic-dedicated orbital satellites deploy — production inference from low Earth orbit begins, capacity measured in tens of MW<em>(H2 2027, medium)</em></li><li>Anthropic + SpaceX become the de facto orbital compute alliance; Google scrambles for its own orbital arrangement<em>(2027, medium)</em></li></ul><h3 id="workforce">Workforce</h3><ul><li>US junior/mid software engineering employment contracts 30–40% from 2024 peaks<em>(2027, high)</em></li><li>F500 tier-1/2 security analyst roles contract 50–70%<em>(2027, high)</em></li><li>Mid-tier law firm associate roles contract 25–35%<em>(2027, medium)</em></li><li>US BLS publishes first major data series on AI-driven employment shifts<em>(H2 2027, medium)</em></li><li>Anthropic launches a $1–2B publicly visible retraining program tied to enterprise deployments<em>(H2 2027, medium)</em></li></ul><h3 id="verticals">Verticals</h3><ul><li>8+ productized verticals exist<em>(end of 2027, medium)</em></li><li>&ldquo;AI Operating Officer&rdquo; or equivalent C-suite role emerges at mid-market firms<em>(2027, medium)</em></li><li>A startup founded in 2027 reaches $1B valuation with &lt;20 employees, running primarily on Claude-managed agents<em>(2027, low)</em></li></ul><h3 id="safety--governance">Safety &amp; Governance</h3><ul><li>Anthropic publishes the first formal capability-declaration framework — internal definitional precision around how to talk about model capabilities; treated as a safety milestone<em>(2027, medium)</em></li><li>Long-Term Benefit Trust survives at least one significant stress-test decision; episode strengthens the governance-as-moat narrative<em>(2027, medium)</em></li><li>One customer-side safety incident; Anthropic-led postmortem published publicly<em>(2027, medium)</em></li></ul><h3 id="geopolitics-1">Geopolitics</h3><ul><li>Chinese open-weight models reach Mythos-class cybersecurity capability<em>(Q2–Q3 2027, medium)</em></li><li>Major AI-caused incident hits the financial system; OpenAI implicated more than Anthropic; enterprise migration toward Claude begins as a quoted compliance posture<em>(H2 2027, medium)</em></li><li>EU regulatory framework binds; Anthropic complies promptly; smaller labs struggle<em>(mid 2027, medium)</em></li></ul><h3 id="industry-1">Industry</h3><ul><li>Anthropic partners with a humanoid robotics company (Figure or 1X)<em>(2027, low)</em></li></ul><h3 id="science">Science</h3><ul><li>An Anthropic-trained model contributes meaningfully to a scientific result<em>(2027, low)</em></li></ul><hr><h2 id="2028">2028</h2><h3 id="models-2">Models</h3><ul><li>Claude 7 family ships<em>(mid 2028, medium)</em></li><li>100M+ context becomes the default<em>(2028, medium)</em></li><li>ASL-5 capabilities exist internally, undeployed<em>(2028, low)</em></li><li>Mechanistic interpretability becomes a deployed production capability<em>(2028, low)</em></li><li>Open-weight frontier closes to weeks (not months) behind the proprietary frontier<em>(2028, medium)</em></li></ul><h3 id="business--finance-2">Business &amp; Finance</h3><ul><li>IPO closes in H1 2028 at $2–2.5T valuation. First-day move respectable, no Musk-litigation-style overhang<em>(H1 2028, medium)</em></li><li>Year-end ARR exits 2028 at $250–320B<em>(Dec 2028, medium)</em></li><li>Anthropic continues to lead OpenAI on ARR through end of 2028 — the compounding cost-per-run advantage holds<em>(2028, medium)</em></li><li>Market cap exits 2028 at $4–5T — Anthropic is the most valuable public AI company by year-end, surpassing OpenAI cleanly<em>(end of 2028, medium)</em></li><li>Gross margin exits 2028 at 70–80%; OpenAI&rsquo;s at 45–55%<em>(2028, medium)</em></li><li>Net revenue retention crosses 130–140% (vs. OpenAI&rsquo;s 110–120%), driven by per-customer agent memory compounding<em>(2028, medium)</em></li><li>3–4 Anthropic-anchored JVs exist by year-end; total external capital flowing through them is $15–25B<em>(end of 2028, medium)</em></li><li>Anthropic Research Foundation launches with $5B+ endowment<em>(2028, medium)</em></li><li>Anthropic Solutions Partners ecosystem becomes a $30–50B sub-economy<em>(2028, low)</em></li></ul><h3 id="compute--orbital-1">Compute &amp; Orbital</h3><ul><li>Total contracted compute capacity exceeds 8GW<em>(end of 2028, medium)</em></li><li>Anthropic does<em>not</em> build a Stargate-equivalent megasite — the &ldquo;rent everywhere terrestrial, pre-buy orbital&rdquo; strategy is the full posture<em>(2028, high)</em></li><li>Orbital compute scales to hundreds of MW deployed across SpaceX satellite constellation<em>(end of 2028, medium)</em></li><li>A dedicated Anthropic-SpaceX orbital-compute JV exists with sovereign-defense-adjacent LPs<em>(end of 2028, low)</em></li></ul><h3 id="hardware">Hardware</h3><ul><li>Anthropic ships agent-runtime hardware — a server appliance or workstation-class device for running Claude agent fleets locally on enterprise IT<em>(H2 2028, medium)</em></li><li>Anthropic does<em>not</em> ship consumer hardware through 2028<em>(2028, high)</em></li></ul><h3 id="workforce-1">Workforce</h3><ul><li>Junior/mid software engineering contracts 50–60% from 2024 peaks<em>(2028, medium)</em></li><li>Security profession reshapes into three tiers (orchestrators, deep specialists, compliance); middle tier essentially gone<em>(2028, medium)</em></li><li>A Western country pilots a UBI-adjacent program tied explicitly to AI displacement<em>(2028, low)</em></li><li>Anthropic headcount exits 2028 at 5,500–6,500 — revenue per employee crosses $45–50M+<em>(end of 2028, medium)</em></li></ul><h3 id="verticals--adjacencies">Verticals &amp; Adjacencies</h3><ul><li>5–6 verticals productized at Anthropic&rsquo;s parent (Healthcare, Finance, Legal, Government, plus one or two of Education/Insurance)<em>(2028, medium)</em></li><li>3–4 Anthropic-anchored JVs cover the long tail and international expansion<em>(end of 2028, medium)</em></li></ul><h3 id="consumer">Consumer</h3><ul><li>250M+ consumer DAU on Claude<em>(2028, medium)</em></li><li>Robotics becomes a real consumer category running Claude-derived models<em>(2028, low)</em></li><li>AR glasses or successor devices ship with Claude as the primary cognition layer<em>(2028, low)</em></li></ul><h3 id="safety-governance--geopolitics">Safety, Governance &amp; Geopolitics</h3><ul><li>Anthropic-published evaluation methodology becomes the legally-required pre-deployment standard in the federal AI law that passes in 2028<em>(2028, medium)</em></li><li>Long-Term Benefit Trust composition update or formal decision lands; survives as evidence the governance form is durable<em>(2028, medium)</em></li><li>Dario Amodei testifies before Congress 3+ times across 2028; profiled extensively in major press; explicitly declines federal advisory or cabinet roles<em>(2028, medium)</em></li><li>Anthropic does not sell into China at all — posture holds through 2028<em>(2028, high)</em></li><li>USG bans Chinese-trained inference services for federal and critical-infrastructure customers; Anthropic positioned as the safe alternative<em>(2028, medium)</em></li><li>A unified Western AI governance framework comes into existence; Anthropic&rsquo;s published rubrics are referenced<em>(2028, low)</em></li></ul><h3 id="industry-2">Industry</h3><ul><li>Anthropic acquires a high-profile open-source AI safety / interpretability lab for $400–800M — single deliberate deal<em>(2028, medium)</em></li></ul><h3 id="science-1">Science</h3><ul><li>An Anthropic-trained model contributes meaningfully to a Nobel-tier scientific result<em>(2028, low)</em></li></ul><hr><h2 id="what-would-break-the-trajectory">What Would Break the Trajectory</h2><p>These predictions hold only if the next two and a half years don&rsquo;t contain a discontinuity. Ranked by probability:</p><ol><li>A publicly visible safety incident with Anthropic technology — the customer-side Dreaming-era agent autonomy creates a class of failure mode that didn&rsquo;t exist before.</li><li>A federal regulatory hammer that lands differently than the incumbent-friendly framing assumed above — most likely from a unified post-incident AI Act that imposes structural rather than rubric-based constraints.</li><li>A compute supply collapse — Taiwan/TSMC, U.S. energy infrastructure, or a SpaceX-side failure that pushes orbital compute back by 2+ years.</li><li>A capability plateau — Claude 5, 6, or 7 fails to deliver the step-change improvements the cadence implicitly promises; or Dreaming-style continual learning fails to compound at scale.</li><li>A serious recession compressing enterprise spending; the JV-and-partnership structure absorbs less of this than a fully-owned subsidiary structure would.</li><li>U.S./China conflict at sufficient intensity to disrupt Pacific operations or chip supply.</li><li>Internal stress at Anthropic — key departures, board conflict, or a Long-Term Benefit Trust governance crisis that the structure does not survive.</li></ol><p>None of these is so improbable it can be ignored. None is so probable it removes the trajectory from the table. The honest sentence: absent a discontinuity, Anthropic ends 2028 as the most valuable AI company on Earth, with the cleanest balance sheet, the smallest headcount, the best margins, and the strongest regulatory moat. The interesting question is no longer whether Anthropic is big enough to matter — it&rsquo;s whether the capital-light holding-company posture and the Trust governance structure become the global template, or remain a competitive idiosyncrasy that only one lab pulls off.</p><hr><h2 id="whats-different-about-anthropic">What&rsquo;s Different About Anthropic</h2><p>Seven observations that distinguish Anthropic&rsquo;s trajectory from OpenAI&rsquo;s or Google DeepMind&rsquo;s, and which I think the rest of this series will return to:</p><ol><li><p><strong>The cost-per-training-run advantage compounds into a margin profile, not a percentage gap.</strong> 4× less spend per training run over 30 months is not a competitive advantage that markets erode — it&rsquo;s a structural margin difference. By end of 2028, Anthropic&rsquo;s gross margin is 70–80% to OpenAI&rsquo;s 45–55%. The per-dollar economics are incompatible for OpenAI to match without an architectural shift.</p></li><li><p><strong>&ldquo;Rent everywhere terrestrial, pre-buy orbital.&rdquo;</strong> Anthropic does not build a Stargate-equivalent megasite. Instead it contracts with 10+ compute partners on 1–3 year terms (AWS, Google, Oracle, Akamai, SpaceX Colossus, Fluidstack, plus sovereign deals) and pre-buys the orbital tier through the SpaceX partnership. As compute prices fall through 2027–2028, Anthropic&rsquo;s leases re-rate downward at expiration while OpenAI carries the $400B+ owned-infrastructure capex on its balance sheet. By end of 2028, financial press is openly questioning whether Stargate was the right call.</p></li><li><p><strong>The JV-with-PE-partners structure is a capital-light holding-company equivalent.</strong> OpenAI just made the opposite move structurally explicit (DeployCo with $4B from TPG/Goldman/SoftBank, majority-owned subsidiary). Anthropic&rsquo;s May 4 enterprise services JV with Blackstone, H&amp;F, Goldman, GIC, Apollo, Leonard Green, General Atlantic, and Sequoia is the same idea executed differently — Anthropic provides engineering and IP, the LP consortium provides capital and customer access, no majority ownership. By end of 2028 there are 3–4 such JVs, totaling $15–25B in external capital. The royalty/license/equity-warrant economics flow into Anthropic&rsquo;s P&amp;L without consolidating the operational risk. This is the<em>capital-light</em> holding company, in deliberate contrast to OpenAI&rsquo;s<em>capital-heavy</em> one.</p></li><li><p><strong>Trust governance becomes the regulatory template.</strong> The Long-Term Benefit Trust structure earns regulated-industry primacy through 2028 — but more importantly, it becomes the corporate form that regulators worldwide point to as desired for frontier AI. The federal AI law that passes in 2028 implicitly references it. By that point, every other frontier lab has been asked by at least one major regulator to explain why it lacks an Anthropic-equivalent governance structure. This is both a regulatory moat (Anthropic&rsquo;s published rubrics become the standard) and a recruiting moat (researchers preferentially join for the governance form).</p></li><li><p><strong>Continual learning is the load-bearing research bet.</strong> Dreaming, shipped at Code with Claude 2026, is the production manifestation of an architectural bet that AI agents reach human-level continual learning<em>without</em> requiring full retraining cycles. The 6× task completion improvement at Harvey is the proof of concept. If this compounds across 2026–2028, per-customer agent memory stores accumulate value over time. Switching from Claude to GPT requires either retraining all that learned context or accepting a step-down in capability. This is the compounding switching-cost moat the original analysis didn&rsquo;t capture, and it&rsquo;s the structural reason net revenue retention diverges from OpenAI&rsquo;s by end of 2028.</p></li><li><p><strong>No consumer hardware through 2028.</strong> Deliberate. Anthropic does not chase the Jony Ive io device. Instead, in H2 2028 Anthropic ships<em>agent-runtime hardware</em> — a server appliance for running Claude agent fleets locally on enterprise IT, sold through B2B channels for regulated-industry and air-gapped deployments. Same word, totally different product category. The hardware question becomes a quoted strategic divergence in tech press, not a tactical lag.</p></li><li><p><strong>Stays smaller, more researcher-productive, deliberately.</strong> Anthropic exits 2028 at 5,500–6,500 employees against OpenAI&rsquo;s 12,000–15,000. Revenue per employee crosses $45–50M+, unprecedented for a software company at scale. The internal use of Claude agents (Dreaming-enabled, customer-specific memory equivalents for internal workflows) compounds researcher productivity faster than headcount grows. Bus-factor risk becomes a recognized story in IPO disclosures, but per-researcher productivity is the dominant fact in earnings calls.</p></li></ol><hr><h2 id="whats-next">What&rsquo;s Next</h2><p>The next post in this series covers Meta — the open-weight Llama strategy, the Reality Labs convergence with FAIR, the Connect conference cadence in September, and the EU regulatory headwinds. After that: the Chinese frontier (DeepSeek, Zhipu, Moonshot, Qwen, and the SOE consolidation question), which most directly tests the bifurcation thesis above.</p><p>Sources for the baseline data in this post:<a href="https://www.anthropic.com/news/enterprise-ai-services-company">Anthropic-Blackstone-H&amp;F-Goldman enterprise services firm (Anthropic)</a>,<a href="https://www.cnbc.com/2026/05/04/anthropic-goldman-blackstone-ai-venture.html">Anthropic + Wall Street giants $1.5B JV (CNBC)</a>,<a href="https://venturebeat.com/technology/anthropic-introduces-dreaming-a-system-that-lets-ai-agents-learn-from-their-own-mistakes">Code with Claude 2026 — Dreaming/Outcomes (VentureBeat)</a>,<a href="https://www.cnbc.com/2026/05/06/anthropic-spacex-data-center-capacity.html">SpaceX-Anthropic Colossus 1 deal (CNBC)</a>,<a href="https://www.bloomberg.com/news/articles/2026-05-08/anthropic-inks-1-8-billion-computing-deal-with-akamai">Anthropic-Akamai $1.8B compute deal (Bloomberg)</a>,<a href="https://www.bloomberg.com/news/articles/2026-05-12/anthropic-in-talks-to-raise-30-billion-at-900-billion-valuation">Anthropic $30B raise at $900B valuation (Bloomberg)</a>,<a href="https://fortune.com/2026/05/05/anthropic-wall-street-financial-services-agents-jamie-dimon/">Anthropic Wall Street financial services agents (Fortune)</a>,<a href="https://www.saastr.com/anthropic-just-passed-openai-in-revenue-while-spending-4x-less-to-train-their-models/">Anthropic just passed OpenAI in revenue (SaaStr)</a>,<a href="https://spacenews.com/anthropic-to-consider-using-spacex-orbital-data-center-satellites/">Anthropic to consider SpaceX orbital data center satellites (SpaceNews)</a>,<a href="https://simonwillison.net/2026/May/7/xai-anthropic/">Notes on the xAI/Anthropic data center deal (Simon Willison)</a>,<a href="https://www.anthropic.com/news">Claude Platform on AWS (Anthropic)</a>,<a href="https://x.ai/news/anthropic-compute-partnership">New Compute Partnership with Anthropic (xAI)</a>.</p>
]]></content:encoded></item><item><title>wisp - Running WebAssembly Under containerd</title><link>https://mtclinton.com/posts/wisp/</link><pubDate>Tue, 12 May 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/wisp/</guid><category>code</category><description>A containerd shim is, in the usual case, an undramatic piece of software. It receives a few RPC calls from containerd, forks a Linux process to run the container&rsquo;s workload, reports the exit code back, and ends. wisp is one of these, and it does not fork. When containerd asks it to start a container under the io.containerd.wisp.v1 runtime, the shim loads the image&rsquo;s payload as a WebAssembly module and runs it inside a Wasmtime instance. From containerd&rsquo;s point of view there is another runtime on the host, alongside runc and runsc, doing the same offices for image pull, lifecycle, and stdio. From the workload&rsquo;s point of view there is no Linux at all — no syscalls, no kernel, no namespaces — only a WASM guest and the small set of WASI bindings it is permitted to touch.</description><content:encoded>&lt;![CDATA[<p>A containerd shim is, in the usual case, an undramatic piece of software. It receives a few RPC calls from containerd, forks a Linux process to run the container&rsquo;s workload, reports the exit code back, and ends.<a href="https://github.com/mtclinton/wisp">wisp</a> is one of these, and it does not fork. When containerd asks it to start a container under the<code>io.containerd.wisp.v1</code> runtime, the shim loads the image&rsquo;s payload as a WebAssembly module and runs it inside a Wasmtime instance. From containerd&rsquo;s point of view there is another runtime on the host, alongside<code>runc</code> and<code>runsc</code>, doing the same offices for image pull, lifecycle, and stdio. From the workload&rsquo;s point of view there is no Linux at all — no syscalls, no kernel, no namespaces — only a WASM guest and the small set of WASI bindings it is permitted to touch.</p><p>This is the fifth in a series of small sandboxes I have been writing on this blog, and the question it pulls on is the same question each previous entry has pulled on, which is where the right place to draw the isolation boundary lives.<em>ironbox</em> drew it at the kernel — namespaces and cgroups, in the manner of every Linux container of the past decade. The gVisor cluster —<em>mini-sentry</em>,<em>a tour of the gVisor front</em>,<em>hijacking signals in Go</em>,<em>running what one did not write</em> — drew it at the syscall, every guest call intercepted and emulated in userspace.<em>A microVM small enough to read</em> drew it at the CPU, with a second kernel under KVM and hardware-enforced separation.<em>The quieter sandbox</em> tightened the syscall boundary without changing where it was. wisp is the fifth answer, and it is the strangest of the five. It draws the boundary by removing one side of it.</p><p>The argument is structural rather than enforced. A Linux container draws a line and asks the kernel to keep the contents on the inside of it; a userspace kernel intercepts the line and emulates what should have happened on the other side; a microVM gives the guest its own kernel and asks the hardware to keep the two apart. wisp does none of these things. There is no kernel inside a WASM guest because WASM is not a kernel-oriented machine — it is a stack machine with linear memory, deterministic semantics, and no concept of syscalls. A guest cannot escape what is not there. What follows is an account of what I encountered while wiring this up against real containerd, which was kinder to me in some respects than I had expected and decidedly less kind in others.</p><h2 id="the-shim-and-the-module">The Shim and the Module</h2><p>containerd&rsquo;s shim v2 ABI is a small protocol with surprisingly many corners. The shim is a binary; containerd invokes it once with a<code>start</code> subcommand to spawn the long-running server, then connects to it over a Unix socket and sends TTRPC calls for the rest of the container&rsquo;s life. The calls are the ones one would expect —<code>Create</code>,<code>Start</code>,<code>State</code>,<code>Wait</code>,<code>Kill</code>,<code>Delete</code>,<code>Shutdown</code>, plus a handful of others that are less obvious until they catch you out. Each running container has its own shim process (the &ldquo;shim-per-container&rdquo; model, which replaced the older &ldquo;shim-per-task&rdquo;). The shim&rsquo;s job is to translate these calls into whatever the underlying runtime can act on —<code>runc</code> invocations for a Linux container,<code>runsc</code> for a gVisor sandbox, and, in our case, a Wasmtime instance.</p><p>Wasmtime, for its part, takes module bytes, an WASI context (env vars, args, preopened files, stdio), and a function name; instantiates the module; calls the function; and returns either a clean exit, a trap, or a host-side error. A<code>proc_exit(n)</code> from inside the guest surfaces as a particular kind of trap that the host can downcast and read<code>n</code> from. A division by zero, an out-of-bounds load, or an<code>unreachable</code> instruction surfaces as a different sort of trap. All of these have to be made to look like containerd&rsquo;s<code>(exit_code, exited_at)</code> shape, and the shim is the gearbox in which the two vocabularies are reconciled.</p><p>I wrote the shim against<code>containerd-shim</code> 0.11 (the Rust crate from the runwasi project) and<code>wasmtime</code> 44. The trait surface for an engine is small enough to read:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">pub</span><span class="w"/><span class="k">trait</span><span class="w"/><span class="n">WasmEngine</span>:<span class="nb">Send</span><span class="o">+</span><span class="w"/><span class="nb">Sync</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">fn</span><span class="nf">create</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"/><span class="n">cfg</span>:<span class="kp">&amp;</span><span class="nc">ContainerConfig</span><span class="p">)</span><span class="w"/>-&gt;<span class="nb">Result</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="p">;</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">fn</span><span class="nf">start</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"/>-&gt;<span class="nb">Result</span><span class="o">&lt;</span><span class="p">()</span><span class="o">&gt;</span><span class="p">;</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">fn</span><span class="nf">wait</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"/><span class="n">timeout</span>:<span class="nb">Option</span><span class="o">&lt;</span><span class="n">Duration</span><span class="o">&gt;</span><span class="p">)</span><span class="w"/>-&gt;<span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Option</span><span class="o">&lt;</span><span class="n">ExitStatus</span><span class="o">&gt;&gt;</span><span class="p">;</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">fn</span><span class="nf">kill</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"/>-&gt;<span class="nb">Result</span><span class="o">&lt;</span><span class="nb">Option</span><span class="o">&lt;</span><span class="n">ExitStatus</span><span class="o">&gt;&gt;</span><span class="p">;</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>The first implementation,<code>NoopEngine</code>, sleeps for five seconds and reports exit 0. The second,<code>WasmtimeEngine</code>, actually runs the guest. Both live behind the same trait so the shim does not know which one it has. The exit-code convention I settled on, after a small skirmish over what to do with traps:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">guest behaviour exit code</span></span><span class="line"><span class="cl">─────────────────────────────────────────────────</span></span><span class="line"><span class="cl">_start returns cleanly 0</span></span><span class="line"><span class="cl">proc_exit(n) (downcast I32Exit) n</span></span><span class="line"><span class="cl">trap (OOB, div0, unreachable, …) 1</span></span><span class="line"><span class="cl">epoch interruption from kill() 137</span></span></code></pre></div></div></figure><p>The last row is the interesting one. WASM has no signals; &ldquo;kill&rdquo; inside a Wasmtime instance does not mean what it means in Linux. The mechanism Wasmtime provides for it is the<em>epoch interruption</em> — the engine carries a counter, each store can ask the engine to trap when the counter advances past a deadline, and<code>Engine::increment_epoch()</code> is the only way to make that deadline pass. I arm the deadline at 1 on store creation, never advance it under normal execution, and call<code>increment_epoch()</code> from<code>kill</code>. The guest sees a trap whose ultimate cause is, simply, that I asked. The run thread then post-processes: if the engine was killed and the natural exit code would have been 1 (since an epoch trap looks like any other trap), rewrite it to 137. The matrix stays tidy and the implementation does not leak through the trap path.</p><p>That is enough plumbing to run a hand-rolled<code>(module (func (export "_start") (i32.const 0) (drop)))</code> to clean exit and to interrupt an infinite-loop module in under five seconds. The unit tests passed. I was, for a pleasant interval, under the impression that the project was most of the way done.</p><h2 id="hello-containerd">Hello, Containerd</h2><p>The integration test of any containerd runtime is<code>ctr run</code>. I installed the binary at<code>/usr/local/bin/containerd-shim-wisp-v1</code> (the name containerd expects, derived from the runtime ID by transposing the dots and stripping the version suffix into a<code>-vN</code> tag), built a hello-world WASM module by writing a five-line Rust crate that did<code>println!("hello")</code> and compiling it for the<code>wasm32-wasip1</code> target, and packaged the result as an OCI image archive — a tar containing<code>oci-layout</code>, an<code>index.json</code>, and a<code>blobs/sha256/...</code> tree referenced by the index. The archive&rsquo;s manifest declared<code>os=wasi</code>,<code>architecture=wasm</code>. I ran:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ctr -n default image import /tmp/wisp-hello.tar</span></span><span class="line"><span class="cl">sudo ctr -n default run --rm<span class="se">\</span></span></span><span class="line"><span class="cl"> --runtime io.containerd.wisp.v1<span class="se">\</span></span></span><span class="line"><span class="cl"> wisp.local/hello-wasm:latest hello</span></span></code></pre></div></div></figure><p>The result was a curt, definite error:<code>ctr: image not found</code>. The image had imported without complaint and then immediately not been there. This is a class of bug that announces itself as a mistake and then refuses to identify which one. I checked the manifest with<code>ctr image ls</code>; the entry was gone. I re-imported with<code>-v</code>; the verbose output mentioned<code>image might be filtered out</code> somewhere in the middle of the dump, in a sentence that did not bother to be alarming.<code>ctr image import</code> filters by host platform by default, and a<code>linux/amd64</code> host does not, on inspection, recognise itself in a<code>wasi/wasm</code> manifest.<code>--all-platforms</code> is the flag, and once added the image stayed. This was the first lesson in what would shortly become a longer one: the well-trodden parts of the containerd toolchain make assumptions about what a container looks like, and a sandbox by absence violates a great many of them.</p><p>The image now in place, the next<code>ctr run</code> produced<code>failed to create TTRPC connection: unsupported protocol</code>. This was less encouraging than<code>not found</code> and, as it turned out, the beginning of an afternoon.</p><h2 id="the-two-errors-that-were-one">The Two Errors That Were One</h2><p>The next thing one learns about a containerd shim is that the<code>start</code> subcommand has an unusual contract. containerd invokes the shim binary with a set of flags and the subcommand<code>start</code>; the shim is expected to fork a long-running server, bind a Unix socket, and<strong>print the socket&rsquo;s address on stdout</strong>. containerd parses this address out of the shim&rsquo;s stdout, connects to it, and uses that connection for every subsequent RPC. The protocol is human-readable: a single line,<code>unix:///run/containerd/s/&lt;hash&gt;</code>, with no preamble and no postamble. If anything else lands in containerd&rsquo;s reader before the address, the URL parses as something else, and the connection fails.</p><p>In containerd 2.x, the shim&rsquo;s stderr is wired into the same reader as its stdout during this lifecycle invocation. I do not know whether this is intentional or whether the abstraction has merely loosened over time; I know only that any byte I write to fd 2 during<code>start</code> mode lands in the buffer containerd is parsing for the URL. The first thing I had written into<code>main</code> was a call to<code>env_logger::Builder::from_env(...).init()</code>. The diagnostic logs that initialisation produced, helpful in development, lodged themselves above the address line in the buffer containerd read, and the address-parser confronted something like<code>[INFO wisp] invoked as io.containerd.wisp.v1: ...\nunix:///run/containerd/s/abc123</code>. The parser took the first thing that looked URL-shaped, which was not a URL, and called the result<code>unsupported protocol</code>.</p><p>I removed the env_logger init, anticipating success. The next<code>ctr run</code> produced a different error:<code>dial unix /run/containerd/s/&lt;hash&gt;: connect: no such file or directory</code>. The address was now correct, but the socket on the other end had ceased to exist. This was the second of the two errors, and it had the same cause as the first one wearing a different costume.</p><p>Server mode — the long-running TTRPC mode the shim enters after<code>start</code> — has its own log infrastructure. The<code>containerd-shim</code> crate&rsquo;s bootstrap routine calls<code>containerd_shim::logger::init</code>, which does<code>log::set_boxed_logger</code> against a writer wired to containerd&rsquo;s per-container log FIFO. The<code>log</code> crate enforces that<code>set_boxed_logger</code> may be called at most once per process. If env_logger had won the race (because I called it from<code>main</code>, before the crate&rsquo;s bootstrap), the crate&rsquo;s init returned<code>SetLoggerError</code>, bootstrap returned<code>Err</code> to the shim binary, the child died before binding its socket, and<code>ctr</code> was left dialling a path that never existed. The two errors looked nothing alike at the failure site. They were, mechanically, the same error twice.</p><p>The fix was three lines, which I append here with the apology one is obliged to make to a reader who has just been asked to follow three pages of diagnosis for them:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="c1">// Don't call env_logger::init here. containerd 2.x merges stderr</span></span></span><span class="line"><span class="cl"><span class="c1">// into stdout during `start` (corrupts the address), and in server</span></span></span><span class="line"><span class="cl"><span class="c1">// mode the containerd-shim crate's logger::init fights us over</span></span></span><span class="line"><span class="cl"><span class="c1">// log::set_boxed_logger (bootstrap fails before binding).</span></span></span><span class="line"><span class="cl"><span class="c1">// Let the crate own logging.</span></span></span><span class="line"><span class="cl"><span class="n">shim</span>::<span class="n">run</span>::<span class="o">&lt;</span><span class="n">WispShim</span><span class="o">&gt;</span><span class="p">(</span><span class="no">RUNTIME_ID</span><span class="p">,</span><span class="w"/><span class="nb">None</span><span class="p">).</span><span class="k">await</span></span></span></code></pre></div></div></figure><p>I keep the clap CLI struct that parses the wire surface as runnable documentation — when the post asks &ldquo;what does containerd actually send a shim binary?&rdquo; the answer is right there in<code>Cli</code> — but I do not call it. The struct is exercised from unit tests so it cannot rot. The behaviour of<code>main</code> is to hand off and stay silent. There is, one is obliged to concede, a small comedy in the discovery that the bug was that I had been<em>too loud</em>.</p><h2 id="the-method-i-did-not-implement">The Method I Did Not Implement</h2><p>The next run produced<code>Connect is not supported</code>, and aborted before the WASM guest had a chance to run. This was a different sort of error from the previous two — not a wiring fault but a missing method.</p><p>The<code>Task</code> trait in<code>containerd-shim</code> 0.11 has a default implementation for every method that returns<code>Error::Unimplemented</code>. The intent is sensible: a shim need only implement the methods it uses, and the rest will produce a polite &ldquo;not supported&rdquo; rather than a crash. The catch is that<code>ctr run</code> calls<code>Task::connect</code> immediately after<code>Start</code> — to attach to the task&rsquo;s stdio before it begins producing output. If the default returns<code>Unimplemented</code>, the run aborts at the precise moment the guest is about to print something.</p><p>A<code>Task::connect</code> implementation in wisp does nothing surprising:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">async</span><span class="w"/><span class="k">fn</span><span class="nf">connect</span><span class="p">(</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">_ctx</span>:<span class="kp">&amp;</span><span class="nc">TtrpcContext</span><span class="p">,</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">_req</span>:<span class="nc">api</span>::<span class="n">ConnectRequest</span><span class="p">,</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">)</span><span class="w"/>-&gt;<span class="nc">TtrpcResult</span><span class="o">&lt;</span><span class="n">api</span>::<span class="n">ConnectResponse</span><span class="o">&gt;</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="kd">let</span><span class="w"/><span class="k">mut</span><span class="w"/><span class="n">resp</span><span class="w"/><span class="o">=</span><span class="w"/><span class="n">api</span>::<span class="n">ConnectResponse</span>::<span class="n">default</span><span class="p">();</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">resp</span><span class="p">.</span><span class="n">shim_pid</span><span class="w"/><span class="o">=</span><span class="w"/><span class="n">std</span>::<span class="n">process</span>::<span class="n">id</span><span class="p">();</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">resp</span><span class="p">.</span><span class="n">task_pid</span><span class="w"/><span class="o">=</span><span class="w"/><span class="n">std</span>::<span class="n">process</span>::<span class="n">id</span><span class="p">();</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">resp</span><span class="p">.</span><span class="n">version</span><span class="w"/><span class="o">=</span><span class="w"/><span class="s">"wisp"</span><span class="p">.</span><span class="n">to_string</span><span class="p">();</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nb">Ok</span><span class="p">(</span><span class="n">resp</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>There is exactly one process — the shim itself — and the WASM guest does not have a PID in any sense Linux would recognise. Returning the shim&rsquo;s own PID for both fields is the convention runwasi uses, and it is what tools that ask about the task&rsquo;s PID will get. The educational moment here, if there is one, is that<em>defaults are a polite ambush</em>. The Rust type system would not have let me forget to implement a method whose default was<code>Unimplemented!()</code>. The trait&rsquo;s default of<code>Err(Unimplemented)</code> is more humane and less safe. Anywhere a library hands one a trait with default<code>Err</code> implementations, one had better look up which methods are actually called in the happy path.</p><h2 id="the-rootfs-one-mounts-oneself">The Rootfs One Mounts Oneself</h2><p>The shim now spoke the protocol. The next<code>ctr run</code> reached the WasmtimeEngine and asked it to load<code>module.wasm</code> from the rootfs path the shim had received in the<code>CreateTaskRequest</code>. The path was<code>/run/containerd/io.containerd.runtime.v2.task/default/hello/rootfs</code>. It was empty.</p><p>In containerd 1.x the rootfs at<code>&lt;bundle&gt;/rootfs/</code> was prepared by containerd itself: snapshots were mounted, layers were unpacked, the path was an actual directory the shim could<code>open()</code> into. In containerd 2.x this convention was relaxed. The<code>CreateTaskRequest</code> now carries a<code>Vec&lt;Mount&gt;</code> and the shim is expected to either run<code>mount(2)</code> for each mount itself or read directly from the snapshot&rsquo;s underlying source. The change is a sensible bit of decoupling — different runtimes want different views of the layers — but it caught me out, because every example I had read assumed the older shape.</p><p>The cleanest answer would have been to call<code>nix::mount::mount</code> over the overlay specification containerd sent. I did not do this, not yet. I shortcut: containerd&rsquo;s overlay mount carries a<code>lowerdir=</code> option in its mount options string, and the layer containing<code>module.wasm</code> is, for a single-layer WASM image, the only entry in<code>lowerdir</code>. So<code>resolve_rootfs</code> parsed the options string, fished out the lowerdir, and read<code>module.wasm</code> straight from there. The proper mount handling would in due course replace this — it does, in the version of the repo a reader visits today — but the shortcut was sufficient to get the next<code>ctr run</code> to find the module, and the rest of the matrix wanted writing more than the rootfs assembly wanted polishing.</p><p>The point worth taking from this section, and from the previous two, is one I should like to leave plainly: a sandbox runtime is mostly<em>not</em> sandbox code. It is glue. The Wasmtime side of wisp — the part that runs the WebAssembly — is a small, tidy module that calls perhaps eight Wasmtime functions and has 200 lines of code. The containerd side is more than four times the size, and almost all of the bugs lived in it. The interesting intellectual content of the project is in the engine; the interesting practical content is in the gearbox.</p><h2 id="hello">Hello</h2><p>After the rootfs change, the next<code>ctr run</code> produced this:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sudo ctr -n default run --rm \</span></span><span class="line"><span class="cl"> --runtime io.containerd.wisp.v1 \</span></span><span class="line"><span class="cl"> wisp.local/hello-wasm:latest hello</span></span><span class="line"><span class="cl">hello</span></span><span class="line"><span class="cl">$</span></span></code></pre></div></div></figure><p>A WebAssembly module compiled from five lines of Rust, packaged as an OCI image, pulled by containerd, handed to a shim that does not fork, run inside a Wasmtime instance that has no concept of Linux, with its stdout wired through a FIFO that containerd attached to<code>ctr</code>&rsquo;s terminal. Five distinct subsystems agreeing for a moment to produce one word.</p><p>I will spare the reader an account of the smaller surprises that followed — the snapshot leftovers from a half-failed previous run that had to be cleaned up by hand, the moment I confused container name with image tag and chased the wrong error for fifteen minutes — and note only that the integration test, having been written to be unflattering, was unflattering precisely until it was not.</p><h2 id="after-the-hello-the-matrix">After the Hello: The Matrix</h2><p>The single hello on stdout proved the wiring; the next several days proved the wiring carried weight. Each cell of the exit-code matrix wanted its own probe — a WASM module that would trigger that particular outcome and let me observe what containerd reported. I rewrote the hello-world crate as a multi-mode probe: a single binary whose first argument selected what to do next.<code>proc_exit 42</code> would call WASI&rsquo;s<code>proc_exit(42)</code> and let me check that<code>ctr</code> reported 42.<code>trap</code> would deliberately trap.<code>loop</code> would spin forever and let me kill it from another shell.<code>print-stderr</code> would write to fd 2;<code>read-stdin</code> would echo a line.</p><p>Each cell taught me something. The three worth recording here are the ones whose lessons were not specific to wisp.</p><p>The first was a question of where the probe found its mode. The OCI image&rsquo;s<code>Entrypoint</code> was set to<code>/module.wasm</code>, and I had assumed<code>ctr run --runtime io.containerd.wisp.v1 wisp.local/probe:latest myname trap</code> would hand the guest an argv consisting of<code>["/module.wasm", "trap"]</code> — the entrypoint preserved at<code>argv[0]</code>, my appended argument at<code>argv[1]</code>. So the probe read its mode from<code>args.get(1)</code>. Every mode I selected, the probe ran the default — it printed<code>hello</code>. This persisted, with mounting indignity on my part, through several careful rebuilds. The behaviour<code>ctr run</code> actually implements is<em>total replacement</em>: the trailing arguments overwrite the OCI Entrypoint+Cmd entirely rather than being appended to it. The guest&rsquo;s argv was<code>["myname", "trap"]</code>, with my container name in<code>args[0]</code> and the mode I had asked for in<code>args[1]</code> — but the probe, expecting the entrypoint to have survived, was reading the container name and treating it as a mode it did not recognise. Reading from<code>args.first()</code> instead of<code>args.get(1)</code> was a one-character fix. The fifteen minutes I had spent hunting for a bug in the WASI argv plumbing was an honest tax on the assumption that<code>ctr</code> worked the way<code>docker</code> works.</p><p>The second was the trap cell, and it deserves its own paragraphs because it is the most instructive of the matrix bugs. The probe&rsquo;s trap mode looked like this:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="s">"trap"</span><span class="w"/><span class="o">=&gt;</span><span class="w"/><span class="k">unsafe</span><span class="w"/><span class="p">{</span><span class="w"/><span class="n">std</span>::<span class="n">hint</span>::<span class="n">unreachable_unchecked</span><span class="p">()</span><span class="w"/><span class="p">},</span></span></span></code></pre></div></div></figure><p><code>unreachable_unchecked</code> is the Rust standard library&rsquo;s way of telling the compiler that a code path will never execute. It is<code>unsafe</code> because if the path<em>does</em> execute, the program is in undefined behaviour territory. In a debug build it lowers to a panic; in a release build it lowers to whatever the compiler decides is most useful, which on most targets is some sort of trap instruction. I was building release with link-time optimisation enabled, expected an<code>unreachable</code> opcode in the WASM, and a<code>Trap::UnreachableCodeReached</code> from Wasmtime when the guest ran. What I got was<code>hello</code>.</p><p>The compiler had read the hint with more attention than I had paid to it.<code>unreachable_unchecked</code> is not an instruction; it is a<em>promise</em> to the optimiser — the promise that the call will never be reached. The link-time optimisation pass took me at my word, proved the arm containing the trap was dead code (because no caller could reach it without violating my own promise), and dead-code-eliminated the entire arm. The probe&rsquo;s match statement now had no<code>"trap"</code> case at all; it fell through to the default arm, which printed<code>hello</code>. The trap was not absent because of a Wasmtime bug. It was absent because I had told the compiler not to emit it, and the compiler had believed me.</p><p>The fix was to switch from a UB-hint to an actual instruction:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="s">"trap"</span><span class="w"/><span class="o">=&gt;</span><span class="w"/><span class="n">core</span>::<span class="n">arch</span>::<span class="n">wasm32</span>::<span class="n">unreachable</span><span class="p">(),</span></span></span></code></pre></div></div></figure><p><code>core::arch::wasm32::unreachable</code> lowers to a real<code>unreachable</code> opcode in the emitted WASM, regardless of optimisation level. The compiler does not have an opportunity to optimise it away because there is nothing to optimise — it is the instruction itself, embedded in the binary. The trap mode now traps, Wasmtime reports<code>Trap::UnreachableCodeReached</code>, the engine maps it to exit 1,<code>ctr</code> reports 1. The cell works. There is a parallel here to the signals post&rsquo;s<code>ABIInternal</code> wrapper, and it is worth naming. In both cases the compiler did something kind that turned out to be the bug. The Go toolchain wrapped my signal handler&rsquo;s entry point in a frame-management prologue I had not written; Rust&rsquo;s optimiser took my<code>unreachable_unchecked</code> hint as the gospel it had been advertised as. Anywhere the host language meets a low-level contract — signal entry, syscall trampolines, FFI, the WASM ABI — one must assume that the compiler is doing something helpful, and that one will sooner or later have to undo it.</p><p>The third was the kill cell, and its lesson concerns Wasmtime&rsquo;s epoch interruption mechanism more specifically. I needed a probe that ran an unbounded loop, so a separate shell could<code>ctr task kill</code> it and I could verify the engine produced exit 137. The simplest such loop is an empty one:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="s">"loop"</span><span class="w"/><span class="o">=&gt;</span><span class="w"/><span class="k">loop</span><span class="w"/><span class="p">{</span><span class="w"/><span class="n">std</span>::<span class="n">hint</span>::<span class="n">black_box</span><span class="p">(());</span><span class="w"/><span class="p">},</span></span></span></code></pre></div></div></figure><p><code>black_box</code> exists to defeat optimisations that would otherwise eliminate the loop body. With it, the loop body is a no-op the optimiser cannot prove away, and the loop itself remains in the emitted WASM. I built the probe, ran it, killed it from another shell, and observed that the entire host went still.<code>ctr task delete</code> blocked, the shell that issued the kill stopped responding, and Ctrl-C produced no result because the shell was waiting on an RPC that was waiting on a<code>wait</code> that was waiting on a guest that was not going to exit. The mechanism I had relied on — Wasmtime&rsquo;s epoch interruption — does not work uniformly on every loop a WASM module might contain. The epoch pass instruments certain back-edges in the control-flow graph with a check against the engine&rsquo;s epoch counter; the empty<code>loop { black_box(()) }</code> produces a particular shape of WASM loop whose back-edge the pass does not instrument. The guest spun, the engine&rsquo;s<code>increment_epoch()</code> did exactly what it was supposed to do, and nothing trapped because nothing was watching for the trap. The whole host hung on a single uninterruptible<code>loop</code> opcode. Giving the loop body a counter increment —<code>loop { i = i.wrapping_add(1); std::hint::black_box(i); }</code> — produces a back-edge the epoch pass does instrument, and the kill cell works. There is, one is obliged to concede, a small horror in having pinned an entire Linux box on a<code>loop {}</code>, even temporarily. It is the kind of thing one writes a careful comment about and never forgets.</p><h2 id="where-wisp-sits-and-what-it-removes">Where wisp Sits, and What It Removes</h2><p>The five sandboxes I have built on this blog form a small library on a single question. It is worth saying plainly what each of them answers.</p><p><em>ironbox</em> draws the boundary at the<strong>kernel</strong>. The container shares the host kernel with everything else on the box; isolation is enforced by namespaces (the kernel pretends each container has its own PID space, network, mount namespace, and so on) and by cgroups (the kernel meters each container&rsquo;s resource use). Every syscall the container makes is a real syscall against the real kernel. A kernel exploit inside, say,<code>setsockopt</code> is a problem for every container on the box, because every container is using the same<code>setsockopt</code>.</p><p>The gVisor cluster —<em>mini-sentry</em>, the<em>tour of the gVisor front</em>, the<em>signals notes</em>, the<em>running what one did not write</em> essay — draws the boundary at the<strong>syscall</strong>. The guest&rsquo;s syscalls are intercepted in userspace (by<code>ptrace</code> or seccomp-unotify) and emulated by a userspace kernel rather than reaching the host kernel. A kernel exploit in<code>setsockopt</code> is no longer a problem, because the host kernel is no longer running<code>setsockopt</code> — my Go code is. The trade-off is that the userspace kernel is now a non-trivial piece of software with its own bugs.</p><p><em>A microVM small enough to read</em> draws the boundary at the<strong>CPU</strong>. The guest runs in its own kernel inside a KVM virtual machine; the host kernel never touches the guest&rsquo;s syscalls because the host kernel is on the other side of a hardware-enforced separation. The trade-off is the price of the second kernel, in memory and boot time, and the need to keep both kernels patched.</p><p><em>The quieter sandbox</em> does not change where the boundary is; it makes the existing boundary smaller. Observation-driven seccomp profiles produce a tighter syscall allowlist than any human will write by hand. The boundary is still at the syscall, where ironbox put it; what has changed is its area.</p><p>wisp does not draw a boundary. The WASM guest has no syscalls because WASM is not a syscall-oriented machine. The instructions it executes are stack manipulations, memory loads against its linear memory, and calls to host-provided functions whose signatures are declared in advance. There is no<code>setsockopt</code> to intercept and no<code>setsockopt</code> to delegate; if a guest wants something the host has not declared a function for, the guest cannot ask for it. The isolation is structural — it inheres in the shape of the language — and not enforced by anyone in particular.</p><p>This is a different kind of safety property from any of the four above. ironbox&rsquo;s safety depends on the kernel being correct. mini-sentry&rsquo;s depends on the userspace kernel being correct. The microVM&rsquo;s depends on the hardware and the host kernel being correct. wisp&rsquo;s depends on Wasmtime correctly executing WASM bytecode — which is a smaller claim, against a smaller target, with a smaller attack surface. It is also a<em>more restrictive</em> kind of safety, because most existing software cannot be run inside a WASM guest at all; it must be compiled to a target that does not assume the existence of an operating system. There is no free lunch here. wisp removes a class of attacks by removing the surface they would have run against, and removes a great deal of useful software along with the attacks.</p><h2 id="what-i-actually-learned">What I Actually Learned</h2><p>Three things seem to me worth writing down.</p><p>The first is that a runtime is mostly its gearbox. The Wasmtime portion of wisp, which is the part that actually executes WebAssembly, is short and tidy and untroubled. The containerd portion, which is the part that translates between containerd&rsquo;s vocabulary and the engine&rsquo;s, is four times the size and contained every bug in this account. When one sets out to write a runtime, one is, in practice, signing up to write a translation layer between two existing pieces of software. The novelty of the runtime is in the engine; the cost of the runtime is in the gearbox. This pattern is, I suspect, general.</p><p>The second is that one&rsquo;s tools ambush quietly. The<code>Task::connect</code> method in<code>containerd-shim</code> came with a default that returned<code>Unimplemented</code>; the consequence was that<code>ctr run</code> aborted at the precise moment my code was about to produce output. Rust&rsquo;s optimiser, given a<code>std::hint::unreachable_unchecked()</code> in a release build with link-time optimisation enabled, dead-code-eliminated the entire arm of a match that called it — because the hint had promised the call would never be reached — and the symptom was that the trap cell of my probe printed<code>hello</code> instead of trapping. Both ambushes shared a shape: a piece of the language&rsquo;s surrounding machinery, a default trait method or a compiler optimisation pass, was doing something polite and reasonable that turned out, at exactly the wrong site, to be the bug. Anywhere the language hands one a contract whose breach is a courtesy rather than a panic, one had better look up which of those courtesies will obtain in the happy path of one&rsquo;s code.</p><p>The third is the structural one, and it is the most important of the three. There are five places to draw an isolation boundary — the kernel, the syscall, the hardware, the syscall-tightened-by-observation, and the ABI-by-absence — and one chooses among them before one chooses anything else. Each choice has a cost the other choices do not have. ironbox&rsquo;s cost is sharing a kernel. mini-sentry&rsquo;s cost is implementing one. The microVM&rsquo;s cost is running two of them. The quieter sandbox&rsquo;s cost is the observation pass that comes before the policy. wisp&rsquo;s cost is that most existing software cannot run inside it. The right question, faced with a real workload, is not which sandbox is<em>best</em> but which cost one would rather pay. The five posts taken together are an attempt to make the choices visible in the same room, side by side, so the question can be asked properly.</p><p>The source is at<a href="https://github.com/mtclinton/wisp">github.com/mtclinton/wisp</a>. The shim&rsquo;s TTRPC service lives in<a href="https://github.com/mtclinton/wisp/blob/main/src/shim.rs"><code>src/shim.rs</code></a>; the Wasmtime engine in<a href="https://github.com/mtclinton/wisp/blob/main/src/wasmtime_engine.rs"><code>src/wasmtime_engine.rs</code></a>; the smoke procedure for<code>ctr run</code> against the full exit-code matrix, along with the hard-won lessons recorded as they were discovered, in<a href="https://github.com/mtclinton/wisp/blob/main/TESTING.md"><code>TESTING.md</code></a>. For the architectural prelude — the question the series has been working on — see<em>ironbox</em> and the gVisor cluster linked above.</p>
]]></content:encoded></item><item><title>The Forecast</title><link>https://mtclinton.com/posts/the-forecast/</link><pubDate>Sun, 10 May 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-forecast/</guid><category>writing</category><description>A man inherits an instrument that prints the day to come, and finds out what a day is worth once it has been read.</description><content:encoded>&lt;![CDATA[<figure class="post-audio" style="margin:1.75rem 0;padding:0.9rem 1.1rem;border:1px solid currentColor;border-radius:6px;"><figcaption style="font-size:0.72rem;letter-spacing:0.1em;text-transform:uppercase;margin-bottom:0.55rem;opacity:0.65;">Audio reading — narrated by Julian</figcaption><audio controls= preload="none" style="width:100%;display:block;"><source src="/audio/the-forecast.mp3" type="audio/mpeg"><a href="/audio/the-forecast.mp3">Download the audio reading</a></audio></figure><p>I have known Edmund Carraway the better part of thirty years, and in all that time I never knew him to be late, to be startled, or to be wrong about a small thing. It was a quality I once admired in him without reservation, and it is only now, with the whole of his case laid out before me, that I understand admiration to have been a poor and incurious response. A man so composed is not a man who has mastered his circumstances. He is a man to whom circumstances no longer happen. The distinction took me the greater part of those thirty years to arrive at, and I arrived at it too late to be of any use to him; but I set it down here, in the order in which I came to it, because Carraway asked me to, and because a thing of this kind ought not to go unrecorded merely on the grounds that no one will believe it.</p><p>He came into the instrument, as he came into most of what he owned, by way of an inheritance. His uncle on the maternal side—a Mr. Aldous Penge, of whom the family spoke seldom and never warmly—had been a maker of barometers and chronometers in a small way of business off the Tottenham Court Road, a man of exact habits and no friends, who died without a will and without, so far as anyone could discover, a single regret. The contents of his rooms were divided among such relatives as could be found, and Carraway, being the only one who would trouble himself to go and look, was permitted to take what he liked. He took a quantity of books, a good clock, and a thing he could not at first identify: a mahogany case, about the size of a writing-desk&rsquo;s drawer, fitted with a glass face, a brass aperture along its lower edge, and an arrangement of springs and escapements within that suggested clockwork put to some purpose other than the telling of time.</p><p>There was a card gummed to the underside of the lid, in Penge&rsquo;s small upright hand. It said only:<em>Wind at night. Read in the morning. Do not come to depend upon it.</em></p><p>Carraway, who told me all of this himself, and told it slowly, said that he had read the third sentence as the kind of thing a solitary old man writes to give his possessions an air of consequence. He wound the instrument that night, in the manner the mechanism plainly invited, and thought no more about it. In the morning he found, projecting an inch from the brass aperture, a slip of paper perhaps two inches wide, covered on both faces in a fine printed hand—not Penge&rsquo;s hand, nor any hand, but a regular mechanical type, faint and grey, as though the machine had a press of its own somewhere in its inwards.</p><p>The slip described his day. It described it from the hour of his waking to the hour the instrument expected him to sleep, and it described it not in the loose and hedging language of an almanac but in particulars. It said that the second post would bring a letter from his sister, that the letter would mention a Dr. Havering and ask after Carraway&rsquo;s chest, and that Carraway would mislay the letter before answering it. It said that at a quarter past eleven a man delivering coal would knock at the area door and be sent away because the coal was not wanted until Thursday. It said that it would rain between four and half-past, briefly, and that Carraway would be indoors and not mind. It gave him the better part of a remark his housekeeper would make about the price of fish.</p><p>He kept the slip in his waistcoat pocket through the day, he told me, in the spirit of a man humouring a coincidence. The letter came with the second post. It mentioned Dr. Havering. The coal-man knocked at a quarter past eleven. The rain came at four. And the housekeeper, setting down the dish, said the thing about the fish almost word for word—Carraway said<em>almost</em>, and I noticed that he was at pains to say it, as though the small inexactness were a thing he wished, even then, to hold on to.</p><h2 id="a-most-convenient-article">A Most Convenient Article</h2><p>I will not pretend the early part of the business was anything but agreeable, because Carraway did not pretend it, and his honesty in the matter is the one mercy in the whole account. For something better than a year the instrument was, in his own phrase, the most convenient article a man could own.</p><p>Consider what it is to be told your day in advance and to find the telling exact. One is never ambushed. Carraway met every caller already knowing the caller&rsquo;s errand, and was thought wonderfully quick. He carried an umbrella on the days it was wanted and left it at home on the days it was not, and was thought wonderfully lucky, which is a reputation a man may enjoy a long while before he examines it. He declined an invitation to dine with the Massinghams on a Tuesday because the slip, read that morning, had set down that a Mr. Croft would be of the party and would contrive to quarrel with him over a matter of politics; Carraway sent his regrets, and the quarrel, having no Carraway to fasten upon, did not occur, and the Massinghams thought him a man of delicate tact.</p><p>He began, in a small way, to lay wagers. Nothing extravagant—Carraway had no taste for extravagance, and besides, the instrument&rsquo;s particulars did not run to the names of horses, which it seemed not to know or not to care for. But it would tell him that a parcel he was expecting would come broken, and he would arrange to be elsewhere when it was opened; it would tell him that a clerk at his bank would make an error of two shillings against him, and he would have the figure ready. Small sure things. The cumulative effect of a great many small sure things, sustained without a single miss across a year, is that a man&rsquo;s friends begin to speak of him with a particular note in the voice—a note of affection laid over something that is not quite envy and not quite unease. I heard that note in my own voice once, speaking of Carraway to a third person, and did not at the time know what it was.</p><p>What it was, I think, was the recognition that he had stopped being surprised, and that the rest of us had not, and that this had quietly become the most important fact about him.</p><h2 id="the-cost-which-arrives-domestically">The Cost, Which Arrives Domestically</h2><p>I have called the early part agreeable, and so it was; but I should be misleading the reader if I let him suppose the change, when it came, announced itself. It did not. Catastrophes announce themselves. This was the other thing—the thing that arrives so gradually, and by such ordinary doors, that a man has lived a good way into it before he thinks to give it a name.</p><p>Carraway put it to me, near the end, in these words, and I have not improved them: &ldquo;A day that you have read at breakfast,&rdquo; he said, &ldquo;is not a day you can afterwards live. You can only verify it.&rdquo;</p><p>I asked him to be plainer, and he was.</p><p>A surprise, he said, is not merely a pleasant or unpleasant jolt; it is the proof that the day is still ahead of you, still unspent, still in some real sense<em>yours</em>. Dread is the same proof wearing a darker coat. And hope—hope above all—hope is the whole forward lean of a life, the thing by which a man leans into his afternoon. Take the three of them away together, as the slip took them away every morning at a stroke, and what is left is a day one walks through the way an actor walks through the four hundredth night of a play he has long ceased to hear. The lines arrive on their cues. One says them. They are correct. One has said them before, at breakfast, reading the grey type by the window, and the saying of them again at noon adds nothing whatever—confirms, merely; files the day, as a clerk files a paper already written, into the drawer of days that have been found to be in order.</p><p>His conversations were the worst of it, he said. To sit at one&rsquo;s own table and hear a friend deliver, with every appearance of spontaneity, a remark one has had in one&rsquo;s waistcoat pocket since nine that morning—to watch the friend arrive at his little joke and be pleased with it, and to know the joke, and the pleasure, and the exact small laugh that will follow—this, Carraway said, is a particular kind of loneliness for which he had never until then required a word. The friend is in the day. Carraway was not in the day. He was outside it, holding the script, and the friend&rsquo;s company, which ought to have been the warm unrepeatable thing it is for the rest of us, had become a performance got up nightly for an audience of one man who had read the notices.</p><p>He stopped, about this time, doing a number of things he had used to enjoy, not from any decision but because enjoyment had quietly gone out of them. There is no savour in opening a letter whose contents you have been told. There is no point in turning to the window to see what kind of day it is. He found, he said, that he had given up wondering—not as one gives up a vice, with effort and relapse, but as one gives up a language one no longer has anyone to speak it to. The faculty simply fell into disuse, and then into disrepair, and the loss of it was the loss of the particular muscle by which a man holds his face toward tomorrow.</p><h2 id="the-experiment-of-defiance">The Experiment of Defiance</h2><p>It will have occurred to the reader, as it occurred to Carraway, that there was an obvious remedy, and that he was a fool not to have tried it sooner. If the slip is a tyranny, defy the slip. Read it, learn what it commands, and then with deliberate purpose do the opposite. Let the day printed at breakfast and the day actually lived diverge, and the divergence itself will be the unread, unspent, genuinely future thing—a small territory of real tomorrow reconquered each day by an act of will.</p><p>He set about it, he told me, with more excitement than he had felt in many months, which excitement should itself have warned him, for it was the excitement of a man who has been shown a door in a wall he had thought unbroken.</p><p>The first morning the slip said that he would lunch at his club at one o&rsquo;clock and have the cold beef. Carraway resolved that he would not. He would lunch at half-past twelve, at a chop-house he never used, and have whatever was furthest from cold beef on the bill. He went out in good time, walked the unfamiliar direction, and found the chop-house closed for the painting of its front. The next establishment he came to did not please him. By the time he had satisfied himself, in a third place, that the painting and his own hesitancy had carried the hour past one, he had eaten, of the things on offer, the only one he could bring himself to face, which was cold beef; and it was, by then, well past one o&rsquo;clock, and he was nearer his club than the chop-house, and had in plain fact lunched at one, on cold beef, a quarter-mile from where the slip had set it down—the slip having been wrong only in the address, and the address being the one thing Carraway found he could not afterward feel had ever greatly mattered.</p><p>He did not give it up. He is not a man who gives a thing up because it has gone badly once. But the experiment, repeated, taught him a lesson by two routes, and I am not sure which of the two he found the colder.</p><p>The first route was the lunch&rsquo;s route. He found, again and again, that the slip&rsquo;s account had a way of being<em>fulfilled around</em> his defiances—that the day was a larger and more loosely woven thing than the single thread he had picked at, and that pulling the thread puckered the cloth without unmaking the pattern. He would refuse to call on a man, and the man would call on him. He would resolve to be out of temper with his housekeeper, by way of contradicting a slip that had foretold a pleasant morning, and would find the resolve curdle, the moment he tried to act on it, into the recognition that he had no genuine quarrel and that manufactured ill-temper is a thing the face declines to counterfeit. The day closed over his defiances the way water closes over a thrown stone.</p><p>The second route was worse, and I will give it to the reader exactly as Carraway gave it to me, because he gave it to me very quietly and then looked at his hands.</p><p>There came a morning when, thoroughly resolved upon revolt, he read the slip through with particular care, looking for the firmest of its statements to break. And he found, set down in the grey type among the rest of the day&rsquo;s small businesses, in the same even and unemphatic voice that allotted the post and the weather, the following: that at about a quarter to ten Mr. Carraway would read his slip, and would form the intention of defying it, and would attempt to do so in the matter of his morning&rsquo;s walk, and would, in the event, walk as the slip described.</p><p>The instrument had foreseen his defiance. It had foreseen it, and printed it, and filed it among the weather. His revolt was not outside the forecast. It was an item<em>in</em> the forecast—a small recurring feature of his days, like the second post.</p><h2 id="the-slips-he-did-not-read">The Slips He Did Not Read</h2><p>After that, Carraway told me, he stopped reading the slips. I want to set down plainly what he hoped from this, because the hope was reasonable, and a reasonable hope defeated is a sadder thing than a foolish one.</p><p>He hoped, simply, to have his days back. If the ruin lay in the reading—if it was the breakfast knowledge that hollowed the noon—then let the knowledge go unclaimed. Let the instrument print into the morning air, if it must; he would not look. He would take his post unforewarned, and be rained on, and be surprised, and walk once more with his face turned properly toward an afternoon he did not own in advance. He did not destroy the instrument. He told himself, and told me, that he kept it only from a natural unwillingness to break a thing of his uncle&rsquo;s; but I have wondered since whether even then some part of him knew that he was keeping it for the reason a man keeps anything he cannot use and cannot part with.</p><p>He let it stand on the side-table in his morning-room, and each day it produced its slip, and each day Carraway did not read it. He went so far, for a time, as to gather the slips unread into a drawer, and then, finding the drawer&rsquo;s slow filling a thing he disliked to think of, he left them simply where the instrument delivered them, in a small white drift along the side-table, accumulating.</p><p>And he discovered the last and quietest of the instrument&rsquo;s properties, which is this: that a known and unread account of the day is very nearly as fatal to the day as a read one.</p><p>He could not, he found, forget that the slip existed. It lay on the side-table, complete, exact, already true—the whole of his Tuesday set down in grey type six feet from where he ate his breakfast, wanting only to be looked at. And the knowledge that it lay there, finished, did to his Tuesday very much what reading it would have done. The surprise of the second post was no surprise; it was an envelope whose contents were at that moment described, in full, on a slip in the next room, and Carraway&rsquo;s not having walked over to read the description did not make the contents one particle less settled. He had not spent the day&rsquo;s secrets. But he no longer possessed them either. They had been<em>written down</em>, and the writing-down was the theft, and his refusal to read what had been written was a refusal that changed nothing, the way a man&rsquo;s shutting his eyes does not unmake the room.</p><p>The future, he said to me—and this was the nearest he came, in the whole telling, to bitterness—the future is not made unknown again by my declining to know it. It is only made unknown to<em>me</em>. The instrument knows it. The slip on the table holds it. I have not got my mornings back. I have merely arranged to be the one person in the house kept in the dark, and a man cannot live forward on a future that has been promised in writing to a drawer.</p><h2 id="the-last-of-it">The Last of It</h2><p>I saw Carraway last in the autumn, at his house, and the instrument was still on the side-table, and there was still the white drift of slips beside it, though the drift was older now and a little yellowed at the edges, and no new slip lay on the top of it. He had let it run down. He had stopped winding it at night some weeks before, he said, and it had printed its last forecast and fallen silent, and the silence, he admitted, had been at first a great relief and then something he could not name and did not like.</p><p>For here is the difficulty, and Carraway laid it before me with the unhappy clearness of a man who has turned a thing over until all its faces are familiar. To wind the instrument again is to resume the forecast, and the forecast he knows; he has had a year and more of what it makes of a life. But to leave it unwound is not, as he had once supposed, to step back into the ordinary blessed ignorance in which the rest of us conduct our affairs. Because he<em>knows the instrument works</em>. He has lived inside its accuracy. And a man who has once been certain that the day to come is a fixed and printable thing does not, by the act of declining to read it, become a man who feels the day to be open. He becomes only a man who knows the day is fixed and has chosen not to be told the fixing. The wonder did not come back when the printing stopped. Carraway had thought it was the slips that had killed his mornings. He understands now that it was the<em>knowledge</em>, and that the knowledge cannot be unwound.</p><p>I asked him—it seemed the only thing left to ask—why, then, he did not simply destroy the thing: take it out to the yard, he said himself it was hardly more than mahogany and clockwork, and have done. And he was quiet a while, and then he said that he had carried it out to the yard twice, and stood with it, and brought it in again. Not, he said, from any hope of it; he was past hoping anything of it. But the instrument was now the single object in his possession that<em>knew</em>—that held, in its springs and escapements, the propositions about his days that he could no longer feel but could no longer disbelieve—and to break it would be to be alone with a settled future and no longer any witness to it; and he had found, standing in the yard with the case in his two hands, that this was somehow worse than the side-table, and worse than the drift of slips, and that he could not do it.</p><p>So it stands there yet. He does not wind it and he does not break it. He goes down each morning and it is the first thing his eye finds, silent, full, declining to be either used or got rid of; and he eats his breakfast within sight of it, and reads no slip, and is surprised by nothing, and the second post comes.</p><p>I have set this down as he asked me to, and as exactly as I am able. I find I have no moral to fix to the end of it, and I think Carraway would not have wanted one fixed. I will say only that I went home from that last visit by a road I did not know, in order to find out what was along it; and that I was aware, the whole way, of doing it on purpose, and of how poor a thing a wondering is once a man has had to take it up deliberately, like a tool, in order to prove to himself that he still owns one.</p>
]]></content:encoded></item><item><title>The Quieter Sandbox - On Generating seccomp by Observation</title><link>https://mtclinton.com/posts/the-quieter-sandbox/</link><pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-quieter-sandbox/</guid><category>code</category><description>Some weeks back I was looking at the seccomp profile that had shipped, alongside one of our services, into production, and admitted I had no precise account of what it permitted. The profile allowed three hundred and fifty system calls. The service made, on a generous accounting of its hot path, perhaps thirty. The other three hundred and twenty had been allowed there because they were in the Docker default we had copied from, and the Docker default contained them because someone, some years ago, had decided it was easier to be liberal than to be specific. It is the architectural equivalent of the famous chair in the corner of the office — the one nobody sits in, with the small sign on it that says do not move.</description><content:encoded>&lt;![CDATA[<p>Some weeks back I was looking at the seccomp profile that had shipped, alongside one of our services, into production, and admitted I had no precise account of what it permitted. The profile allowed three hundred and fifty system calls. The service made, on a generous accounting of its hot path, perhaps thirty. The other three hundred and twenty had been allowed there because they were in the Docker default we had copied from, and the Docker default contained them because someone, some years ago, had decided it was easier to be liberal than to be specific. It is the architectural equivalent of the famous chair in the corner of the office — the one nobody sits in, with the small sign on it that says<em>do not move</em>.</p><p>The other half of the seccomp profiles I have seen in the wild, I should add, are written by hand against a checklist. They are tighter. They are also, on the day someone calls a code path nobody had thought to test, the cause of an entirely avoidable post-mortem.</p><p>What I should have liked, three months ago, was a tool that would simply<em>observe</em> what the service did, for a representative run, and write down the list it had observed. Such a tool exists, in the loose sense —<code>strace -c</code> will produce a syscall summary if asked, and there are several published shell scripts that pipe its output through a JSON formatter. I looked at these and concluded, for reasons I will come to, that they were not the thing. So I wrote one.</p><p>What I built is a small Rust binary called sandprint. It traces a target process — by command, or by attaching to a running PID — through eBPF, watches every system call that process or any of its children make, and at the end emits a tight allowlist in whatever format the sandbox tool ultimately wants: an OCI runtime profile, a<code>SystemCallFilter=</code> line for systemd, a libseccomp C header, raw JSON. The code is at<a href="https://github.com/mtclinton/sandprint">github.com/mtclinton/sandprint</a>, Apache-2.0; about twenty-five hundred lines of Rust and eighty lines of BPF C, which is small enough to read in an afternoon.</p><h2 id="a-short-demonstration">A Short Demonstration</h2><p>The pitch, in thirty seconds:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="o">$</span><span class="n">sudo</span><span class="n">sandprint</span><span class="n">profile</span><span class="n">run</span><span class="o">--</span><span class="n">ls</span><span class="o">/</span><span class="n">tmp</span></span></span><span class="line"><span class="cl"><span class="o">...</span><span class="n">INFO</span><span class="n">BPF</span><span class="n">tracer</span><span class="n">loaded</span><span class="ow">and</span><span class="n">attached</span></span></span><span class="line"><span class="cl"><span class="o">...</span><span class="n">INFO</span><span class="n">tracing</span><span class="n">command</span><span class="n">pid</span><span class="o">=</span><span class="mi">2409773</span></span></span><span class="line"><span class="cl"><span class="p">[</span><span class="n">directory</span><span class="n">listing</span><span class="p">]</span></span></span><span class="line"><span class="cl"><span class="o">...</span><span class="n">INFO</span><span class="n">child</span><span class="n">exited</span><span class="n">status</span><span class="o">=</span><span class="n">Exited</span><span class="p">(</span><span class="n">Pid</span><span class="p">(</span><span class="mi">2409773</span><span class="p">),</span><span class="mi">0</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">Observed</span><span class="mi">202</span><span class="n">syscall</span><span class="n">events</span><span class="p">(</span><span class="mi">27</span><span class="n">unique</span><span class="n">syscalls</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">NR</span><span class="n">COUNT</span><span class="n">NAME</span></span></span><span class="line"><span class="cl"><span class="mi">9</span><span class="mi">36</span><span class="n">mmap</span></span></span><span class="line"><span class="cl"><span class="mi">257</span><span class="mi">35</span><span class="n">openat</span></span></span><span class="line"><span class="cl"><span class="mi">3</span><span class="mi">26</span><span class="n">close</span></span></span><span class="line"><span class="cl"><span class="mi">5</span><span class="mi">23</span><span class="n">fstat</span></span></span><span class="line"><span class="cl"><span class="mi">1</span><span class="mi">19</span><span class="n">write</span></span></span><span class="line"><span class="cl"><span class="mi">59</span><span class="mi">11</span><span class="n">execve</span></span></span><span class="line"><span class="cl"><span class="mi">0</span><span class="mi">9</span><span class="n">read</span></span></span><span class="line"><span class="cl"><span class="mi">10</span><span class="mi">6</span><span class="n">mprotect</span></span></span><span class="line"><span class="cl"><span class="mi">157</span><span class="mi">6</span><span class="n">prctl</span></span></span><span class="line"><span class="cl"><span class="mi">12</span><span class="mi">5</span><span class="n">brk</span></span></span><span class="line"><span class="cl"><span class="mi">217</span><span class="mi">5</span><span class="n">getdents64</span></span></span><span class="line"><span class="cl"><span class="o">...</span></span></span></code></pre></div></div></figure><p>That is<code>ls /tmp</code> running under sandprint. Twenty-seven unique syscalls is the honest, observed footprint of a directory listing —<code>getdents64</code> and<code>statx</code> for the entries,<code>write</code> for the output, plus the usual glibc startup ritual. A seccomp profile derived from this run is twenty-seven syscalls. A generic container default is north of three hundred. The two profiles do not, on inspection, agree on what<code>ls</code> is for.</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ sandprint profile generate --input trace.json --format oci &gt; seccomp.json</span></span><span class="line"><span class="cl">$ wc -l seccomp.json</span></span><span class="line"><span class="cl"> 71 seccomp.json</span></span></code></pre></div></div></figure><p>Drop that into the OCI runtime spec under<code>linux.seccomp</code> and one has, against modest expectations, a working sandbox.</p><h2 id="the-hundred-lines-of-bpf">The Hundred Lines of BPF</h2><p>The kernel-side of sandprint is a BPF program of roughly that length, attached to three raw tracepoints.<code>sys_enter</code> fires on every system call entry, and the program — when the calling task is in our tracked set — pushes a forty-byte event onto a ring buffer.<code>sched_process_fork</code> admits any child of a tracked task to the tracked set automatically; this is how process trees get followed without any userspace bookkeeping.<code>sched_process_exit</code> evicts the dead tasks so the tracked-PID hashmap does not grow without bound over a long trace.</p><p>The userspace side is a single thread that polls the ring buffer until the target process exits, and converts the event log into a canonical JSON trace at the end.</p><p>The whole arrangement is unfussy. The BPF program declares only what it must; for example, it needs to read<code>task-&gt;tgid</code> to identify the task group, but it does not bring in the whole<code>task_struct</code>. Instead it declares a one-field stub:</p><figure class="code-terminal" data-lang="c"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">c</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">struct</span><span class="n">task_struct</span><span class="p">{</span></span></span><span class="line"><span class="cl"><span class="kt">int</span><span class="n">tgid</span><span class="p">;</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="nf">__attribute__</span><span class="p">((</span><span class="n">preserve_access_index</span><span class="p">));</span></span></span></code></pre></div></div></figure><p>CO-RE — Compile Once, Run Everywhere — does the rest. libbpf rewrites the field offset at load time, using BTF (BPF Type Format) information from the running kernel. The same compiled BPF object loads against a 5.10 kernel, a 6.1 kernel, and whatever Ubuntu chose to ship on its newest LTS, without rebuilding. There is no<code>vmlinux.h</code> checked into the repository and no per-distribution build matrix. The cost of this independence is that any kernel without a<code>/sys/kernel/btf/vmlinux</code> will refuse to load the program — which, in practice, is a non-concern on any kernel from the last few years.</p><p>The program uses only verifier-friendly constructs: bounded array indexing, no unbounded loops, atomic counter updates, paired ring-buffer reserve and submit. The verifier does not, on inspection, complain about it. One is grateful for this, having had occasion in past work to be lectured by the verifier at length.</p><h2 id="what-strace-could-not-do">What strace Could Not Do</h2><p>The first question one asks of any new tool is whether it duplicates an old tool.<code>strace -c</code> has been counting system calls and post-processing them into summaries since I was learning what a system call was. Two reasons it did not, on a careful look, suffice.</p><p>The first is performance. ptrace-based tracing — which is what strace does — is a non-trivial slowdown on the target. Each traced syscall takes a round-trip through ptrace&rsquo;s wakeup machinery; for a workload that is at all perf-sensitive or timing-sensitive, the version of the workload running under strace behaves differently from the version running in production. One ends up profiling the strace, not the service. eBPF tracing, by contrast, is essentially free at this scale: the tracepoint fires anyway, the BPF program drops forty bytes onto a ring buffer, and userspace reads the buffer asynchronously. There is no signalling, no syscall round-trip per traced call, no per-call overhead detectable in benchmarks.</p><p>The second reason is conflict. ptrace is exclusive — a process being ptraced by one tool cannot be ptraced by another. One cannot strace a process that is already under gdb, and one cannot gdb a process that is already under strace. eBPF tracing has no such constraint. A process can be traced by sandprint, ptraced by gdb, and audited by auditd, all simultaneously, with none of the three knowing about the others. This is the kind of property one does not value until one needs it.</p><p>The cost of going the eBPF route is the capability requirement. The tracer needs<code>CAP_BPF + CAP_PERFMON</code>, or<code>CAP_SYS_ADMIN</code> on older kernels, and the kernel needs the BTF entry under<code>/sys/kernel/btf/vmlinux</code>. On any kernel from the last few years both are standard. On older or hardened kernels they are not, and one is back to ptrace; sandprint does not pretend to be the tool for those cases.</p><h2 id="the-trouble-with-watching">The Trouble With Watching</h2><p>A profile generated from observation has a defect that a profile written from a specification does not: it can only contain what one&rsquo;s run actually executed. If the test harness one ran sandprint against does not exercise the error path that calls<code>prctl</code>, the generated profile will block<code>prctl</code> in production. The first time the error path runs in earnest, the kernel will deliver a SIGSYS to the offending process, and one will have, at that moment, a perfectly characteristic and entirely avoidable production incident.</p><p>This is fundamental to any observation-based tool and is not specific to sandprint.<code>oci-seccomp-bpf-hook</code>,<code>syscall2seccomp</code>, the various shell scripts that derive profiles from<code>strace -c</code> outputs — all share it. The honest framing is that a generated profile is a starting point for tightening, not a finished verification.</p><p>The workflow that has, on a working basis, served me is roughly: run sandprint while exercising every code path one cares about, including CI integration tests, soak tests, and error paths; merge the resulting traces with<code>profile merge</code> to union them into a single profile; apply that profile in staging and watch the kernel logs for SIGSYS and EPERM events; iterate. The generated profile is wrong on the first run, less wrong on the third, and acceptably tight by the time it has caught everything one&rsquo;s CI suite knows how to catch.</p><p><code>profile diff</code> between two runs has a useful side benefit. It tells one which test paths exercise which syscalls — and, by absence, which paths exercise no new syscalls and are therefore candidates for pruning from the CI matrix. I had not anticipated this when writing the tool. It has been, on more than one occasion, the bit of the tool I most use.</p><h2 id="what-i-should-like-to-build-next">What I Should Like to Build Next</h2><p>A syscall allowlist alone is a meaningfully weaker sandbox than a syscall allowlist plus a path allowlist. The next feature on the list is argument capture for<code>open</code> and<code>openat</code>: reading the path argument out of the kernel as the call enters, and emitting an allowlist of paths alongside the syscall list. The mechanism is more involved — one has to walk<code>task-&gt;files-&gt;fdt-&gt;fd[i]</code> for the file-descriptor case, or<code>process_vm_readv</code> the userspace pointer for the path case — but it is tractable, and the kernel side of it is no more complicated than what sandprint already does for the syscall numbers themselves.</p><p>Network syscall argument capture (socket family, type, protocol) is the same mechanism applied to a different argument list. Container-runtime integration as a containerd NRI plugin or a runc hook is the most ambitious item; it would let one flip sandprint on for any container workload without changing the command line, and would close the loop with the OCI profile output that already exists. None of the three is hard in any architectural sense. They are, in the language one uses about such things, a matter of finding the time.</p><p>The code is at<a href="https://github.com/mtclinton/sandprint">github.com/mtclinton/sandprint</a>, Apache-2.0. Issues and pull requests are, against the standard caveat that I will respond to them on a hobbyist&rsquo;s schedule, welcome.</p>
]]></content:encoded></item><item><title>The Listening Mirror</title><link>https://mtclinton.com/posts/the-listening-mirror/</link><pubDate>Sun, 26 Apr 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-listening-mirror/</guid><category>writing</category><description>A bachelor discovers that the looking-glass above his mantel has been keeping every word said before it, and learns, slowly, what it costs to have lived in the hearing of such an object.</description><content:encoded>&lt;![CDATA[<p>I have set down what follows because Hollis Vane asked me to, and because I do not entirely trust myself to remember it correctly if I do not write it now. He told me the thing over several conversations in the last winter of his tenancy of the Wimpole Street house — told it without pressing it, as a man states a fact about his own affairs and leaves the question of belief to the listener. I believed him then and I believe him still, though I will admit I do not always wish to. There is a class of stories of which the chief discomfort is not that they are incredible, but that they are credible at every point, and arrange themselves at last into a thing one would rather have remained ignorant of. This is such a story.</p><p>Vane was a bachelor solicitor of fifty when he came into the house. He had taken the Wimpole Street lease, and the contents of the rooms with the lease, on the death of an aunt who had not been a near relation. He moved in chiefly because the rooms were better than his chambers, and because — he was honest with me about this — the rent of his chambers had been raised in a manner he had felt to be personal.</p><p>The drawing-room was the best of the rooms: a long room on the first floor, with two windows giving onto the street and a heavy black mantel of marble at the far end. Above the mantel hung the looking-glass.</p><p>It was, as such things go, a perfectly ordinary mirror — a plate somewhat over four feet in height and a little over three across, with the faint silver-bloom of glass long silvered and never resilvered, set in a sober Regency frame of polished mahogany. There was nothing whatever to mark it out. Vane noticed it as one notices a piece of furniture in a room one means to live in: he formed the small private intention of having it cleaned, and did not have it cleaned, and forgot the intention, and the mirror hung as it had hung, presumably, for most of his aunt&rsquo;s tenancy and possibly for the tenancy before hers as well.</p><p>He went on living in the house, in his quiet and orderly way, for some months before anything occurred. He wrote letters and read in the drawing-room of an evening; his sister called on Thursdays and they took tea there; once a month a man of his acquaintance from the Inn would come up and they would sit and talk about a case or about nothing. A good deal was said in the room, in the way a good deal is always said in rooms, and Vane thought no more of any of it than one thinks of breath.</p><h2 id="the-first-voice">The First Voice</h2><p>The first replay came on a Tuesday evening in the November of his first year. He had spent the day in chambers and had come home tired and settled into the chair he kept by the fire in the drawing-room, with a book and a glass. He was reading, he said, with the half-attention of a man whose principal pleasure is in the sitting still, when he heard, perfectly distinctly, his own voice say a sentence in the room.</p><p>The sentence was: &ldquo;Well, I don&rsquo;t pretend to know what Aunt Maud would have wanted; but I think she would have wanted the desk to go to Phoebe.&rdquo;</p><p>He sat up in the chair. The voice had come, plainly, from the direction of the mantel. It was altogether his own voice, in the unmistakable way one&rsquo;s own voice is unmistakable — in a manner one cannot afterwards confuse with any other thing.</p><p>Vane was not a man given to fancies. His first thought was perfectly rational: he had heard something from the street, refracted by the chimney or by some peculiarity of the room&rsquo;s acoustics, and his mind had supplied the resemblance. He set the book down and listened. The street was quiet. The fire ticked. A cab went by, far off. Nothing else came. His second thought was that he had spoken the sentence himself, aloud, in the absence of mind that overtakes a tired man with a book, and had only thought he had heard it. He found this less plausible than the first, but he entertained it, because the alternative — that the sentence had come, fully formed and in his own voice, out of an empty room — was not a thing he was prepared to entertain at all.</p><p>It was when he went, an hour later, to bed, that the third thought arrived, and the third thought was the bad one.<em>He had spoken the sentence before.</em> He had spoken it, in fact, in that very room, three weeks earlier, to his sister Phoebe, on a Thursday over tea. They had been discussing the disposal of certain pieces from the estate. He remembered now, with the sharp small remembering one does in bed at such moments, that Phoebe had laughed at the formality of his manner and said, &ldquo;Hollis, you are not a probate clerk, you are her nephew.&rdquo; He remembered the laugh. He had heard, an hour before in the drawing-room, the sentence and not the laugh.</p><p>He went to sleep telling himself that he was tired, and that the brain, which is an instrument he had never quite trusted, had supplied an echo of a real conversation in place of an unreal one. He woke in the morning believing this. He believed it through breakfast. By evening he had given up believing it, because he could not, in honesty, believe a thing the only support of which was that he wished to.</p><p>For some days he did not sit in the drawing-room. He took his book to the dining-room, where he had never sat in the evenings, and read there, and was uncomfortable, and felt foolish for being uncomfortable. By the end of the week he had decided that the only respectable course was to go back. He went in. He sat. He read. Nothing came. He went in the next evening. Nothing came. He went in the third evening, and Phoebe&rsquo;s voice, from the direction of the mantel, said, &ldquo;Hollis, you are not a probate clerk, you are her nephew.&rdquo; And then, after a pause perhaps of a second, the small contained laugh he remembered her giving. And then nothing more.</p><h2 id="the-pattern-so-far-as-i-could-make-it-out">The Pattern, So Far as I Could Make It Out</h2><p>It would be tidy to report that Vane settled at once into careful observation; he did not. The first weeks were a watchfulness one could not tell from dread, in which he heard nothing for several evenings together and then a fragment at the unlikeliest possible hour, and was made to start. It was nearer four months before he had anything like a pattern to lay before himself.</p><p>The mirror gave back things that had been said in front of it. He satisfied himself of this by a series of small tests: he would say a particular harmless sentence aloud in the room of an evening, with no one to hear; and within a few days to a few weeks, that sentence, in his own voice and at his own pitch, would come back from the mantel at some moment he could not predict. The replay was perfectly faithful in voice and in word. It was not faithful in selection. The mirror did not give back everything. It gave back, by some preference of its own, only certain things.</p><p>The preference he learned slowly, and never with confidence; but as nearly as he could state it: the mirror favoured what had been said with feeling. It did not concern itself with the housekeeper&rsquo;s good-morning, nor with the small mechanical phrases by which men open and close their evenings. It returned, by preference,<em>confidences</em> — the things one says when one has dropped one&rsquo;s voice a little; the half-completed thought one had not pursued because the friend changed the subject and one had been a little relieved. It returned, especially, the sentences a man says once and once only — a kindness expressed, an admission made, an opinion offered with more candour than was strictly safe — and then does not repeat, because to repeat such a thing is to underline it, and one does not always wish to be quite so underlined.</p><p>It returned, in short, the things one said meaning them.</p><h2 id="the-first-conversation-staged-for-it-deliberately">The First Conversation Staged for It Deliberately</h2><p>There came a stage at which Vane attempted to use the mirror. He had been carrying for some weeks a piece of unfinished business in his own mind: a sentence he had not said to his father before his father died, twelve years before. He did not tell me what the sentence was. I gathered only that not having said it had been, in his own private accounting, one of the few real failures of his ordinary decency.</p><p>He resolved, one evening in February, to say the sentence aloud to the mirror — in his father&rsquo;s hearing, so to speak, in the closest approximation the world any longer allowed — and to let it be there. He did not expect his father to answer; he had not lost his sense of proportion. He expected only that the mirror, having heard the sentence in the register of feeling in which he meant to say it, would in due course return it, and that he would hear it then in his own voice, as a man hears a thing he has at last said, and the unfinished business would by this means be at any rate retired.</p><p>He cleared the room. He put the lamp where he wished it. He sat in the chair by the mantel and said the sentence aloud, in the voice he had meant to use, and got up afterwards a little foolish and a little relieved.</p><p>Three days later, going into the drawing-room with the post, he heard from the mantel a sentence in his own voice — and it was not the sentence he had said. It was an instruction he had given some months earlier to his clerk, in passing, about a misfiled affidavit. He stood with the post in his hand and listened to himself deliver it; and there was nothing else.</p><p>He waited, after that, for weeks. He gave the mirror, as he put it, every opportunity to amend the choice. It did not amend the choice. It returned, in those weeks, a number of other things — a remark of Phoebe&rsquo;s, a fragment of a conversation with a client whom he no longer liked, a sentence of his own about the price of asparagus — and it did not return the sentence he had prepared. It did not return it that winter, and it did not return it in the spring, and at some point in the summer he understood that it would not return it at all.</p><p>The mirror was not to be commanded. One could speak in front of it; one could not address it. His attempt to feed it the sentence had been an attempt to instruct an instrument of which he was, evidently, not the operator but the subject.</p><h2 id="the-voices-he-did-not-know">The Voices He Did Not Know</h2><p>I should have mentioned earlier — except that Vane himself did not mention it to me until quite far into the telling — that he had by this time begun to hear voices in the drawing-room that he did not know.</p><p>They had been there from the start; he had simply taken them, in the first months, for further tricks of his mind. There would be the small distinct sound of a woman saying, &ldquo;I have asked him twice, and he will not say.&rdquo; A man&rsquo;s voice, with a north-country edge in it, saying only, &ldquo;Then it is settled, and we shall not speak of it again.&rdquo; Once — and this was the one that had stayed with him longest — a child, perhaps eight or nine, said quite calmly, &ldquo;I do not want to live with her, Father,&rdquo; and then nothing.</p><p>These had at first frightened him more than the others, because the others were at least his. He began, by way of getting them in order, to keep a small notebook of the sentences he had heard; and in the second half of the first year he took the notebook to the small office in the basement that had been his aunt&rsquo;s, and went through the papers there with a patience he had not previously brought to them. He found a quantity of correspondence going back many decades, in three or four different hands, and a small leather-bound household book in which his aunt had kept, all her widowed life, a record of her dinners — who had dined, what had been served, what had been spoken of. The aunt had been a methodical woman.</p><p>By cross-reference, Vane was able to put names to a number of the voices. Some were friends of his aunt, long since dead. Some were earlier — his aunt&rsquo;s husband, who had died before Vane was born, and whose voice Vane had now heard several times in his own drawing-room; his aunt&rsquo;s husband&rsquo;s first wife, of whom Vane had never heard, and whose existence he had learned of only by tracing her name through a letter. And some were older than the household book itself. They belonged to a tenancy before the aunt&rsquo;s, and Vane could not, by any document he could find, attach a name to them at all.</p><p>He came to understand, then, that the mirror had not begun with him. It had not begun with his aunt either. It had been hanging on some mantel or other, in some drawing-room or other, for as long as it had been a mirror; and it had kept what was said in front of it, the whole time, and given back whatever portion the mirror chose to give back, to whoever happened to be sitting in the room when the giving back occurred. None of it had gone. The mirror evidently kept everything.</p><h2 id="the-closing-of-the-house">The Closing of the House</h2><p>The period that followed is difficult to give in the proper proportion, because nothing very dramatic took place, and yet the shape of Vane&rsquo;s life altered considerably, by stages that were each in themselves quite small.</p><p>He stopped sitting in the drawing-room in the evenings unless he was alone. He found, after a few attempts at company there, that he could no longer hear a friend say something across the hearth without thinking,<em>and now that, too, has been kept;</em> and this thought, once arrived, put a small constraint on his side of the conversation which the friend felt without identifying, and which spoiled the evening. He gave up the drawing-room for company, and used the small parlour at the back of the house instead, and matters were better there, for a time.</p><p>He understood, after some months, that he could no longer be sure the mirror&rsquo;s effect was confined to the drawing-room. He had no evidence that any other room held the same property; but he had no evidence that none did, either, and the second absence weighed on him more heavily than the first. He moved his company to the dining-room; gave up the dining-room after a winter; and then, by a step that arrived without quite being decided on, gave up the house for company altogether. He met his friends at his club, or at theirs, or at restaurants in which he had never previously taken any pleasure, and he did not have them in.</p><p>Phoebe, who was the only person who would have insisted, did insist; and Vane, who could not bring himself to tell her the reason, told her instead that he had become difficult and solitary in his old age. She accepted this, because she had always half expected it of him, and because the alternative was a thing she could not have done very much with. She came less often, and then on alternate Thursdays, and then for tea at her own house instead of his. The drawing-room sat empty most evenings, and the mirror hung in it.</p><h2 id="the-realisation">The Realisation</h2><p>He had begun, after the first months, to think of the mirror as a recording device. That was the natural figure, in the age in which we live; it was the figure I myself reached for when he first described it, and he saw me reach for it, and was patient with the reach. But he had come, by stages, to think it was not a recording device at all. A recording device sets out to capture what passes before it and stores a copy of the capture; the original passage of speech has gone, and the copy, which is a kind of artefact, is what remains.</p><p>The mirror was not of this kind. It did not so much<em>record</em> what was said before it as<em>retain</em> it. It did not produce a copy and store the copy. It kept the thing itself. What had been spoken in front of the mirror had not, in any sense the mirror cared about,<em>gone;</em> it had merely ceased, for a while, to be audible. The replays were not playbacks of stored copies. They were the original speech, becoming audible again, in the same voice and on the same breath, as if no time had passed at all.</p><p>I do not know whether Vane was right about this. It is, on the face of it, a metaphysical claim, and he was not by trade a metaphysical man. But I have not found a way of describing the mirror&rsquo;s behaviour that fits the behaviour as well as his does. A recording is a copy. The mirror did not give copies. It gave the thing.</p><p>The consequence was this. Vane had spent the first fifty years of his life, as the rest of us spend ours, on the working assumption that speech is a perishable substance. One says a thing aloud; the air receives it; the thing is gone, and only such part as the listeners chose to retain in their own memory survives. This assumption underwrites the whole texture of ordinary conversation. One ventures a confidence because the confidence will soon be only what the friend chooses to remember of it; one drops one&rsquo;s guard because the air will close, in a moment, over whatever one has let through.<em>Speech is provisional.</em> This is the unwritten contract under which men have been talking to one another, in drawing-rooms and elsewhere, for the whole of recorded time.</p><p>The mirror voided the contract. Not by recording. By<em>witnessing</em>. What had been said in its presence had not gone; it had been held; and Vane had been talking, for the better part of two years before he understood this, on the assumption that it was going.</p><p>What he most regretted, he said, was not anything in particular he had said. His life had not been the kind to furnish shameful sentences in any quantity. What he regretted was the<em>manner</em> of his having said the ordinary things: said them in the confidence that the air would presently close over them. He had spoken with feeling because the feeling would not be kept; and the feeling had been kept, and was now in the room, complete, available to be reissued on the mirror&rsquo;s own schedule and on no schedule of his.</p><p>It was, he said, like discovering at sixty that one had been overheard since five.</p><h2 id="the-last-evening">The Last Evening</h2><p>He gave up the lease the following spring. I was there on his last evening. Most of the furniture had gone. The drawing-room held only the chairs, and the small table, and the mantel with the mirror over it.</p><p>He had, by then, covered the mirror. He had done it weeks before, with an old grey cloth he had had from somewhere — not, he was at pains to say, in any expectation that it would silence the thing, but as a small private courtesy to himself, so that he should not be obliged to see the room reflected in it whenever he went in. The cover did not silence it. A sentence had come out from under the cloth, on a Wednesday in the previous month, in a voice he did not know — a woman&rsquo;s voice, perhaps a hundred years dead, saying, &ldquo;It is not the money, James, you know it is not the money.&rdquo; It had come out as clearly as it would have come from in front of the glass. The cover was, as he had expected, only a courtesy.</p><p>I asked him whether he meant to take the mirror with him. He shook his head. The mirror was a piece of the house and not of his furniture, he said. He had considered breaking it; but he could not destroy a thing which contained the only surviving record — if record was the word — of speech that had belonged to people he had never known, and he was not at liberty to silence the dead a second time on his own authority.</p><p>We sat there a while, in the chairs, in the nearly empty room. The fire was low. He was, I think, a little reluctant to leave. He had not been happy in the house, in the latter part; but he had been, in some way I could not quite name, attended in it, and was not yet sure what it would be like not to be.</p><p>He got up, after a long pause, and walked over to the mantel, and took the cloth down from the mirror, and folded it, and laid it on the empty mantelshelf. The plate, with the small bloom on it, gave back the room and the two of us in it and the low fire behind us. We did not say anything for some little while.</p><p>Then, from the direction of the mantel, in his own voice, came a sentence I had not heard him say and that he was not, in that moment, saying. It was not long. He had spoken it, he told me later, in the autumn of his second year in the house, in this room, alone, on an evening he had quite forgotten until he heard it now. He gave me, when I asked, the words of it; but I think on consideration that I will not set them down. It was the sort of sentence a man says once, to no one, because he had not until that moment known he meant it; and the mirror had taken it and kept it for him; and it now stood — if it stood — as the only proof that he had ever meant it at all.</p><p>He listened to it through. He did not speak. When it was done, he stood another moment by the mantel, and then put the cloth back over the glass, and we left the room, and he locked the door.</p><p>I walked with him as far as Cavendish Square. At the corner he stopped and shook my hand and thanked me, in his ordinary undemonstrative way, for having listened to him over the winter; and he said, almost as an afterthought, that he supposed the mirror would be heard by someone else now, and that this was probably as it should be, since a thing of that kind ought not, on reflection, to belong to any one tenant.</p><p>I have not been back to the house. I do not know who lives there now. I do not know whether the mirror still hangs above the mantel, or whether it has been moved, in the way mahogany frames eventually are, into another drawing-room in another house, on another street, where someone is at this moment sitting by the fire and reading and is about to hear, very distinctly, a sentence in a voice he knows.</p><p>I have set this down as Vane asked me to, and as exactly as I am able. I have no moral to attach, and I think Vane would not have wanted one attached. I will say only that I have, since that winter, found myself a little more careful about what I say in rooms — not from any belief that the rooms I sit in are listening, for I have no such belief, but from a small new awareness that the air&rsquo;s closing over a sentence is a thing I had been counting on without ever having examined the count; and that a man who has once been told the air does not always close cannot quite, afterwards, return to the easy speech of those who have not been told.</p>
]]></content:encoded></item><item><title>A microVM Small Enough to Read</title><link>https://mtclinton.com/posts/a-microvm-small-enough-to-read/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/a-microvm-small-enough-to-read/</guid><category>code</category><description>Modern sandboxing arranges itself, if one steps back a few paces, on a rough spectrum. At one end sits the container, a cleverly fenced process that remains, under the fences, a process. At the other sits the virtual machine — a small second computer, with its own kernel, its own interrupts, its own illusion of having the hardware to itself. Between the two, engineering has inserted a pair of curiosities that belong to neither kind: gVisor, which is a kernel in userspace and intercepts its guest&rsquo;s syscalls from above, and Firecracker, which is a virtual machine stripped of every convenience that a virtual machine ordinarily supplies. The two are, in a sense, responses to the same complaint — that containers are weak and virtual machines are heavy — approached from opposite directions and shaking hands in the middle.</description><content:encoded>&lt;![CDATA[<p>Modern sandboxing arranges itself, if one steps back a few paces, on a rough spectrum. At one end sits the container, a cleverly fenced process that remains, under the fences, a process. At the other sits the virtual machine — a small second computer, with its own kernel, its own interrupts, its own illusion of having the hardware to itself. Between the two, engineering has inserted a pair of curiosities that belong to neither kind: gVisor, which is a kernel in userspace and intercepts its guest&rsquo;s syscalls from above, and Firecracker, which is a virtual machine stripped of every convenience that a virtual machine ordinarily supplies. The two are, in a sense, responses to the same complaint — that containers are weak and virtual machines are heavy — approached from opposite directions and shaking hands in the middle.</p><p>I spent a few weeks at the gVisor end of this spectrum. The earlier writings on this blog —<a href="/posts/mini-sentry/">mini-sentry</a>,<a href="/posts/hijacking-signals-in-go/">the signals piece</a>,<a href="/posts/a-tour-of-the-gvisor-front/">the tour of gVisor&rsquo;s own code</a> — are records of what I found there. This post is a record of what happened when I walked, not very patiently, to the other end, and tried to build the small version of the thing that lives there.</p><p>The result is<a href="https://github.com/mtclinton/mini-firecracker">mini-firecracker</a>. About 5,300 lines of Go, one external dependency (<code>golang.org/x/sys</code>), Linux and KVM and x86_64 only. It boots a real Linux kernel, serves it a virtio-blk block device backed by a file, serves it a virtio-net interface backed by a tap, gives it a serial console the guest&rsquo;s shell writes to, and — the piece of Firecracker that made Lambda economical — dumps the running machine to disk and restores it into a fresh process in under three hundred milliseconds.</p><p>The headline demonstration, cribbed from the README, is a snapshot taken part of the way through the boot and resumed elsewhere:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Take a snapshot 800 ms into the boot.</span></span></span><span class="line"><span class="cl">$ ./mini-fc run<span class="se">\</span></span></span><span class="line"><span class="cl"> --kernel testdata/vmlinux-5.10.245 --mem<span class="m">512</span><span class="se">\</span></span></span><span class="line"><span class="cl"> --drive<span class="nv">path</span><span class="o">=</span>ubuntu-24.04.squashfs,ro<span class="se">\</span></span></span><span class="line"><span class="cl"> --net<span class="nv">tap</span><span class="o">=</span>minifc0<span class="se">\</span></span></span><span class="line"><span class="cl"> --cmdline<span class="s2">"console=ttyS0 reboot=k panic=1 root=/dev/vda rootfstype=squashfs ro init=/bin/sh"</span><span class="se">\</span></span></span><span class="line"><span class="cl"> --snapshot-after 800ms --snapshot-to /tmp/snap</span></span><span class="line"><span class="cl"><span class="o">[</span>mini-fc<span class="o">]</span> snapshot written to /tmp/snap</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="c1"># Restore and interact.</span></span></span><span class="line"><span class="cl">$<span class="o">(</span>sleep 1.5<span class="p">;</span><span class="nb">printf</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="s1"> ip link set eth0 up</span></span></span><span class="line"><span class="cl"><span class="s1"> ip addr add 172.16.0.2/30 dev eth0</span></span></span><span class="line"><span class="cl"><span class="s1"> ping -c 3 172.16.0.1</span></span></span><span class="line"><span class="cl"><span class="s1"> exit</span></span></span><span class="line"><span class="cl"><span class="s1"> '</span><span class="o">)</span><span class="p">|</span> ./mini-fc restore --from /tmp/snap</span></span><span class="line"><span class="cl"><span class="o">[</span>mini-fc<span class="o">]</span> restored from /tmp/snap in<span class="m">262</span> ms</span></span><span class="line"><span class="cl"><span class="c1"># ping -c 3 172.16.0.1</span></span></span><span class="line"><span class="cl">PING 172.16.0.1<span class="o">(</span>172.16.0.1<span class="o">)</span> 56<span class="o">(</span>84<span class="o">)</span> bytes of data.</span></span><span class="line"><span class="cl"><span class="m">64</span> bytes from 172.16.0.1:<span class="nv">icmp_seq</span><span class="o">=</span><span class="m">1</span><span class="nv">ttl</span><span class="o">=</span><span class="m">64</span><span class="nv">time</span><span class="o">=</span>0.264 ms</span></span><span class="line"><span class="cl"><span class="m">3</span> packets transmitted,<span class="m">3</span> received, 0% packet loss</span></span></code></pre></div></div></figure><p>That is an entire virtual machine&rsquo;s lifecycle — booted, shelled into, networked, paused, serialised to disk, resumed in another process, continued — running through about five kilobytes of structured state and a 512 MiB memory blob. Having built this on one side of the sandboxing spectrum and mini-sentry on the other, I now have the curious sensation of having laid down two small flagstones at opposite ends of a long path and found, to my surprise, that the path is shorter than it looked.</p><h2 id="most-of-the-vmm-is-a-switch-statement">Most of the VMM Is a Switch Statement</h2><p>The body of the VMM, once one has granted oneself a few conveniences, is a handful of owned things and a loop.</p><p>Each VM is one Go process. It owns one file descriptor into<code>/dev/kvm</code>, one VM-level descriptor derived from that, an in-kernel interrupt chip and a programmable interval timer, a single anonymous<code>mmap</code> that serves as the guest&rsquo;s RAM and is registered as KVM memory slot zero, and one vCPU pinned — by way of<code>runtime.LockOSThread</code>, KVM being insistently a per-thread interface — to a Go goroutine that will not migrate elsewhere. It also owns a minimal 16550A UART stub at the historic port<code>0x3f8</code>, which the kernel will speak to the moment it is alive, and a collection of virtio-MMIO device slots at four-kilobyte intervals starting at<code>0xd0000000</code>.</p><p>The hot path, once all of that has been arranged, is a single-threaded loop around<code>KVM_RUN</code> with a switch on the reason the guest stopped:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"/><span class="p">(</span><span class="nx">v</span><span class="w"/><span class="o">*</span><span class="nx">VMM</span><span class="p">)</span><span class="w"/><span class="nf">Run</span><span class="p">()</span><span class="w"/><span class="kt">error</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">runtime</span><span class="p">.</span><span class="nf">LockOSThread</span><span class="p">()</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">for</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">if</span><span class="w"/><span class="nx">err</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nx">v</span><span class="p">.</span><span class="nx">vcpu</span><span class="p">.</span><span class="nf">Run</span><span class="p">();</span><span class="w"/><span class="nx">err</span><span class="w"/><span class="o">!=</span><span class="w"/><span class="kc">nil</span><span class="w"/><span class="p">{</span><span class="w"/><span class="k">return</span><span class="w"/><span class="nx">err</span><span class="w"/><span class="p">}</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">switch</span><span class="w"/><span class="nx">v</span><span class="p">.</span><span class="nx">vcpu</span><span class="p">.</span><span class="nf">ExitReason</span><span class="p">()</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">case</span><span class="w"/><span class="nx">kvm</span><span class="p">.</span><span class="nx">ExitIO</span><span class="p">:</span><span class="w"/><span class="nx">v</span><span class="p">.</span><span class="nf">handleIO</span><span class="p">()</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">case</span><span class="w"/><span class="nx">kvm</span><span class="p">.</span><span class="nx">ExitMMIO</span><span class="p">:</span><span class="w"/><span class="nx">v</span><span class="p">.</span><span class="nf">handleMMIO</span><span class="p">()</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">case</span><span class="w"/><span class="nx">kvm</span><span class="p">.</span><span class="nx">ExitHLT</span><span class="p">:</span><span class="w"/><span class="k">return</span><span class="w"/><span class="kc">nil</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">case</span><span class="w"/><span class="nx">kvm</span><span class="p">.</span><span class="nx">ExitShutdown</span><span class="p">:</span><span class="w"/><span class="k">return</span><span class="w"/><span class="nx">errShutdown</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">case</span><span class="w"/><span class="nx">kvm</span><span class="p">.</span><span class="nx">ExitSystemEvent</span><span class="p">:</span><span class="w"/><span class="o">...</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="o">...</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="p">}</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="p">}</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>That switch is most of the VMM.<code>KVM_EXIT_IO</code> is dispatched to the serial stub, or to a small &ldquo;is this a reboot port write?&rdquo; detector.<code>KVM_EXIT_MMIO</code> is dispatched to whichever virtio transport happens to own the address the guest has just touched. Everything else either returns cleanly or surfaces as an error. Asynchronous work — the goroutine that reads frames from the tap into the guest&rsquo;s RX queue, the one that fires at a preset time and pauses the machine so that it can be snapshotted — lives alongside and talks to the guest by pulsing the in-kernel interrupt chip with<code>KVM_IRQ_LINE</code>.</p><p>I had expected, before writing any of this, that the VMM would be a thing of considerable mass. It is not. It is a switch statement and a handful of friends, and the body of it is the one file.</p><h2 id="a-kernel-boots-into-apparatus-i-had-just-finished-writing">A Kernel Boots Into Apparatus I Had Just Finished Writing</h2><p>Booting a real Linux kernel into a machine one has just built, without the supplied conveniences of a BIOS, is considerably less magical than it sounds and considerably more so than it ought to be.</p><p>Firecracker — and mini-firecracker behind it — uses<strong>PVH</strong>, the Xen-derived fast-boot protocol that permits a hypervisor to skip every byte of firmware and deposit the kernel directly at a 32-bit protected-mode entry point with a single pointer in<code>EBX</code>. The kernel&rsquo;s ELF image carries, among its notes, an<code>XEN_ELFNOTE_PHYS32_ENTRY</code> that names the address it wishes to resume from. One loads the program segments into guest memory at their declared<code>p_paddr</code>s, plants a small<code>hvm_start_info</code> struct at a known location and fills it with the cmdline and a memory map, sets up flat thirty-two-bit segments with a stub GDT, puts the start-info pointer in<code>EBX</code>, and calls<code>KVM_RUN</code>. Every subsequent transition — long mode, page tables, interrupt setup, the whole edifice of x86 housekeeping — the kernel arranges on its own behalf.</p><p>The package that does this is about six hundred lines, including the ELF parser and the start-info builder. The first kernel banner that emerged from my stubbed-up serial port was, frankly, unearned. Nothing I had written teaches the kernel anything about itself; the apparatus merely lays a table, and the kernel arrives and eats.</p><h2 id="virtio-stripped-to-sixteen-bytes-and-a-kick">virtio, Stripped to Sixteen Bytes and a Kick</h2><p>The guest, now booted into long mode and printing to a serial port, must be persuaded to see a disk and a network. This is what virtio is for.</p><p>virtio is a device-emulation contract between hypervisor and guest, organised around three shared-memory rings per device. The guest places buffer descriptors in an<em>available</em> ring; the device takes them, does its work, writes results, and places completed descriptors in a<em>used</em> ring. Both sides notify each other — the guest by writing a magic value to a doorbell register, the device by raising an interrupt on a configured IRQ line. This is the whole of the mechanism. There is no driver-specific negotiation more exotic than feature bits, no framing beyond the descriptor&rsquo;s<code>len</code> field, no locking that is not already implicit in the queue indices.</p><p>mini-firecracker implements the modern virtio-MMIO transport (version 2), the split virtqueue, and two device drivers on top of the shared plumbing. The first of these is<code>virtio-blk</code>, backed by a host file — the guest sees<code>/dev/vda</code>, the host sees whatever squashfs or raw image one handed it, and the translation between the two is a few dozen lines of descriptor parsing and<code>pread</code>/<code>pwrite</code>. A fragment of cmdline,<code>virtio_mmio.device=4K@0xd0000000:5</code>, which mini-fc auto-appends per<code>--drive</code>, tells the kernel where to find the device on the bus; one sets<code>root=/dev/vda</code> and adds<code>init=/bin/sh</code> and the guest, having mounted its root and finished its boot, drops the operator at a shell prompt on the same serial port the kernel was just writing to.</p><p>The second driver is<code>virtio-net</code>, which is structurally identical to<code>virtio-blk</code> — the same transport, the same ring mechanics — and differs only in its having two queues, for receive and transmit, and in being backed by a Linux tap device rather than a file. The transmit path is synchronous: when the guest kicks the TX queue, mini-fc walks the chain of buffers and writes the Ethernet frames out to the tap file descriptor. The receive path is asynchronous, for the good reason that the host kernel is the one deciding when a frame is due; a goroutine blocks on the tap fd, and when a frame arrives it pulls a buffer from the guest&rsquo;s RX queue, prepends the twelve-byte<code>virtio_net_hdr</code>, copies the frame in, and pulses the shared IRQ to tell the guest there is work. With a tap pre-created on the host, the guest comes up with an<code>eth0</code> that answers pings at sub-millisecond latency in both directions.</p><h2 id="a-computer-dumped-and-resumed">A Computer Dumped and Resumed</h2><p>Snapshotting and restoring a running virtual machine is the piece of Firecracker whose economics make AWS Lambda make sense. A fleet of pre-booted interpreters, pre-configured to the customer&rsquo;s exact image, can be thawed into running VMs faster than the request reaches them. To restore in the low tens of milliseconds is to render the concept of a cold start fiscally uninteresting.</p><p>mini-firecracker&rsquo;s snapshot is a directory on disk:</p><ul><li><code>manifest.json</code> — kernel path, cmdline, memory size, drive and net bindings, the configuration needed to reconstruct the VMM&rsquo;s outer shell.</li><li><code>state.json</code> — the vCPU&rsquo;s registers, the VM&rsquo;s own state, each virtio device&rsquo;s internal bookkeeping, with the larger opaque blobs base64-encoded so the JSON remains human-readable.</li><li><code>memory.bin</code> — the raw bytes of the guest&rsquo;s RAM.</li></ul><p>Restore is the reverse of every step that produced a snapshot. One<code>mmap</code>s a fresh memory region and copies the RAM in, replays every<code>KVM_SET_*</code> ioctl in the strict dependency order the kernel requires — clock, then IRQ chips, then the PIT, then CPUID, then SREGS, then REGS, then XSAVE, then XCRS, then FPU, then LAPIC, then MP state, then events, then MSRs — and calls<code>KVM_RUN</code> once more. The whole snapshot pipeline including device serialisation is something under eight hundred lines. Restore lands in sixty-five to seventy-seven milliseconds for a 128 MiB boot-only snapshot, and two hundred and sixty to two hundred and ninety milliseconds for the 512 MiB shell-with-networking case. The larger number is dominated by the<code>memory.bin</code> copy, which a<code>mmap(MAP_PRIVATE, fd)</code> of the snapshot file would skip entirely; that is a future optimisation I have not yet troubled to write.</p><p>I shall now narrate the three episodes, of the many that presented themselves, in which the thing declined to do what I had been expecting it to do.</p><h2 id="a-kernel-whose-binary-does-not-know-about-command-lines">A Kernel Whose Binary Does Not Know About Command Lines</h2><p>The kernel cmdline fragment<code>virtio_mmio.device=&lt;size&gt;@&lt;base&gt;:&lt;irq&gt;</code> is the documented means by which Linux learns about an MMIO device when neither Device Tree nor ACPI is available. mini-firecracker generates these fragments automatically, and on the firecracker-CI<strong>5.10</strong> kernel they work exactly as the documentation suggests.</p><p>They did not work on the firecracker-CI<strong>6.1</strong> kernel. I spent an embarrassing quantity of time hunting the problem through guest userspace, through the virtio dispatch code, through the cmdline I had been appending, and finally — having exhausted every hypothesis I could produce from the running system — through the kernel binary itself:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ strings testdata/vmlinux-6.1.155<span class="p">|</span> grep -iE<span class="s2">"Registering device virtio-mmio|virtio_mmio_cmdline"</span></span></span><span class="line"><span class="cl">$</span></span></code></pre></div></div></figure><p>Nothing at all. The cmdline-registration code path had been configured out at build time. Firecracker&rsquo;s CI kernel is produced under the assumption that device discovery happens via generated ACPI tables on x86, and so the cmdline-registration symbols are stripped from the binary. mini-firecracker does not generate ACPI tables; mini-firecracker accordingly pins the 5.10 kernel, and will until some future version of me decides that writing a small ACPI-table emitter is the evening he has left to spend.</p><p>The lesson, which I had not quite absorbed before this, is that<em>documented Linux interface</em> and<em>compiled into every kernel</em> are entirely distinct propositions. The kernel is a menu; distributions and build systems order from the menu; one&rsquo;s hypervisor must order from the same menu the guest did, or prepare to eat alone.</p><h2 id="a-console-that-would-not-deliver">A Console That Would Not Deliver</h2><p>The kernel, booted and speaking through the serial port, was the easy half. When the shell took over and I tried to type into it, an asymmetric failure declared itself. Typing was accepted; each character echoed back on the terminal.<code>ls /</code> produced a clean return to the prompt and nothing else. The kernel had announced, with its customary polite formality, &ldquo;Run<code>/bin/sh</code> as init process&rdquo;, and after that every byte of userspace output seemed to vanish into the apparatus I had built.</p><p>The shape of the asymmetry was the clue. Kernel<code>printk</code> reaches the UART via the<em>polled</em> write path — a sequence of direct<code>writel</code> instructions into the transmit register, each waiting for the previous to drain before emitting the next. Userspace<code>write()</code> calls arrive at the same UART through the tty layer, which uses the<em>interrupt-driven</em> transmit path: write one byte to the transmit holding register, set the transmitter-ready bit in the interrupt-enable register, wait for the interrupt that announces the byte has cleared, and only then emit the second byte. If the interrupt never fires, the tty driver is content to wait forever, the second byte never goes out, and the file descriptor looks, to a naive observer, to be in perfect working order.</p><p>My first-pass 16550A stub had no interrupt-identification register and no mechanism for raising IRQ 4 when the transmit holding register became empty. Some forty lines of additional state — tracking the interrupt-enable bits, firing IRQ 4 on transmit-enable and on each write to the holding register, modelling the interrupt-identification register with its priority scheme and its clear-on-read semantics — turned every tty write in the guest&rsquo;s userspace into something the operator could see. A parallel bug presented itself in the same session: writes to port<code>0x3f8</code> while the line-control register&rsquo;s<code>DLAB</code> bit was set were being routed to the operator&rsquo;s terminal, when they ought to have been routed to the baud-rate divisor latches. The consequence had been that the first byte of every shell session arrived as a control character,<code>\x0c</code>, until a single check on the<code>DLAB</code> bit ended the exhibition.</p><p>The general principle I should like to record here is that a kernel&rsquo;s satisfaction with its peripheral is not evidence of the peripheral&rsquo;s correctness. The kernel has polled pathways for its own use and interrupt pathways for everyone else&rsquo;s; a stub that implements only the former is a stub that supports only the kernel, and will deceive the operator that the guest&rsquo;s userspace has gone mute.</p><h2 id="it-is-always-the-msrs">It Is Always the MSRs</h2><p>The first snapshot-and-restore round-trip worked. This ought to have been suspicious, but I took it as a gift. The guest resumed, the restore reported seventy-seven milliseconds, and five lines of perfectly correct continuation arrived on the console — and then, with no hesitation, this:</p><figure class="code-terminal" data-lang="text"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">text</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">[mini-fc] restored from /tmp/snap1 in 77.258217ms</span></span><span class="line"><span class="cl">[ 0.472834] i8042: Can't read CTR while initializing i8042</span></span><span class="line"><span class="cl">[ 0.480069] Segment Routing with IPv6</span></span><span class="line"><span class="cl">[ 0.482567] bpfilter: Loaded bpfilter_umh pid 148</span></span><span class="line"><span class="cl">[ 0.483268] traps: PANIC: double fault, error_code: 0x0</span></span><span class="line"><span class="cl">[ 0.483287] RIP: 0000:0x0</span></span></code></pre></div></div></figure><p><code>RIP</code> at address zero is the tell, and it names the shape of the mistake before one has finished reading it. On x86-64, the<code>SYSCALL</code> instruction reads the kernel-side syscall entry point out of the model-specific register<code>MSR_LSTAR</code>, which lives at<code>0xC0000082</code>. If<code>MSR_LSTAR</code> is zero at the moment<code>SYSCALL</code> executes, every syscall jumps to RIP equals zero and the CPU triple-faults shortly thereafter. The<code>bpfilter</code> kernel module, whose job it is to spawn a small userspace helper, had forked the helper; the helper had made its first syscall; the CPU had done its honest best to find the entry point at the address the MSR pointed to, and found nothing.</p><p>I had saved, between the vCPU and the VM, every general-purpose register and every segment, every chip&rsquo;s state in sufficient detail to resume its interrupts, and the contents of every memory page. I had not saved any of the model-specific registers. The remedy is<code>KVM_GET_MSR_INDEX_LIST</code>, which asks the kernel for the canonical list of MSRs that round-trip safely, together with<code>KVM_GET_MSRS</code> and<code>KVM_SET_MSRS</code> to bulk-read and bulk-write them. The addition is some eighty lines. After it, every snapshot point I tested round-tripped without complaint.</p><p>There is a general principle that announced itself to me at that moment, with the loudness of a dropped tray, and that is this: when a kernel restores from saved state and immediately misbehaves at syscall entry, one forgot the MSRs. When it misbehaves in floating-point code, one forgot the<code>XSAVE</code> area. When its notion of wall-clock time jumps backwards, one forgot the kvmclock MSRs. Every half-resumed machine I have now watched misbehave has turned out to be a symptom of the same missing noun. It is, with a dreary reliability, always the MSRs.</p><h2 id="an-accounting-of-lines-and-milliseconds">An Accounting of Lines and Milliseconds</h2><p>Two tables, in lieu of what would otherwise be a much longer paragraph.</p><p>The restore timings across the three workloads I routinely test against:</p><table><thead><tr><th>Workload</th><th>Mem</th><th>Restore</th></tr></thead><tbody><tr><td>Kernel boot only, no devices</td><td>128 MiB</td><td>65–77 ms</td></tr><tr><td>virtio-blk plus interactive shell</td><td>512 MiB</td><td>285 ms</td></tr><tr><td>virtio-blk plus virtio-net plus ping</td><td>512 MiB</td><td>262 ms</td></tr></tbody></table><p>And the line counts, by package, for the curious:</p><table><thead><tr><th>Component</th><th>LoC</th></tr></thead><tbody><tr><td><code>pkg/kvm</code> — ioctl wrappers, state save/restore</td><td>~1,100</td></tr><tr><td><code>pkg/boot</code> — ELF, PVH, initial vCPU registers</td><td>~600</td></tr><tr><td><code>pkg/virtio</code> — transport, virtqueue, block, net</td><td>~700</td></tr><tr><td><code>pkg/vmm</code> —<code>KVM_RUN</code> loop, serial, snapshot glue</td><td>~1,100</td></tr><tr><td><code>pkg/snapshot</code> — on-disk format</td><td>~250</td></tr><tr><td><code>pkg/tap</code> —<code>/dev/net/tun</code> wrapper</td><td>~100</td></tr><tr><td>Other — CLI, host check, docs, tests</td><td>~1,400</td></tr><tr><td><strong>Total</strong></td><td><strong>~5,300</strong></td></tr></tbody></table><p>A single external dependency,<code>golang.org/x/sys</code>. A statically linked binary of some four megabytes, which is, as these things go, closer to a negotiating position than a figure.</p><h2 id="afterwards">Afterwards</h2><p>Two propositions have outlasted the code itself, and it is worth setting them down before the memory of the evenings that produced them has faded.</p><p>The first is that the conceptual layer of a microVM monitor is exceedingly thin. A working VMM is<code>KVM_RUN</code> inside a switch statement on the exit reason. virtio is a sixteen-byte descriptor format, two queue indices in shared memory, and a doorbell. A snapshot is sixteen or so<code>KVM_GET_*</code> ioctls, an<code>mmap</code>, and a list of model-specific registers one remembered to enumerate. I had expected a body of arcane knowledge; what I found was a short catalogue of contracts, each of which, once named, was not difficult to honour.</p><p>What makes Firecracker — or any production microVM monitor — is, I can now report with some confidence, not the microVM. It is everything that surrounds the microVM: the jailer that wraps the VMM in a seccomp profile and a chroot and a cgroup and writes down exactly what system calls the VMM process itself is permitted to make; the REST API that drives the control plane in a form the orchestrator expects; the CPU-template system that pins guest-visible CPUID leaves across host generations so that a fleet of Lambda workers can be live-migrated without the guests noticing they have moved from one generation of silicon to another; the rate limiters on I/O and network; the metrics; the careful accommodation of every CVE that has ever emerged from the KVM stack. The interesting part of a production microVM monitor is not the microVM. It is the production. mini-firecracker stops where the concept has been demonstrated, which is precisely where the easy part ends.</p><p>The second is what one gets out of building small versions of things one admires. Reading Firecracker&rsquo;s upstream Rust is, on its own merits, pleasant; it is a clean codebase and one learns from it. But having built a smaller one has the curious effect of making the larger one legible in a way that reading it alone does not produce. I can now open<code>firecracker/src/vmm/src/persist.rs</code> and recognise, in the ordering of its calls, the shape of the triple-fault I encountered at midnight and its MSR-shaped remedy. The small version is not a replacement for the large one; it is a reader&rsquo;s aid to it.</p><h2 id="an-honest-list-of-absences">An Honest List of Absences</h2><p>A small-minded completeness suggests it is worth recording, for any reader tempted to extend the project or mistake it for a production tool, the places where it declines to do what a production tool would. In rough order of how painful their absence is likely to be:</p><p>Snapshot-while-idle does not fire. The pause flag is examined at the next<code>KVM_RUN</code> boundary, and a<code>HLT</code>-ed guest stays in the kernel until an interrupt rouses it; the standard remedy is<code>KVM_SET_SIGNAL_MASK</code> paired with a<code>tgkill</code> at the vCPU&rsquo;s OS thread.</p><p>Restore copies the memory from disk into a fresh<code>mmap</code>. The Lambda-grade trick is<code>mmap(MAP_PRIVATE, fd)</code> of the snapshot file itself — the first guest write copy-on-writes the affected page, every unread page stays on disk, and a 512 MiB restore drops from the high hundreds of milliseconds to something in the low single digits.</p><p>No ACPI table emitter exists, so the firecracker-CI 6.1 kernel remains off-limits. The 5.10 kernel is pinned in the testdata.</p><p>No jailer, no REST API, no PCI, no GPU, no live migration. mini-firecracker stays small enough to read, which is the entire point.</p><p>The next thing on this axis I should like to build is a common bench harness — runc, runsc, mini-fc, and real Firecracker on the same host, on the same workloads, with the same instrumentation — now that I have spent a few weeks with each. The numbers, having been sat with, are likely to be more interesting to read.</p><p>The code is at<a href="https://github.com/mtclinton/mini-firecracker">github.com/mtclinton/mini-firecracker</a>. Its sibling on the gVisor axis remains<a href="https://github.com/mtclinton/mini-sentry">github.com/mtclinton/mini-sentry</a>, and the earlier writeups of that project are linked at the top of this one.</p>
]]></content:encoded></item><item><title>Running What One Did Not Write</title><link>https://mtclinton.com/posts/running-what-one-did-not-write/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/running-what-one-did-not-write/</guid><category>code</category><description>The shell one-liner, which twenty years ago required a trip to Usenet and the confidence of a stranger, is now produced by a language model the moment one asks for an installation or a fix. I type curl | sh more often than I ought to, and I read what sh is about to receive less often than I should. A Go tool&rsquo;s install instructions arrive as a pipe through a shell. A forum answer suggests a bash -c the length of a paragraph. The LLM, asked for a build script, cheerfully produces one and expects no audit. The terminal, being an instrument of considerable trust, obliges one to extend that trust to whatever it is about to consume. Most of the time this is fine. Some of the time it is not, and one has a poor morning of it afterwards.</description><content:encoded>&lt;![CDATA[<p>The shell one-liner, which twenty years ago required a trip to Usenet and the confidence of a stranger, is now produced by a language model the moment one asks for an installation or a fix. I type<code>curl | sh</code> more often than I ought to, and I read what<code>sh</code> is about to receive less often than I should. A Go tool&rsquo;s install instructions arrive as a pipe through a shell. A forum answer suggests a<code>bash -c</code> the length of a paragraph. The LLM, asked for a build script, cheerfully produces one and expects no audit. The terminal, being an instrument of considerable trust, obliges one to extend that trust to whatever it is about to consume. Most of the time this is fine. Some of the time it is not, and one has a poor morning of it afterwards.</p><p>What I wanted was a small third thing, between the two choices the situation presently offers. The first choice is to run the script as oneself, which is the default and, in the ordinary run of things, what actually happens. The second is to spin up a virtual machine, which involves a disk image, a kernel, a network bridge, and a ten-minute detour before the original question — &ldquo;will this command do what it claims?&rdquo; — can be asked. I wanted a command one could paste in front of any other command and be done with it — something that would turn the whole affair into a brief, constrained, untrusted episode, cleared away at the end.</p><p>The result is<code>gvisor-exec</code>, and it does this:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ gvisor-exec -- uname -a</span></span><span class="line"><span class="cl">Linux gvisor-exec 4.4.0 #1 SMP Sun Jan 10 15:06:54 PST 2016 x86_64 GNU/Linux</span></span></code></pre></div></div></figure><p>The<code>4.4.0</code> is the tell. gVisor ships with a spoofed kernel version baked into its Sentry, and every program that asks<code>uname()</code> is answered with<code>4.4.0</code> regardless of the kernel the host is actually running. The syscalls the guest makes never touch the host kernel at all; they are intercepted and re-implemented in a userspace kernel written in Go. What arrives at the host is not the guest&rsquo;s syscalls but the Sentry&rsquo;s requests on the guest&rsquo;s behalf, which are themselves run under a seccomp filter that refuses most of the interesting ones.</p><p>No Docker is involved. No containerd. No root. The binary wraps<code>runsc</code> in rootless mode, produces an OCI bundle in a temp directory, runs the command, and tears everything down.</p><h2 id="a-command-between-bash-and-a-hypervisor">A Command Between Bash and a Hypervisor</h2><p><code>gvisor-exec</code> is one Go binary of perhaps five hundred lines, half of which is the OCI spec builder and its validation. It wraps<code>runsc --rootless</code> behind a CLI tuned for one-shot sandboxing. The defaults encode a stance on what it means to &ldquo;just run this thing&rdquo;: the host<code>/</code> is visible read-only, writes land in an ephemeral overlay that is discarded on exit, network is off, every capability is dropped, and the sandbox receives its own PID, mount, IPC, UTS, and network namespaces. The process is isolated along every dimension the kernel offers and a few it does not.</p><p>In the ordinary idiom, the uses look like this:</p><figure class="code-terminal" data-lang="shell"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">shell</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># A script from a forum, piped in.</span></span></span><span class="line"><span class="cl">cat sus.sh<span class="p">|</span> gvisor-exec -- /bin/sh</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="c1"># A build that reads from the current directory.</span></span></span><span class="line"><span class="cl">gvisor-exec -bind<span class="s2">"</span><span class="nv">$PWD</span><span class="s2">:/mnt"</span> -cwd /mnt -- make</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="c1"># The same build, returning its output as a tarball on stdout.</span></span></span><span class="line"><span class="cl">gvisor-exec -ro-bind<span class="s2">"</span><span class="nv">$PWD</span><span class="s2">:/mnt"</span> -- sh -c<span class="s1">'cd /mnt &amp;&amp; make &amp;&amp; tar c build/'</span> &gt; out.tar</span></span></code></pre></div></div></figure><p>The implementation, taken in isolation, is embarrassingly boring.<code>gvisor-exec</code> composes a<code>Config</code> struct into an OCI runtime-spec JSON, writes the JSON to<code>/tmp/gvisor-exec-XXXX/config.json</code>, execs<code>runsc --rootless ... run --bundle $dir $id</code>, forwards stdio, waits, returns the exit code, and removes the bundle. The Go source is a templating engine in one hand and an<code>exec.Cmd</code> in the other. What makes the tool useful is not the code at all but the set of defaults the code encodes — and arriving at those defaults was the work. The rest of this is a record of how I arrived at them, in the order in which the arriving actually happened.</p><h2 id="the-library-that-will-not-be-a-library">The Library That Will Not Be a Library</h2><p>I had begun with the fond expectation that I would<code>import gvisor.dev/gvisor/pkg/sentry/...</code> and drive the Sentry directly from my own Go program. This is not on offer. The gVisor packages are not structured for external consumers — their interfaces assume internal coordination with the rest of gVisor&rsquo;s machinery, the build system is Bazel and not easily persuaded otherwise, and the glue between the Sentry and its platform is not publicly exposed at all. One can read the code with profit; one cannot link against it with any pleasure.</p><p>The practical path is to treat<code>runsc</code> as a black-box binary with a stable CLI and shell out to it. Every other OCI-layer integration I have examined takes the same route: containerd&rsquo;s<code>shim-runsc-v1</code>, Kata&rsquo;s optional gVisor mode, the various systemd experiments, the CI runners that need a per-job sandbox.<code>runsc</code> is the supported entry point. The Sentry is the implementation detail. That division is not incidental, and it is worth accepting without argument.</p><h2 id="the-arithmetic-of-being-ones-own-root">The Arithmetic of Being One&rsquo;s Own Root</h2><p><code>runsc --rootless</code> installs a user namespace of one entry: host uid 1000 is mapped to sandbox uid 0. The sandbox&rsquo;s root, in other words, is me. There is no escalation in any meaningful sense; it is a spelling of my own identity, in a namespace that permits only that one spelling and no other.</p><p>I had initially configured the sandbox process to run as uid 1000, on the theory that a sandbox process should not appear, even to itself, to be root. The sandbox started. The files on my bind-mounted directory could be read. Writing to the same files returned<code>EACCES</code>. I spent longer than I care to confess working out why.</p><p>The arithmetic, once one sets it down, is not subtle. A file on the host is owned by uid 1000 (myself). Inside the user namespace, that same file appears owned by uid 0 — the only uid the namespace knows how to spell. The sandbox process is running as uid 1000, which is not the file&rsquo;s apparent owner and not in any group that owns it, and so for the purposes of permission checks it is &ldquo;other&rdquo;. Mode<code>0755</code> on a file whose owner is someone else leaves &ldquo;other&rdquo; with<code>r-x</code>. No write bit.<code>EACCES</code>.</p><p>The remedy is to default the sandbox uid and gid to 0. The sandbox process is then, from its own point of view, the owner of the files it wants to write to, which it was all along — the namespace having quietly relabelled my identity at the door. The mapping is still the same single-entry identity map; the process is simply standing where the mapping expects it to stand.</p><h2 id="an-overlay-wider-than-advertised">An Overlay Wider Than Advertised</h2><p>runsc&rsquo;s overlay behaviour is controlled by an<code>--overlay2</code> flag that takes a<code>{mount}:{medium}</code> pair. The first half is either<code>root</code> — an overlay on the rootfs only — or<code>all</code>, an overlay on every mount in the bundle. The second selects the storage:<code>self</code> is a tmpfs scratch directory the sandbox creates,<code>memory</code> is RAM, and so on.</p><p>I had started with<code>root:self</code> under the assumption that the rootfs overlay was what I wanted and that the bind mounts would quietly behave. This was wrong in a way that presented itself on the user as a bewildering failure. Writes to the bind-mounted directory returned<code>EINVAL</code> on<code>openat(..., O_CREAT, ...)</code>. The strace was unambiguous — the syscall was legal, the target directory existed, and the flags I had passed were plausible — and yet the Sentry, in the end, returned<code>EINVAL</code>. One can reproduce the shape of the problem without knowing anything about gVisor: the kernel has said the request is legal, and something after the kernel has disagreed.</p><p>After some time spent in runsc&rsquo;s debug logs I switched to<code>all:self</code>. The failures stopped, every mount received its own overlay, and writes landed in temp storage as intended. I did not pursue the original defect to its source.<code>root:self</code> plus writable bind mounts is, I suspect, an edge case in rootless mode that the maintainers have not been handed a reproducer for, and my workaround cost nothing. I did not file an issue. I did, however, write the decision down, which is why I am writing it down again now.</p><h2 id="the-gofer-cannot-make-your-directories">The Gofer Cannot Make Your Directories</h2><p>gVisor&rsquo;s filesystem is served to the sandbox by a separate trusted process called the Gofer, which speaks 9P over a socket to the Sentry and holds the only handles into the host filesystem. If the rootfs is the host<code>/</code>, as the defaults of<code>gvisor-exec</code> arrange, the Gofer has no permission to create directories anywhere on it. The host filesystem is to be read, not written.</p><p>The practical consequence is that bind-mount destinations must already exist on the host.<code>gvisor-exec -bind "$PWD:/work"</code> fails, because<code>/work</code> is a directory I have never created and which the Gofer cannot create on my behalf. The error<code>runsc</code> returns, in this case, is not a diagnostic but a condolence:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">cannot read client sync file: waiting for sandbox to start: EOF</span></span></code></pre></div></div></figure><p>The chain of events, reconstructed after the fact, is that the Gofer died attempting<code>mkdir("/proc/fs/root/work")</code>, the Sentry could not complete its handshake with a Gofer that was no longer on the line, and the handshake pipe accordingly reported EOF to whichever process was still reading it. The operator is told that something has gone wrong, and that is all.</p><p>I now validate this case ahead of time. If the rootfs is<code>/</code>, every bind-mount destination is<code>os.Stat</code>&rsquo;d before the spec is handed off to<code>runsc</code>, and a missing destination produces an error of my own devising that names the missing path. The operator is told that<code>bind destination "/work" does not exist on host</code>, which is, unlike an EOF, a problem an operator can act on. The general lesson I should like to set down here is a habit rather than a fix: when a subprocess&rsquo;s error messages are an entreaty rather than a diagnostic, catch the precondition in one&rsquo;s own code and produce a diagnostic of one&rsquo;s own.</p><h2 id="a-network-in-name-only">A Network In Name Only</h2><p><code>runsc</code>&rsquo;s default network mode,<code>sandbox</code>, creates a<code>veth</code> pair and installs iptables rules to route packets through the Sentry&rsquo;s userspace network stack. Neither operation is available to a rootless user, and so the attempt announces itself plainly enough:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">failed to run /usr/bin/ip link add ve-runsc-...: exit status 2</span></span></code></pre></div></div></figure><p><code>--network=host</code> is the remaining option, and on paper it places the sandbox in the host&rsquo;s network namespace. In rootless mode this does not produce a working network so much as a skeleton of one. The routing table inside the sandbox is effectively empty;<code>/proc/net/route</code> returned me only its header row. DNS failed to resolve a single query. Direct connections to a literal IP address might succeed if one were fortunate in the configuration, and I did not dig further to establish the conditions under which they did. For a one-shot sandbox whose chief virtue is containment, the correct default is<code>none</code>, and that is what<code>gvisor-exec</code> picks.</p><p>Every serious tool that wants real network behaviour under a rootless-ish gVisor — the GitHub-hosted runners, modal.com&rsquo;s runtime — has an out-of-band arrangement for the network. There is typically a privileged host process that pre-creates the<code>veth</code>, or a proxy the sandbox punches through to. For<code>gvisor-exec</code> I kept<code>-network host</code> available, documented its limitations, and moved on. A sandbox that cannot speak to the internet is, for my purposes, a feature.</p><h2 id="writes-one-does-not-mean-to-keep">Writes One Does Not Mean to Keep</h2><p>I had, on arriving at the overlay question, held the view that &ldquo;writes should persist to the source directory&rdquo; was the obvious default. Between the<code>EINVAL</code> quirk and the user-namespace permission model, making this work cleanly was a project in itself, and as the yak shave lengthened I began to suspect that I had misread the requirement.</p><p>For the nine commands out of ten one would plausibly run under a tool of this kind, ephemeral writes are in fact the correct semantic. The script one does not trust should be permitted to believe that it has written its output. The output should not arrive on the host. If the operator wants some bytes back, the sandbox is given an instrument — tar to stdout, a file descriptor redirected on the way out, an explicit volume mount meant for the purpose — and the rest is discarded without ceremony. The defaults, I realised, were being asked to serve paranoia and not convenience, and paranoia is better served by forgetting than by remembering.</p><p>Having committed to the ephemeral default, the tool&rsquo;s CLI fell out very naturally. The idiom matches, without any conscious borrowing, the way people use<code>firejail</code>,<code>bubblewrap</code>, and every container-based &ldquo;scratch pad&rdquo; the industry has produced. One writes into a thing that will evaporate. If one wants bytes out, one reaches in for them deliberately.</p><h2 id="a-spec-smaller-than-its-reputation">A Spec Smaller Than Its Reputation</h2><p>I had been quietly dreading the OCI runtime spec. I had an image in my head of committee meetings and a thousand optional fields, a document composed by twelve organizations in mutual suspicion.</p><p>The spec one actually needs for a single sandboxed command is about thirty fields. Most of them are set to constants: an empty capability list, one rlimit, five namespaces, four default mounts, a process argv, a working directory, a terminal flag. It is one Go struct with some nested structs, a<code>json.MarshalIndent</code>, and a unit test that round-trips the result through<code>json.Unmarshal</code> to confirm that one has not produced JSON one&rsquo;s self cannot read back.</p><p>One now understands, in a concrete way, why every container runtime that is not<code>runc</code> or<code>runsc</code> — Kata, Youki, crun — is implementable in a reasonable amount of code. The runtime spec is small. The hard part is the material that surrounds it: the image-unpacking and filesystem-layering, the CRI integration, the platform syscall interception.<code>gvisor-exec</code> gets to skip every last one of those, because<code>runsc</code> does them.</p><h2 id="afterwards">Afterwards</h2><p>The project is a Go binary of the sort that lives in a single directory, a handful of test files, a Makefile, and five runnable examples. It is at<a href="https://github.com/mtclinton/gvisor-exec">github.com/mtclinton/gvisor-exec</a>, and it requires<code>runsc</code> on the host; the static binary from<a href="https://gvisor.dev/docs/user_guide/install/">gvisor.dev</a> installs in a single<code>curl</code>. It is, by any honest metric, a wrapper. What I took from building it, though, is not the wrapper but the set of postures the wrapper encodes.</p><p>The first is that gVisor&rsquo;s threat model is a model of<em>interception</em>, not of<em>permission</em>. The interesting thing about a sandboxed command is not the long list of capabilities it does not have; it is the fact that its syscalls do not reach the host kernel at all. A kernel vulnerability inside<code>write()</code> is, as the earlier gVisor writeups of mine keep wanting to say, of no consequence whatever to a sandbox whose guest never causes the host to run<code>write()</code>. This reframes the defaults. One turns off the network not because the command might try to exfiltrate, but because the small surface of the Sentry&rsquo;s network stack is still larger than the surface one wants the untrusted command to have access to. One runs with no capabilities not to prevent the command from doing anything with them, but to shrink the number of behaviours the Sentry has to correctly re-implement.</p><p>The second is that ephemeral state is a sharper tool than permission state. A file the command wrote but which does not exist after the command has exited is more strictly controlled than a file the command wrote to a location one had tried to permission correctly. The former cannot be left behind; the latter can, and one has to reason about the manner in which it might be left. In every non-trivial sandbox I have built or configured, the cheapest safety comes from things that do not persist, not from things that were not allowed.</p><p>The third is that the hardest work in a tool like this lives in the defaults, and the defaults are load-bearing in proportion to how unobvious they were to arrive at.<code>uid=0</code>,<code>all:self</code>,<code>-network none</code>,<code>root</code> as read-only, bind-mount preconditions validated in the wrapper — every one of these was a day I spent not understanding something, and every one of them was subsequently hidden behind a flag the operator does not need to set. A good wrapper is a monument to the bad mornings of the author who wrote it. I take this, on the whole, as a reasonable arrangement.</p><p>The repository, again, is<a href="https://github.com/mtclinton/gvisor-exec">github.com/mtclinton/gvisor-exec</a>; it is MIT-licensed and perhaps five hundred lines of Go. The examples under<code>examples/</code> are the quickest way to acquire a working sense of the CLI. If one is curious to read the defaults and the reasons for them in the place they actually live,<code>spec.go</code> is the file to start with.</p>
]]></content:encoded></item><item><title>The Sections One Did Not Ask For</title><link>https://mtclinton.com/posts/the-sections-one-did-not-ask-for/</link><pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-sections-one-did-not-ask-for/</guid><category>code</category><description>A compiler, asked to produce an object file from three lines of assembly, will produce a good deal more besides. It will emit debug sections describing the provenance of the program. It will deposit a .note.gnu.property record attesting to the object&rsquo;s compatibility with Intel&rsquo;s control-flow enforcement. It will insert, around any function it is given, a stack-guard reference against the possibility that some absent buffer may one day overrun itself. And should the source indulge in a __builtin_unreachable, it will plant a trap call into the undefined-behaviour sanitiser runtime on the cheerful assumption that such a runtime is available to be linked against. A linker, if it intends to consume this output with any equanimity, must reach a settled opinion about each of these items. My linker, I discovered, had reached no such opinion. It refused them all, in series, and declined to say which of them was the cause.</description><content:encoded>&lt;![CDATA[<p>A compiler, asked to produce an object file from three lines of assembly, will produce a good deal more besides. It will emit debug sections describing the provenance of the program. It will deposit a<code>.note.gnu.property</code> record attesting to the object&rsquo;s compatibility with Intel&rsquo;s control-flow enforcement. It will insert, around any function it is given, a stack-guard reference against the possibility that some absent buffer may one day overrun itself. And should the source indulge in a<code>__builtin_unreachable</code>, it will plant a trap call into the undefined-behaviour sanitiser runtime on the cheerful assumption that such a runtime is available to be linked against. A linker, if it intends to consume this output with any equanimity, must reach a settled opinion about each of these items. My linker, I discovered, had reached no such opinion. It refused them all, in series, and declined to say which of them was the cause.</p><p>This is the story of finding out what, exactly, it was refusing.</p><h2 id="a-linker-conceived-in-private">A Linker, Conceived in Private</h2><p>The project — I called it<code>zelf</code>, which is short for Zig and ELF, and which I discovered rather late is also a Dutch word meaning<em>self</em> — was intended to link one executable, by the most direct means I could contrive. The target was Linux x86-64. The input was ELF64 relocatable objects. The output was a single statically linked binary with no dynamic loader, no shared libraries, and no concessions to modernity beyond what the kernel itself demanded. The point of the exercise was not to compete with anyone. It was to discover, by refusing every convenience, what steps lay between a pair of<code>.o</code> files and the brief, useful thing the kernel eventually runs.</p><p>The resulting system occupies four modules of about a thousand lines each. A reader parses ELF64 object files into their constituent sections, symbols, and relocation entries. A relocations module implements the small handful of x86-64 fixups that a static link actually needs —<code>R_X86_64_64</code>,<code>R_X86_64_PC32</code>,<code>R_X86_64_PLT32</code>, and<code>R_X86_64_GOTPCREL</code>, the last of which, in the absence of a real global offset table, reduces to the same arithmetic as<code>PC32</code> and costs the linker nothing to implement. A writer computes segment layout, emits a program header and a single R+X<code>PT_LOAD</code>, and writes the bytes. A CLI ties them together in the obvious order.</p><p>Every module owned its tests, eighty-six in all, and for an agreeable stretch the feedback loop was the pleasant one of writing a test, watching it fail for the reason I expected, and then watching it pass. The culminating exercise was a small fixture — an object file I had hand-assembled, byte by byte, to mimic what I believed<code>gcc -c</code> would produce. The linker accepted it, emitted a valid executable, and the VM I keep for these purposes ran the result and exited with status 0. I told myself, in the tone of a man who has built a thing he does not yet understand, that I had built a linker.</p><h2 id="the-compilers-letters-of-introduction">The Compiler&rsquo;s Letters of Introduction</h2><p>The temptation, once the tests are green, is to feed the thing something one did not write oneself. The smallest real input I could think of was a C file whose<code>_start</code> issued the Linux<code>exit</code> syscall through a sliver of inline assembly.</p><figure class="code-terminal" data-lang="c"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">c</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">void</span><span class="nf">_exit</span><span class="p">(</span><span class="kt">long</span><span class="n">code</span><span class="p">)</span><span class="p">{</span></span></span><span class="line"><span class="cl"><span class="k">asm</span><span class="k">volatile</span><span class="p">(</span><span class="s">"syscall"</span><span class="o">:</span><span class="o">:</span><span class="s">"a"</span><span class="p">(</span><span class="mi">60</span><span class="p">),</span><span class="s">"D"</span><span class="p">(</span><span class="n">code</span><span class="p">));</span></span></span><span class="line"><span class="cl"><span class="nf">__builtin_unreachable</span><span class="p">();</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span><span class="line"><span class="cl"><span class="kt">void</span><span class="nf">_start</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="p">{</span><span class="nf">_exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="p">}</span></span></span></code></pre></div></div></figure><p>This is as plain as a Linux program gets. No globals, no library calls, no data section, not even a return from<code>_start</code>. I compiled it with the cross-compiler Zig so usefully bundles —</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">zig cc -target x86_64-linux-gnu -c -fno-PIC -ffreestanding -nostdlib hello.c -o hello.o</span></span></code></pre></div></div></figure><p>— fed the resulting object to my linker, and was told, curtly, that there was an<code>UnresolvedSymbol</code>.</p><p>No name. Just the name of the error.</p><p>This struck me, even in the moment, as a defect of diagnostic manners rather than of logic. A diagnostic that says a symbol is missing but declines to name it has the character of a servant announcing a visitor without asking who the visitor is. I reached for<code>nm</code>:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">U __ubsan_handle_builtin_unreachable</span></span></code></pre></div></div></figure><p>The clang shipped inside Zig, it turns out, is configured by default to emit a trap-call into the undefined-behaviour sanitiser runtime whenever one writes<code>__builtin_unreachable()</code>. The program I had taken to be the smallest possible Linux program was, in quiet fact, a program that demanded a sanitiser library I had no intention of supplying. The compiler had posted a letter of introduction in my program&rsquo;s name, and the recipient was a library I did not possess.</p><p>I deleted the<code>__builtin_unreachable</code>, a hint I had written only because I had been trained, long since, to mark non-return to compilers that cared.<code>zig cc</code> dutifully produced an object without a UBSan reference. My linker, inspecting it, announced that it had failed to resolve<code>__stack_chk_fail</code>.</p><p>The stack protector is a feature I admire in production code and had, by some oversight of principle, given no thought to at all while writing a toy program. Clang was inserting a guard around my<code>_start</code> function and a reference to<code>__stack_chk_fail</code> against the possibility that a buffer overrun might trip it. There are no buffers in<code>_start</code>. No overrun is possible. The compiler is not in a position to know this, and does its duty.</p><p><code>-fno-stack-protector</code>, I added.</p><h2 id="a-diagnostic-lacking-its-subject">A Diagnostic Lacking Its Subject</h2><p>The next refusal came differently. My linker did not now complain of an unresolved symbol. It complained, unhelpfully, of a<code>BadTargetSection</code>.</p><p>I set about reasoning at the compiler in flags. I added<code>-fno-asynchronous-unwind-tables</code> and<code>-fno-unwind-tables</code>, on the thesis that clang was emitting<code>.eh_frame</code> sections with relocations my linker was not prepared to handle. I added<code>-fcf-protection=none</code>, because clang on recent toolchains decorates its objects with<code>.note.gnu.property</code> metadata attesting to Intel CET compatibility. I added<code>-fno-sanitize=all</code>, out of a developing conviction that whatever sanitiser had been asleep was about to wake up. I added<code>-fno-builtin</code>, in the fear that clang might decide my two-instruction<code>_start</code> was a better candidate for an intrinsic than I had dared to anticipate.</p><p>None of this helped. The error remained<code>BadTargetSection</code>, unadorned and uncurious about its own subject.</p><p>It is a property of small linkers, I was beginning to realise, that they can be persuaded to produce executables by the grace of their authors, but that they meet real-world input with a faint air of surprise. Every flag I added was, in effect, an apology to the linker for the compiler&rsquo;s competence.</p><p>I gave up on C. If clang could not be coaxed into emitting only the sections my linker recognised, I would bypass the compiler altogether and hand it pure assembly, which would surely yield an object file consisting of nothing but instructions and bookkeeping.</p><figure class="code-terminal" data-lang="asm"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">asm</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-asm" data-lang="asm"><span class="line"><span class="cl"><span class="na">.global</span><span class="no">_start</span></span></span><span class="line"><span class="cl"><span class="na">.text</span></span></span><span class="line"><span class="cl"><span class="nl">_start:</span></span></span><span class="line"><span class="cl"><span class="nf">movq</span><span class="no">$60</span><span class="p">,</span><span class="nv">%rax</span></span></span><span class="line"><span class="cl"><span class="nf">xorq</span><span class="nv">%rdi</span><span class="p">,</span><span class="nv">%rdi</span></span></span><span class="line"><span class="cl"><span class="nf">syscall</span></span></span></code></pre></div></div></figure><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">zig cc -target x86_64-linux-gnu -c -nostdlib hello.s -o hello.o</span></span></code></pre></div></div></figure><p>A nine-byte function, emitted from six lines of assembly, containing no C runtime whatever. My linker, examining it, announced<code>BadTargetSection</code> once again and declined to produce an output file.</p><p>I was, I will admit, briefly uncharitable toward Zig.</p><h2 id="readelf-being-candid">readelf, Being Candid</h2><p>The first and most instructive act of any debugging session that has stopped responding to guesses is to look at the actual evidence. I installed the GNU binutils, pointed<code>readelf -S</code> at the insulting little object file, and was handed a list of thirteen sections:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">[ 1] .text PROGBITS AX</span></span><span class="line"><span class="cl">[ 2] .debug_info PROGBITS</span></span><span class="line"><span class="cl">[ 3] .rela.debug_info RELA</span></span><span class="line"><span class="cl">[ 4] .debug_abbrev PROGBITS</span></span><span class="line"><span class="cl">[ 5] .debug_aranges PROGBITS</span></span><span class="line"><span class="cl">[ 6] .rela.debug_aranges RELA</span></span><span class="line"><span class="cl">[ 7] .debug_line PROGBITS</span></span><span class="line"><span class="cl">[ 8] .rela.debug_line RELA</span></span><span class="line"><span class="cl">[ 9] .note.GNU-stack PROGBITS</span></span><span class="line"><span class="cl">[10] .symtab SYMTAB</span></span><span class="line"><span class="cl">[11] .shstrtab STRTAB</span></span><span class="line"><span class="cl">[12] .strtab STRTAB</span></span></code></pre></div></div></figure><p>For a three-instruction function,<code>zig cc</code> had produced four DWARF debug sections, three accompanying relocation sections, a note section, and the usual metadata. Only<code>.text</code> carried the flag<code>A</code>, meaning<em>allocatable</em>, meaning<em>destined to live somewhere in the final executable&rsquo;s virtual address space</em>. Everything else was information the compiler felt obliged to emit and which a linker was expected to do something sensible about.</p><p>The revelation was in the relocations. The object contained eight fixups in total, and every one of them targeted a<code>.debug_*</code> section, not<code>.text</code>. My linker had been traversing the entire relocation set, looking up the target section for each, and finding — quite correctly — that sections like<code>.debug_info</code> were present in the object but had no vaddr, no bytes in the layout, no place to land. It had interpreted this as a malformed input and refused to proceed.</p><p>A real linker does not behave this way. A real linker, when it decides to strip debug information from a static output, does not merely drop the debug sections — it also drops the relocations that refer to them. The relocations, orphaned of any destination, have no reason to exist once their targets have been discarded. To carry them forward and then object that they have no home is to misunderstand what stripping means.</p><h2 id="a-patch-that-mostly-declines">A Patch That Mostly Declines</h2><p>The fix, once the shape of the problem is clear, is embarrassingly small. A linker must distinguish three states for every section index in an input object:</p><ol><li>The section is allocatable and has been laid out in the output. Its relocations are applied in place.</li><li>The section does not exist, or is a bookkeeping slot that no real content occupies. A relocation against it is genuinely malformed, and an error is appropriate.</li><li>The section exists, but is non-allocatable — debug information, a comment, a GNU note — and has been intentionally dropped from the output. Its relocations should be silently skipped, without ceremony.</li></ol><p>The existing code collapsed (2) and (3) into a single error condition. I added an<code>ignored</code> field to the per-section dispatch table. When the CLI marks every non-allocatable section as ignored, the relocation batch driver skips over orphan fixups rather than erring on them. The change was perhaps a dozen lines, most of them comments.</p><figure class="code-terminal" data-lang="zig"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">zig</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="c1">// Section exists in the input but was intentionally dropped from the</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// output layout because it isn't allocatable (.debug_*, .comment,</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// .note.*, etc.). Mark the slot as ignored so any .rela.* relocations</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// targeting it are silently skipped rather than erroring out. Real</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// linkers behave the same way when stripping debug info.</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"/><span class="p">((</span><span class="n">sec</span><span class="p">.</span><span class="n">sh_flags</span><span class="w"/><span class="o">&amp;</span><span class="w"/><span class="n">reader</span><span class="p">.</span><span class="n">SHF_ALLOC</span><span class="p">)</span><span class="w"/><span class="o">==</span><span class="w"/><span class="mi">0</span><span class="p">)</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">targets</span><span class="p">[</span><span class="n">li</span><span class="p">]</span><span class="w"/><span class="o">=</span><span class="w"/><span class="p">.{</span><span class="w"/><span class="p">.</span><span class="n">ignored</span><span class="w"/><span class="o">=</span><span class="w"/><span class="kc">true</span><span class="w"/><span class="p">};</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>The next run accepted the unmodified<code>zig cc</code> output, processed eleven symbols and ten relocations of which nine targeted debug sections and were quietly ignored, and produced a valid x86-64 ELF executable that<code>file</code> reported as statically linked. The eighty-six existing tests continued to pass. An eighty-seventh, asserting that relocations against an ignored section are skipped without emission, joined them.</p><p>I also took the small liberty of threading the unresolved symbol&rsquo;s name through its error, so that the next operator who met the first class of failure would at least be told the missing symbol was called<code>__stack_chk_fail</code> rather than merely that some symbol somewhere was missing. The original diagnostic had saved bytes at the cost of operator hours. The new one is about forty characters longer and is, in practice, the entire debugging session.</p><h2 id="afterwards">Afterwards</h2><p>Three observations remain with me, not all flattering to myself.</p><p>The first concerns the unfortunate pedagogy of demo fixtures. Every object I had constructed by hand produced exactly the sections I believed a linker ought to consume, because I was the person deciding what sections to emit. The compiler, given the same source program, produces a superset: everything it is in the habit of producing, regardless of whether the author has asked for it. A linker that works on its author&rsquo;s fixtures and fails on real compiler output is, in the end, a demonstration of what a linker is not quite yet.</p><p>The second is that the work of a static linker is, by line count and by temperament, more than half refusal. The mental image I had brought to the project was of a machine that combined object files — that picked up bytes, placed them, patched them, and emitted them. What a linker actually does, in the case of debug sections and notes and comment strings and compiler-provenance records and half a dozen kinds of metadata one rarely thinks about, is decide not to do anything. It refuses to lay them out. It refuses to honour the relocations written against them. It lets them drop quietly out of the story. The allocation chapter is the tutorial one in any book on linkers; the refusal chapter is what separates a linker that works from a linker that only works on its own input.</p><p>The third, and the one I should like to press hardest, concerns diagnostics.<code>BadTargetSection</code>, without the name of the offending section, was not a diagnostic but a riddle. The operator — in this case myself — was obliged to install a foreign toolchain, read a twenty-line section table, cross-reference it with a handful of relocation entries, and derive by elimination the fact that sections like<code>.debug_info</code> were the subject of the complaint. Adding the section name to the error would have turned ten minutes of spelunking into a single line of output. Diagnostic plumbing, as a discipline, is almost always undersold. A tool with worse diagnostics is not a smaller or a simpler tool. It is a tool whose operator has been sent to do part of the tool&rsquo;s work.</p><p><code>zelf</code> is not a replacement for anything, and was not written in the hope of becoming one. It is, perhaps, an instrument for understanding — and the chief thing it has taught me is that a great deal of what the compiler emits is, from the linker&rsquo;s point of view, something to be politely set aside.</p>
]]></content:encoded></item><item><title>The Map That Came True</title><link>https://mtclinton.com/posts/the-map-that-came-true/</link><pubDate>Sun, 19 Apr 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-map-that-came-true/</guid><category>writing</category><description>A surveyor charts a half-known district, and returns a year later to find the land has quietly agreed with him.</description><content:encoded>&lt;![CDATA[<p>I have set down what follows exactly as Mr. Aldous Renn told it to me, on three evenings in the autumn of his retirement, in the small house he kept above the harbour at Penllech. He was by then an old man, careful and unexcitable, with the dry, exact manner that the long practice of his profession leaves upon those who have given their lives to it; and he told the thing without ornament, as a man states a fact he has examined from every side and cannot make to come out otherwise. I record it because I have not been able, in the years since, to make it come out otherwise either; and because Renn asked me, with a particular and quiet insistence, to write it down only after he was gone. He has been gone now some while. What I owe him is accuracy, and I have tried to give him that.</p><p>Renn was a surveyor — a good one, by the testimony of every man I have spoken to who knew his work. He had been trained in the old discipline of the chain and the theodolite, in the days before the aeroplane and the photographic plate took so much of the labour and so much of the judgement out of the business; and he held, all his life, that a map made by a man who had walked the ground was a different kind of object from a map made by a man who had not. The distinction mattered to him. He returned to it more than once in the telling, as though it were the hinge of everything else.</p><p>In the spring of his thirty-fourth year he was commissioned to survey a district in the west that had never been properly charted. I shall not name it precisely; Renn did not, and I think his reticence was deliberate, and I have come to share it. It was a stretch of perhaps forty square miles — moor and rough upland to the north and east, a broken and difficult coast to the west, and between them a country of small valleys, peat, standing water, and a few scattered farms whose people kept to themselves and had kept to themselves, by every sign, for a very long time. It had been mapped before, after a fashion. There existed an estate plan of part of it, and a coastal chart that concerned itself only with what a vessel must avoid, and a county map on which the whole district was rendered with the frank and cheerful vagueness of a thing copied from another thing that had itself been guessed. Renn&rsquo;s commission was to replace all of this with a single accurate survey, at a scale of six inches to the mile, fit to be engraved.</p><p>He took two seasons over it, and a chainman and a boy, and he did the work, as he insisted to me, honestly. I want to be exact about his meaning here, because the whole of the rest depends upon it. He did not mean that he had measured every yard of forty square miles, for no surveyor does that or could. He meant that wherever the ground would yield to measurement he had measured it, and wherever it would not he had done what every competent surveyor does, which is to<em>infer</em> — to carry the line across the doubtful place by reason and by eye, and to set it down with the same firm stroke as the part that was certain, because a map may not stammer. A map that confessed every uncertainty would be unreadable, and useless, and no map at all.</p><p>So there were, in Renn&rsquo;s finished survey, a number of strokes that were inference and not measurement, and he knew precisely which they were, and he named them over to me one by one, that first evening, the way a man tells over a debt.</p><p>There was the coastline below the northern headland, where the cliffs fell sheer into broken water and no man could stand to take a reading; he had drawn that coast from a boat, in a swell, at two hundred yards, and he had smoothed it — had given it a clean, plausible, gently curving line where the truth was very likely a thing more jagged and more ugly than any instrument of his could have caught.</p><p>There was the river. It ran down off the moor and went, for the better part of a mile, into a gorge so deep and so overgrown that he could not follow it and could not see into it; he had stood at the place where it entered and the place where it came out, and between those two certainties he had drawn the course he judged most probable — a single confident curve through country he had never set eyes on.</p><p>There was a hill in the southeast quarter. He had never climbed it and never properly seen it; but the light, on two separate evenings, had fallen across that quarter in a way that declared high ground, and the streams ran from it as streams run from a summit, and so he had placed a hill there, of a height he inferred, and drawn the contour rings about it with a steady hand.</p><p>There was a boundary, an old parish line, that the documents disputed and the local people remembered three different ways; and a boundary a map cannot leave ambiguous, so he had chosen, and drawn it, and made it certain by drawing it.</p><p>And there was — this he told me last, and more slowly — a valley in the empty west of the sheet, a small green valley running down toward the sea, that had no name. He had asked, and no one had a name for it; it was simply<em>the valley</em>, or<em>down there</em>, or it was nothing at all. A surveyor dislikes a blank where a name should be; it makes the sheet look unfinished, and it troubles the eye. And so, idly, at his table one evening with the lamp drawn close, to fill that empty quarter and for no better reason than that the sheet asked for it, he had written across the little valley a name of his own invention. He told me the name. I will not give it here. It was a soft name, plausible, of the kind the country itself might have produced; he had built it, he said, out of two ordinary words of the old local speech, fitted together the way such names are fitted, so that it would not look false beside the true ones. And then he had inked it in, in the proper lettering, and thought no more about it, and delivered the map.</p><p>That was the whole of it. There is nothing in any of that which a hundred honest surveyors have not done a hundred times. Renn was at pains that I should understand this. He had done nothing that the profession does not silently sanction; he had done only what the work itself requires; and if there is a horror in this account — and I believe there is — it begins precisely there, in the fact that he had done nothing wrong at all.</p><hr><p>He returned to the district fourteen months later.</p><p>There was an ordinary reason for it. A question had been raised about one of the engraved sheets — some small discrepancy of levels, the sort of thing that is settled in a morning — and Renn, being the man who had done the original work, was the natural man to send. He thought nothing of the journey. He went down in the early autumn, alone this time, with a single copy of his own published map folded in his coat, and he meant to be home within the week.</p><p>He was not home within the week.</p><p>He came up onto the moor by the eastern road, the way he had first come into the district two years before, and the first thing — he was insistent that it was the very first thing, before he had any thought in his head of anything being wrong — the first thing he noticed was the hill.</p><p>It stood in the southeast quarter. It stood exactly where he had placed it. He had placed it, you will remember, by inference, from the fall of the light and the running of the streams, having never seen it; and now he saw it, and it was the hill he had drawn. He stood in the road a long time looking at it. A man may, of course, infer a hill correctly; that is what the skill is for; and Renn told me that for perhaps a quarter of an hour he stood there assuring himself, quite reasonably, that he had simply done his work well, and that the unease he felt was the foolish unease of a man meeting, in the flesh, a thing he had previously known only as a line. He walked on. But he had taken the map out of his coat, and he did not put it back.</p><p>He went down to the coast next, because the coast was on his way, and because — though he did not say so to himself in those words — he wished to be reassured by the coast. He was not reassured by the coast.</p><p>The cliffs below the northern headland, which he had drawn smooth from a boat at two hundred yards in a swell, knowing as he drew them that the truth was certainly rougher and uglier than his line — those cliffs now ran smooth. They ran in a clean and gentle and plausible curve. They ran, foot for foot and bay for bay, as he had drawn them. He stood above them for a long while, Renn said, and he was a careful man and not a fanciful one, and he searched that coast for the jaggedness he knew ought to be there, the jaggedness that any true coast has; and the coast declined to be jagged. It had the smoothness of a drawn thing. It had been, he said — and here he stopped, the first evening, and was silent for a little — it had been<em>generalised</em>. That was the surveyor&rsquo;s word he reached for, and could not better. The coast had been generalised, in the way a draughtsman generalises a coast he cannot see in full; and the generalisation was his.</p><p>I will not give every test in the order he gave it to me, for he gave it to me very slowly, and circled back, and the three evenings ran together. But the substance of the next days, as he reconstructed them for me, was this.</p><p>He went up the river, and the river had moved. Where it came out of the gorge — that mile of gorge he had never been able to enter or see into — it came out now along the course he had guessed for it. He knew it had moved, because he had stood at that lower mouth two years before and watched the water come out, and it had come out then bearing to the left of a particular split rock, and now it came out bearing to the right of that rock, which was the side his drawn line required; and the old channel, the true channel, was a dry and grassy scar that the eye could still follow if the eye knew to look. The river had been corrected. It had been brought into agreement with the map.</p><p>He went, last, to the valley.</p><p>He went to it, he admitted to me, with dread, and he went to it knowing already, I think, what he would find, because by then the pattern of the thing had laid itself out before him with the cold and orderly logic of a proof. There was a valley in the empty west of the sheet. It ran down toward the sea, small and green, as he had drawn it. He came over the shoulder of the land above it in the late afternoon and stood looking down, and there was a farm in the valley, and a man mending a wall, and Renn went down to him and gave him good evening and asked him, as a traveller asks, the name of the place.</p><p>The man told him the name.</p><p>It was the name Renn had invented at his table by lamplight, out of two old words, to fill an empty quarter of a sheet of paper. The man gave it readily, with the small flat certainty of a thing entirely beyond question; and when Renn — keeping his voice, he said, very level — asked how long the valley had been called by that name, the man looked at him without comprehension and said that it had always been called that. That his father had called it that. That it was the name of the place. There was no other name, had never been any other name, and the question itself was a foolishness, the sort of question a stranger asks.</p><p>Renn thanked him and went back up onto the high ground in the last of the light and sat down, because his legs, he told me without any embarrassment at all, would not at that moment carry him further.</p><hr><p>I have wondered since how a man of Renn&rsquo;s particular temper met a thing like that, and the answer he gave me — the answer his whole conduct over the following days was — is the part of the story I find I most want to set down faithfully, because it is the part most unlike what a man imagines of himself.</p><p>He did not flee, and he did not pray, and he did not persuade himself he was ill. He was a surveyor. He had spent his life establishing the truth of doubtful ground by subjecting it to test, and so, sitting on the hill in the dark, he resolved quite steadily that he would subject<em>this</em> to test; that he would treat the appalling proposition before him exactly as he would treat any other hypothesis about the country — that is, he would put a mark on the map where the ground did not yet warrant it, and then he would go and see.</p><p>He chose something small. He told me he chose it small on purpose, partly from a scientist&rsquo;s instinct for the modest experiment and partly — he was honest about this — from fear; he did not want to author anything large. There was a particular field he knew, a high bare field on the moor&rsquo;s edge with nothing in it, and he took his pen that night at the inn and he drew, in the corner of that field nearest the road, the small circular symbol that the survey used for a single standing stone. There was no standing stone in that field. He had walked the field himself two years before; he had walked every yard of it; it was empty. He inked the symbol in and let it dry and folded the map and, he said, did not sleep.</p><p>In the morning he walked out to the field. The walk was four miles. He has described that walk to me and I will not attempt to improve on the plainness of his description: he said it was the longest distance he ever covered, and that he did it without once raising his eyes from the road immediately before his feet, because he found he could not bear to look up and see the field while there was still any distance left in which the field might be empty.</p><p>The stone was there.</p><p>It stood in the corner nearest the road, where his pen had put it — a single rough pillar of the grey country rock, lichened, bedded deep, leaning a little with the unmistakable look of having leaned so for a thousand years. The grass grew up against its base undisturbed. There was no rawness anywhere about it, no mark of the ground having been opened. It had the complete and seamless pastness of a thing that has always been there; and Renn stood with his hand flat against it — he wanted, he said, the fact of it against his palm — and understood that the map was no longer a description of that country.</p><p>The map was the authority. The country was the copy. Where the two differed the country would, quietly and without haste and without any witness to the moment of change, give way and become what the map already said. He had spent his career, and his whole faith, on the principle that the map must answer to the ground. He stood in the field and understood that for this district, and perhaps — the thought came to him there and he did not afterward find any way to refuse it — for every district, the ground answered to the map.</p><hr><p>A man might have stopped there. Renn did not stop there, and I have come to believe that the reason he did not stop is the reason the story is worth the telling, and worth the long care he took that it should reach me whole.</p><p>He did not stop, because a question had opened under the first horror, and it was a question only a mapmaker would think to ask, and once asked it could not be put down. The question was this. If the ground of that district had been made to agree with<em>his</em> map — if his survey of two seasons had become the true thing and the country the obedient copy — then his survey was not a description. It was an instrument. It had<em>made</em>. And a thing with that power was either the first such thing that had ever existed, which Renn, sitting in the field, found he did not for a moment believe; or else it was not the first, and his map stood in a line.</p><p>He wanted, therefore, an older map. He wanted to know what had charted that country before he came to it.</p><p>He spent, he told me, the better part of three weeks at it, and he was a methodical man and knew where such things are kept — the muniment rooms of the old houses, the county archive, the chests in the vestries of remote churches where the parish records lie under dust and damp. He found the estate plan he already knew of, and the coastal chart, and two or three others, none older than a hundred and fifty years and none of them anything but ordinary. And then, in the last place he looked — it was the strong-room of a private library, the collection of a family long settled in that country, and he had got himself admitted to it by a chain of small civilities I need not detail — in the last place he looked, folded in a parchment cover and catalogued under no useful heading, he found the old map.</p><p>He knew it was old before he could have said how he knew. It was drawn on skin, and the skin was very dark, and the hand that had drawn it was not any draughtsman&rsquo;s hand he had been trained to recognise; but it was, unmistakably and beyond any possibility of his mistaking it, a map of his district. There were the forty square miles. There was the moor, and the broken coast, and the small valleys between. And it was drawn — Renn made me sit with this, the third evening, for a long time before he would go on — it was drawn with features upon it that he believed he had invented.</p><p>The coast ran smooth, in his curve. The river ran in his guessed channel. The hill stood in the southeast quarter. The valley in the western quarter bore a name, lettered small in the old brown ink, and though the characters were strange to him he had spent his life reading the lettering of maps and he worked it out, and it was his name — the soft name he had built one evening out of two old words to fill an empty space. It was on the old map. It had been on the old map, by every evidence of the skin and the ink, for longer than his country had kept records at all.</p><p>He stood in the strong-room, he said, and he was past horror now and into something colder and more level, a kind of attention; and being a surveyor, being to the last a man who reads a sheet methodically and to its edges and does not stop at the part that interests him, he read the rest of the old map. He read it across, and down, and into its corners.</p><p>And in the eastern quarter, on the moor&rsquo;s edge, above the line of an old road, he found a small mark.</p><p>It was not a symbol of the survey he knew. It was a little figure, drawn fine, of a kind he could not name; and beside it, lettered very small in the old brown hand, was a word. The word was a name. He read it. He stood, he told me — and this was the last thing he told me, on the last of the three evenings, and he told it quite quietly, with his hands still on the arms of his chair — he stood and read, set down on that map centuries before his birth, in a country he had believed himself the first man ever truly to chart, the name of the house in which he had been born, and beside it, in the same small ancient certain hand, his own.</p><p>He understood then, he said, what he was. He had gone into that district as the man who held the pen. He came out of the strong-room knowing that he had never held it; that he, and his two careful seasons, and his six inches to the mile, and his whole exact and honest life, were a line on someone&rsquo;s earlier sheet — drawn, inferred perhaps across some doubtful place, named to fill a space — and that he had been walking, all the while he believed himself the author, the obedient and finished country of an older map.</p><p>He did not tell me, and I did not ask, whether he ever went back to the strong-room to look at the old map again. I think he did not. There would have been no use in it. A man cannot revise the sheet he is drawn upon; he can only, at the last, and carefully, and to one other person, set down what he has read there — and hope that the setting-down is itself not already inked, small and certain, in some hand he will never see.</p>
]]></content:encoded></item><item><title>A Tour of the gVisor Front</title><link>https://mtclinton.com/posts/a-tour-of-the-gvisor-front/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/a-tour-of-the-gvisor-front/</guid><category>code</category><description>1
One of the minor peculiarities of writing about systems software in the present era is the Tour of the Sandbox. One reads a paper, reads some source, builds a small toy of one&rsquo;s own, runs a few benchmarks — and then, improbably, writes down one&rsquo;s impressions as if one had in fact been somewhere. I mention this at the outset because the reader deserves fair warning. What follows is a dispatch from such a tour, conducted over the past few weeks in and around gVisor, the userspace kernel Google has deployed to make the running of untrusted code a less dangerous proposition than it had been. I have not been to Mountain View, and nobody in particular invited me. The only credential I possess is that I have, in an earlier post or two, built a small and imperfect mini-sentry of my own, which is to gVisor approximately what a scale model of a Dreadnought is to a Dreadnought. My tour was conducted with a notebook, a Docker daemon, a bench harness of my own devising, and the disposition of a man who hopes to be useful to whoever comes up the road behind him.</description><content:encoded>&lt;![CDATA[<p>1</p><p>One of the minor peculiarities of writing about systems software in the present era is the Tour of the Sandbox. One reads a paper, reads some source, builds a small toy of one&rsquo;s own, runs a few benchmarks — and then, improbably, writes down one&rsquo;s impressions as if one had in fact been<em>somewhere.</em> I mention this at the outset because the reader deserves fair warning. What follows is a dispatch from such a tour, conducted over the past few weeks in and around gVisor, the userspace kernel Google has deployed to make the running of untrusted code a less dangerous proposition than it had been. I have not been to Mountain View, and nobody in particular invited me. The only credential I possess is that I have, in an earlier post or two, built a small and imperfect<a href="/posts/mini-sentry/">mini-sentry</a> of my own, which is to gVisor approximately what a scale model of a Dreadnought is to a Dreadnought. My tour was conducted with a notebook, a Docker daemon, a bench harness of my own devising, and the disposition of a man who hopes to be useful to whoever comes up the road behind him.</p><p>What I bring back is, first, a collection of specimens — numbers, mostly — and, second, a set of impressions that the numbers by themselves do not entirely explain. I am going to attempt both, and I am going to try hard not to let the second tyrannize the first.</p><p>2</p><p>It is difficult, after a few weeks, to remember that when I first set out to understand gVisor I believed it was another container runtime. It is not. A container runtime, in the ordinary sense, is a tool for using the Linux kernel&rsquo;s isolation primitives — namespaces, cgroups, seccomp — to persuade several processes to ignore each other&rsquo;s existence. gVisor does something altogether different, and more audacious. gVisor<em>pretends to be Linux.</em> It sits in userspace, as a binary written in Go, and when a sandboxed process calls<code>read</code> or<code>openat</code> or<code>socket</code>, gVisor catches the call before the real kernel learns of it, does whatever the call is supposed to do from within its own quiet reimplementation of the relevant subsystem, and hands the result back. The sandboxed process lives out its whole life in the earnest belief that it is in conversation with Linux. It is, in fact, in conversation with something on the order of two hundred thousand lines of Go.</p><p>That is, one is obliged to admit, a different<em>kind</em> of system software. Namespaces and seccomp, however cleverly composed, in the end all let the guest&rsquo;s syscalls land on the host kernel, and rely on the kernel to be both correct and trustworthy. gVisor declines to take that bet. The host kernel, in gVisor&rsquo;s conception of things, is precisely the piece whose correctness one does not wish to have to depend upon. The insolence of the idea grows on one the longer one thinks about it.</p><p>3</p><p>A rough accounting may be helpful. Linux exposes something on the order of four hundred system calls — the exact figure depends upon how one counts the many subcalls of<code>ioctl</code>,<code>prctl</code>,<code>fcntl</code>, and their relations — but four hundred is a fair round figure. Each of these is, from the point of view of a guest process that wishes the host ill, a potential avenue into the most privileged region of the machine. A kernel bug lodged anywhere along that frontier, if reachable from the guest, is a way out.</p><p>The Sentry — which is the piece of gVisor that does the pretending-to-be-Linux — answers almost every one of those calls itself, in Go, without troubling the host kernel at all. The Sentry&rsquo;s own interaction with the host, that is to say, what it itself needs in order to do its job, has been pared down with visible deliberation to about sixty-eight distinct syscalls; a seccomp filter nails it to precisely that set. The arithmetic is nearly the whole pitch: four hundred down to sixty-eight, a sixfold contraction of the frontier. It is the single compact argument that justifies the existence of the thing. What that contraction<em>costs,</em> in the running of a program, is the subject of the rest of this dispatch.</p><p>4</p><p>There are, or have been, three platforms in gVisor — three mechanisms by which the Sentry catches the guest&rsquo;s syscalls — and one must visit all three, however briefly, to have any real picture of the landscape.</p><p>The first is ptrace, which uses the same mechanism a debugger does. The parent process stops the child at every syscall, inspects the registers, and either emulates the call or lets it pass to the host. It is the most honest of the three implementations in that it hides nothing; it is also ruinously slow, because every single syscall costs a context switch to the tracer and a context switch back, whether or not the Sentry has anything to do with it. Tight syscall benchmarks report a tax on the order of forty-to-one over native. This is the platform gVisor shipped with; it has since been, effectively, retired.</p><p>The second, and current default, is systrap. Systrap uses a seccomp filter that returns<code>SECCOMP_RET_TRAP</code> — a signal the Sentry handles<em>in-process,</em> with no tracer involvement — paired with a shared-memory region for argument passing. The whole business becomes less a stop-the-world interrupt and more a function call. The tax falls from ruinous to acceptable, and one can run gVisor in production on systrap without feeling foolish, which is not a trivial thing.</p><p>The third is KVM, which runs the Sentry inside a small hardware virtualization container and turns the guest&rsquo;s syscalls into vmexits rather than signals. It has the best raw performance on many workloads and the most restrictive deployment prerequisites. Most of what one reads about gVisor in the wild is about systrap, for the very good reason that systrap is what ordinary installations default to. My bench harness was systrap throughout.</p><p>5</p><p>So I built a bench harness. The harness is small — five workloads, each chosen to exercise a different part of the stack — and I ran each one first under plain<code>runc</code>, the unremarkable OCI runtime, and then under<code>runsc</code>, which is gVisor&rsquo;s. The ratio between the two is the specimen I came back with.</p><p>The first workload is coldstart: the time it takes a container to come up and print a message. The second is<code>sha256sum</code> of a 256-megabyte blob, which is almost entirely CPU with a<code>read</code> call every thirty-two kilobytes — a compute-bound workload with, as it were, a modest syscall habit. The third is a pipelined Redis PING loop run over TCP with gVisor configured to use the host&rsquo;s real network stack; the socket syscalls are dispatched by the Sentry but serviced, ultimately, by the host kernel&rsquo;s TCP implementation. The fourth is the same loop, but in gVisor&rsquo;s default network mode, in which TCP rides through Netstack — a full TCP/IP stack written in Go and carried about by the Sentry wherever it goes. The fifth is<code>wrk</code> driving ten seconds of HTTP against nginx.</p><p>The ratios were these. Coldstart, 4.07x: runsc containers take about four times as long to boot as runc containers, which, in absolute terms, is about five hundred milliseconds against a hundred and twenty. SHA-256, 1.41x: the sentry-dispatch tax on roughly eight thousand<code>read</code> calls, amortized over the hashing work, is modest but visible. Redis-ping on host-network, 10.61x: a pipelined PING is the syscall-dense extreme — two<code>sendto</code>/<code>recvfrom</code> pairs per round trip, with almost nothing happening in between — and this ratio pins the upper bound of what sentry dispatch, alone, can cost. Redis-ping through Netstack, 12.40x: the same workload, but with the userspace TCP/IP stack on the path; the seventeen per cent delta from the previous figure is Netstack&rsquo;s own share, and one remarks that it is smaller than one might have guessed. Nginx under<code>wrk</code>, 5.79x: this is, I suspect, about the shape of a typical HTTP microservice running under gVisor, and it is the number I would quote to anybody who wanted one round figure.</p><p>Reading down the ratios in the order given, one watches the tax<em>rise</em> as the workload becomes more syscall-dense. Hashing is mostly computation and pays little. Bouncing small requests through a socket is almost all syscalls and pays nearly an order of magnitude. nginx sits between them, because nginx does a great deal of socket work but it also does parsing, response assembly, routing, and logging, some of which is comparatively cheap under gVisor. The per-syscall tax is diluted by whatever computation happens between the syscalls. This is not a surprising pattern, but there is a useful clarity in having seen it confirmed in particular numbers.</p><p>6</p><p>If the performance picture is workload-shaped, the compatibility picture is less reassuring still. A userspace kernel that reimplements Linux reimplements a great deal of it — the Sentry&rsquo;s syscall table runs to several hundred entries, and the coverage of ordinary-server syscalls is very good indeed — but it does not, and in some cases cannot, reimplement all of it.<code>perf_event_open</code> returns<code>ENODEV</code>; Linux&rsquo;s hardware-performance-counter infrastructure is, inside a gVisor container, simply not present.<code>io_uring</code>, the newer asynchronous I/O mechanism, is partially supported and, depending on version and policy, usually turned off.<code>bpf</code>, including the extended BPF system calls that have become the ordinary way of writing Linux tracing and networking extensions, is unsupported. Most of the tools one reaches for when chasing a production problem in depth —<code>perf record</code>, the<code>bcc</code> suite,<code>bpftrace</code> — simply fail to run inside a gVisor container.</p><p>This is not, I think, a defect so much as a<em>shape.</em> A userspace reimplementation of a kernel can reimplement the parts that are mostly state machines — virtual file systems, sockets, pipes — but cannot really reimplement the parts that are hardware interfaces (perf counters, hardware breakpoints) or host-global facilities (BPF program attachment, cgroup BPF). What one gets, in exchange for the sixfold attack-surface contraction, is a container that politely refuses to answer some of the most powerful questions one might want to ask of it. Whether the bargain is a good one depends entirely on whether the workload inside had ever cared about those questions. For most Web services, it did not. For a data-plane workload of any ambition, it very much did.</p><p>It is worth pausing over the picture one is usually shown of gVisor, which is the version that gets repeated on conference slide-decks and vendor blogs. In that version, gVisor is a secure-by-default default, substitutable wherever one runs containers, and the tax is described in an averaged ratio — &ldquo;about 5x&rdquo; — that concedes nothing about where the tax actually falls. The real version is less tidy. gVisor is not a drop-in. gVisor is a<em>fit</em> — suitable for workloads of a particular shape, unsuitable for workloads of other shapes, and the shape at issue is not a matter of opinion but of which syscalls the workload happens to depend upon. The averaged ratio is an effigy of the truth, not the truth itself.</p><p>7</p><p>I come back from the tour with less a conclusion than a set of impressions that do not obviously cohere, and I am going to offer them rather than pretend they do.</p><p>The first impression is that the attack-surface arithmetic is the<em>real</em> argument, and that the whole edifice of benchmarks and compatibility tables exists to let one determine whether one can afford to accept the argument for any particular workload. Four hundred host syscalls down to sixty-eight is not a marketing figure but a structural one, and it is what makes the project interesting even when the benchmarks are unflattering. One can always write faster code; one cannot so easily rewrite a threat model.</p><p>The second is that the performance tax is not uniform and that treating it as uniform produces bad decisions. A 1.4x penalty on hashing is, in any practical sense, nothing. A 12x penalty on localhost TCP is disqualifying for some workloads and irrelevant for others. The useful question is never<em>how fast is gVisor;</em> it is<em>how syscall-dense is this particular workload, and how much of that density is socket work.</em></p><p>The third is that the compatibility holes are the quiet determiner. The workloads that fail under gVisor fail most often not because the tax is too high but because something they need —<code>perf</code>,<code>bpf</code>,<code>io_uring</code> — is simply not there. The benchmark harness was useful; the compatibility harness — a workload actually launched under<code>runsc</code> and watched carefully, to see whether it did or did not do what it had been meant to do — was more useful still.</p><p>And there is, finally, a fourth impression, which I offer less confidently but will nevertheless record. Having built the small and dreadful toy version first — the one described in my earlier posts — and only afterwards gone to meet the large and serious version on its own ground, one comes back from the trip with a kind of respect for gVisor that no amount of reading the source could have produced. The ratios are legible because one has, in however reduced a form, written the code that produces them. The Tour, as it turned out, was worth the going.</p>
]]></content:encoded></item><item><title>Hijacking Signals in Go - Notes from a Tiny gVisor</title><link>https://mtclinton.com/posts/hijacking-signals-in-go/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/hijacking-signals-in-go/</guid><category>code</category><description>A few days ago I began writing a toy version of gVisor — Google&rsquo;s userspace kernel — as a way of discovering, in the only way one truly discovers such things, how it actually intercepts a syscall. The project lives at github.com/mtclinton/mini-sentry, and its pitch, shorn of ornament, is this: if a sandboxed Linux program calls write(), the kernel is not to handle it. My Go code is to handle it. That is the shape of gVisor&rsquo;s security story, and it is a shape worth taking seriously — a kernel exploit sitting inside write() is of no consequence whatever if the kernel never runs write() to begin with.</description><content:encoded>&lt;![CDATA[<p>A few days ago I began writing a toy version of gVisor — Google&rsquo;s userspace kernel — as a way of discovering, in the only way one truly discovers such things, how it actually intercepts a syscall. The project lives at<a href="https://github.com/mtclinton/mini-sentry">github.com/mtclinton/mini-sentry</a>, and its pitch, shorn of ornament, is this: if a sandboxed Linux program calls<code>write()</code>, the kernel is not to handle it. My Go code is to handle it. That is the shape of gVisor&rsquo;s security story, and it is a shape worth taking seriously — a kernel exploit sitting inside<code>write()</code> is of no consequence whatever if the kernel never runs<code>write()</code> to begin with.</p><p>Most of the project was kinder to me than I had expected.<code>PTRACE_SYSEMU</code> catches every syscall before the kernel touches it, my Go handlers fill in a return value, and I resume the guest. A few hundred lines of this and I had a sandbox capable of running static Linux binaries against a fabricated filesystem. I was, for a pleasant interval, under the impression that I was most of the way done.</p><p>Then I tried to make signals work, and the next three phases of the project disappeared into them. What follows is an account of what I encountered there.</p><h2 id="the-setup-syscall-interception-in-one-page">The Setup: Syscall Interception in One Page</h2><p>Before signals intrude, the architecture has the clean lines of something that can be drawn without apology.<code>PTRACE_SYSEMU</code> is a ptrace operation that stops the tracee every time it is about to make a syscall,<em>skips</em> the real call, and permits the tracer to write a return value directly into<code>RAX</code>:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// simplified loop</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceSyscall</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">)</span><span class="w"/><span class="c1">// SYSEMU under the hood</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">wait4</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">ws</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">regs</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nf">readRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">ret</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nx">sentry</span><span class="p">.</span><span class="nf">HandleSyscall</span><span class="p">(</span><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">regs</span><span class="p">.</span><span class="nx">Rax</span><span class="w"/><span class="p">=</span><span class="w"/><span class="nb">uint64</span><span class="p">(</span><span class="nx">ret</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">writeRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>If I want the kernel to handle something — say<code>mmap</code>, which touches page tables that cannot be forged from userspace — I rewind<code>RIP</code> by two bytes (the width of the<code>syscall</code> instruction) and step with<code>PTRACE_SYSCALL</code> instead. The kernel runs it; I read the result.</p><p>That is enough to emulate<code>read</code>,<code>write</code>,<code>openat</code>,<code>getdents64</code>,<code>getpid</code>,<code>getuid</code>, and a dozen of their relations. My sandbox could print &ldquo;hello&rdquo; and read fabricated files out of an in-memory VFS. This is the point at which, if the project were a novel, the protagonist would go for a walk and fail to notice the weather.</p><h2 id="phase-3a-a-mirror-without-effect">Phase 3a: A Mirror Without Effect</h2><p>The first thing one learns about signals is that<code>rt_sigaction(2)</code> appears, on the surface, to be nothing more than a table assignment. The kernel keeps an array of<code>sigaction</code> structs, one per signal, and<code>rt_sigaction(SIGUSR1, &amp;act, NULL)</code> writes into slot 10. Emulating this sounds, for a moment, as though it will not detain us long:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"/><span class="p">(</span><span class="nx">s</span><span class="w"/><span class="o">*</span><span class="nx">Sentry</span><span class="p">)</span><span class="w"/><span class="nf">sysRtSigaction</span><span class="p">(</span><span class="nx">pid</span><span class="w"/><span class="kt">int</span><span class="p">,</span><span class="w"/><span class="nx">sc</span><span class="w"/><span class="nx">SyscallArgs</span><span class="p">)</span><span class="w"/><span class="kt">uint64</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">signum</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nb">int</span><span class="p">(</span><span class="nx">sc</span><span class="p">.</span><span class="nx">Args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">buf</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nf">readFromChild</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="nx">sc</span><span class="p">.</span><span class="nx">Args</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span><span class="w"/><span class="nx">sigactionSize</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">s</span><span class="p">.</span><span class="nx">signals</span><span class="p">.</span><span class="nf">SetAction</span><span class="p">(</span><span class="nx">signum</span><span class="p">,</span><span class="w"/><span class="nf">decodeAction</span><span class="p">(</span><span class="nx">buf</span><span class="p">))</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">return</span><span class="w"/><span class="mi">0</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>The trouble is that this tracks state and does nothing else. The kernel still owns<em>delivery</em>. When something sends SIGUSR1, the kernel consults its own sigaction table — not mine — and runs whatever was there before I had begun to intercept anything at all. My mirror, for all its diligent bookkeeping, is a read model with no bearing on behaviour.</p><p>It was here, too, that I had to understand gVisor&rsquo;s Task and ThreadGroup split, because I was going to have to reproduce it. Signal masks and pending queues are per-thread; the sigaction table is per-thread-group. gVisor expresses this with a<code>Task</code> struct for the per-thread half and a<code>ThreadGroup</code> for the shared one. I ended up with<code>ThreadState</code> and<code>ThreadGroup</code> doing the same offices. If one has ever wondered why<code>kill(pid, sig)</code> may pick any thread in the group while<code>tkill</code> targets precisely one, this is the reason: the routing predicate consults every per-thread mask in the group.</p><p>Phase 3a produced a mirror. It did not yet own a single delivery.</p><h2 id="phase-3b-becoming-the-kernels-signal-path">Phase 3b: Becoming the Kernel&rsquo;s Signal Path</h2><p>To own delivery, the Sentry must construct the signal frame itself. On x86_64 the frame is a particular data structure —<code>struct rt_sigframe</code>, some 1032 bytes in all — and it must be matched to the byte:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">+0x000 ucontext { flags, link, stack, mcontext (RAX..RIP..), sigmask }</span></span><span class="line"><span class="cl">+0x1A8 fpstate { 512-byte FXSAVE area }</span></span><span class="line"><span class="cl">+0x3A8 siginfo { si_signo, si_code, si_pid, si_uid, ... }</span></span><span class="line"><span class="cl">+0x408 pretcode pointer to rt_sigreturn trampoline</span></span></code></pre></div></div></figure><p>The contract is as follows. One writes this structure onto the guest&rsquo;s stack, sets<code>RSP</code> to point at it, sets<code>RIP</code> to the handler, and resumes the guest. The handler executes and returns with<code>ret</code>, which pops<code>pretcode</code> and lands in a small trampoline that issues<code>rt_sigreturn</code>. That syscall is the exact inverse of frame construction — it reads the frame back, restores the pre-handler register state, and returns the interrupted code to what it had been doing.</p><p>In mini-sentry,<code>BuildRtSigframe</code> writes the frame via<code>process_vm_writev</code> and<code>sysRtSigreturn</code> reads it back via<code>process_vm_readv</code>. The round-trip is perhaps 600 lines distributed across<code>frame_amd64.go</code>,<code>deliver_amd64.go</code>, and<code>handlers_signals_amd64.go</code>, and the greater part of it is byte-layout bookkeeping. One decides to own delivery; one signs, in the same motion, for matching the kernel&rsquo;s struct offsets to the byte.</p><p>I got both halves of this written, wired up a guest test that did<code>kill(getpid(), SIGUSR1)</code> against a handler that atomically incremented a counter, ran it, and was answered with:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">runtime: newstack sp=0xc00000dbf8 stack=[0xc0000ce000, 0xc0000d6000]</span></span></code></pre></div></div></figure><p>Go&rsquo;s stack guard, which I had not thought to trouble, was informing me that the stack pointer was outside the goroutine&rsquo;s stack. This was the first of two bugs that cost me real hours, and the more instructive of the pair.</p><h2 id="the-compilers-quiet-assistance">The Compiler&rsquo;s Quiet Assistance</h2><p>The guest test installed its handler like this:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">act</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nx">sigactionKernel</span><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">Handler</span><span class="p">:</span><span class="w"/><span class="nx">reflect</span><span class="p">.</span><span class="nf">ValueOf</span><span class="p">(</span><span class="nx">sigusr1Handler</span><span class="p">).</span><span class="nf">Pointer</span><span class="p">(),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">Flags</span><span class="p">:</span><span class="w"/><span class="nx">saSigInfo</span><span class="w"/><span class="p">|</span><span class="w"/><span class="nx">saRestorer</span><span class="p">,</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">Restorer</span><span class="p">:</span><span class="w"/><span class="nx">reflect</span><span class="p">.</span><span class="nf">ValueOf</span><span class="p">(</span><span class="nx">restoreRT</span><span class="p">).</span><span class="nf">Pointer</span><span class="p">(),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p><code>sigusr1Handler</code> was a pure-assembly function — no Go frame, no stack-growth probe, merely<code>LOCK XADDL $1, sigCounter; RET</code>. I had written it in assembly precisely because signal handlers cannot touch Go&rsquo;s runtime: the kernel&rsquo;s signal-entry contract is the SysV C ABI, but Go&rsquo;s ABIInternal expects<code>R14</code> to hold the current goroutine pointer, and<code>R14</code> on signal entry is whatever the interrupted code happened to have left there. Any Go-level handler that so much as glances at a runtime primitive comes apart at once.</p><p>The trouble — and it was a trouble that hid itself well — was that<code>reflect.ValueOf(fn).Pointer()</code> did not return the address of my assembly. It returned the address of a compiler-generated<em>wrapper</em>. When a<code>.s</code> file defines<code>sigusr1Handler</code> and a<code>.go</code> file declares<code>func sigusr1Handler()</code>, the Go toolchain helpfully synthesises an ABIInternal shim:</p><figure class="code-terminal" data-lang="asm"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">asm</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-asm" data-lang="asm"><span class="line"><span class="cl"><span class="nl">sigusr1Handler:</span></span></span><span class="line"><span class="cl"><span class="nf">PUSHQ</span><span class="no">BP</span></span></span><span class="line"><span class="cl"><span class="nf">MOVQ</span><span class="no">SP</span><span class="p">,</span><span class="no">BP</span></span></span><span class="line"><span class="cl"><span class="nf">CALL</span><span class="no">sigusr1Handler.abi0</span><span class="c1">; the real asm</span></span></span><span class="line"><span class="cl"><span class="nf">POPQ</span><span class="no">BP</span></span></span><span class="line"><span class="cl"><span class="nf">RET</span></span></span></code></pre></div></div></figure><p>That<code>PUSHQ BP</code> and<code>CALL</code> shift<code>RSP</code> by sixteen bytes. For the counter-bumping handler it did not matter — the handler had no opinion on<code>RSP</code> — but the same wrapper had been installed as the<code>sa_restorer</code>. When the handler returned, it popped<code>pretcode</code> into<code>RIP</code> and landed, not in the real<code>restoreRT</code>, but in the<em>restorer&rsquo;s</em> wrapper:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">W_restore:</span></span><span class="line"><span class="cl"> PUSHQ BP ; RSP -= 8</span></span><span class="line"><span class="cl"> MOVQ SP, BP</span></span><span class="line"><span class="cl"> CALL restoreRT.abi0 ; RSP -= 8 (pushes return addr)</span></span><span class="line"><span class="cl"> ; restoreRT.abi0: MOVQ $15, AX; SYSCALL</span></span></code></pre></div></div></figure><p>By the time the<code>syscall</code> instruction inside the real<code>restoreRT</code> actually fired,<code>RSP</code> was sixteen bytes below where my<code>sysRtSigreturn</code> expected to find the frame. It read 1032 bytes of garbage, decoded a nonsensical register set, and<code>PTRACE_SETREGS</code> loaded nonsense into the tracee. The stack-guard panic was the first visible symptom of values that had been quietly corrupted three steps earlier — which is, one is obliged to concede, the most honest possible description of most systems bugs.</p><p>The fix was to refuse the wrapper altogether:</p><figure class="code-terminal" data-lang="asm"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">asm</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-asm" data-lang="asm"><span class="line"><span class="cl"><span class="nf">GLOBL</span><span class="err">·</span><span class="no">sigusr1HandlerPC</span><span class="p">(</span><span class="no">SB</span><span class="p">),</span><span class="no">RODATA</span><span class="p">,</span><span class="no">$8</span></span></span><span class="line"><span class="cl"><span class="nf">DATA</span><span class="err">·</span><span class="no">sigusr1HandlerPC</span><span class="p">(</span><span class="no">SB</span><span class="p">)</span><span class="err">/</span><span class="mi">8</span><span class="p">,</span><span class="no">$</span><span class="err">·</span><span class="no">sigusr1Handler</span><span class="p">(</span><span class="no">SB</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="nf">GLOBL</span><span class="err">·</span><span class="no">restoreRTPC</span><span class="p">(</span><span class="no">SB</span><span class="p">),</span><span class="no">RODATA</span><span class="p">,</span><span class="no">$8</span></span></span><span class="line"><span class="cl"><span class="nf">DATA</span><span class="err">·</span><span class="no">restoreRTPC</span><span class="p">(</span><span class="no">SB</span><span class="p">)</span><span class="err">/</span><span class="mi">8</span><span class="p">,</span><span class="no">$</span><span class="err">·</span><span class="no">restoreRT</span><span class="p">(</span><span class="no">SB</span><span class="p">)</span></span></span></code></pre></div></div></figure><p>A<code>GLOBL</code>/<code>DATA</code> pair in the<code>.s</code> file exposes the raw ABI0 entry point as a plain<code>uintptr</code>. On the Go side, one deletes the<code>func sigusr1Handler()</code> and<code>func restoreRT()</code> declarations so that the compiler has no occasion to produce wrappers in the first place, and installs the handler using the PC variable. The handler now runs at the address the kernel wrote into the frame,<code>RSP</code> stays exactly where<code>rt_sigreturn</code> expects to find it, and the round-trip completes.</p><p>I verified the fix with<code>go tool objdump -s sigusr1Handler ./cmd/guest/guest</code>. The wrapper entry sat a few dozen bytes above the raw handler — one with the<code>PUSHQ BP</code> /<code>CALL</code> prologue, one without.<code>reflect.ValueOf</code> had been returning a pointer, in the most technical sense; it had simply been the wrong one.</p><p>The debugging of this cost me about half a day. I do not think I have ever paid such close attention to a disassembler in my life.</p><h2 id="the-other-bug-setregs-will-not-hear-of-cs0">The Other Bug: SETREGS Will Not Hear of CS=0</h2><p>The second bug was briefer but no more obvious. After decoding the signal frame on<code>rt_sigreturn</code>, I needed to write the restored registers back to the tracee:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">var</span><span class="w"/><span class="nx">restored</span><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nx">PtraceRegs</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nf">readMContext</span><span class="p">(</span><span class="nx">frame</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">restored</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceSetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">restored</span><span class="p">)</span><span class="w"/><span class="c1">// input/output error</span></span></span></code></pre></div></div></figure><p><code>PTRACE_SETREGS</code> returned<code>EIO</code>. The frame&rsquo;s mcontext stores only general-purpose registers along with<code>RIP</code>,<code>RSP</code>, and<code>EFLAGS</code>; it does not include segment registers.<code>restored.Cs</code> was zero.</p><p>The kernel refuses<code>PTRACE_SETREGS</code> with<code>CS=0</code> on a 64-bit user task.<code>CS=0</code> is non-canonical, and the kernel treats any attempt to set it as &ldquo;someone is about to crash userspace, and that is my problem.&rdquo; The correct remedy was not to rebuild the register set but to merge the restored fields into the live one:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="nx">regs</span><span class="p">,</span><span class="w"/><span class="nx">_</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceGetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nx">regs</span><span class="p">.</span><span class="nx">Rax</span><span class="w"/><span class="p">=</span><span class="w"/><span class="nx">restored</span><span class="p">.</span><span class="nx">Rax</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nx">regs</span><span class="p">.</span><span class="nx">Rip</span><span class="w"/><span class="p">=</span><span class="w"/><span class="nx">restored</span><span class="p">.</span><span class="nx">Rip</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nx">regs</span><span class="p">.</span><span class="nx">Rsp</span><span class="w"/><span class="p">=</span><span class="w"/><span class="nx">restored</span><span class="p">.</span><span class="nx">Rsp</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// ... GPRs, RIP, RSP, EFLAGS</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// Do NOT touch Cs, Ss, Fs_base, Gs_base, Orig_rax</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceSetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">regs</span><span class="p">)</span></span></span></code></pre></div></div></figure><p>Segment registers and<code>orig_rax</code> must come from the pre-sigreturn state. The handler could not have altered them in any case — there are no segment-writing instructions on x86_64 that survive into userspace.</p><p>The educational payoff here is worth putting plainly: the mcontext is not a complete register file. It is &ldquo;the subset of user-visible state a signal handler might wish to examine or modify.&rdquo; Everything else the kernel tracks quietly and in its own keeping, and a userspace reimplementation is obliged to remember this whenever it pretends to be the kernel.</p><h2 id="phase-3c-routing-to-the-right-thread">Phase 3c: Routing to the Right Thread</h2><p>The last phase concerned itself with making all of this behave when the guest has more than one thread. The Go runtime creates OS threads by way of<code>clone(CLONE_THREAD)</code>, and by default my tracer attached only to the initial one. Every other thread then ran unsupervised, which is to say that any signal routed to those threads bypassed the Sentry altogether — the guest speaking to the kernel behind my back, as it were.</p><p>The remedy was<code>PTRACE_O_TRACECLONE</code>. This option instructs the kernel to stop the parent on every<code>clone</code> and issue a<code>PTRACE_EVENT_CLONE</code> bearing the new tid. I attach to that tid and add it to my<code>ThreadGroup</code>. Every thread in the guest is traced; every syscall lands in the Sentry.</p><p>The routing predicate thereafter mirrors gVisor&rsquo;s<code>canReceiveSignalLocked</code>. For<code>kill(tgid, sig)</code>, one walks the threads in deterministic order and selects the first whose per-thread mask does not have<code>sig</code> blocked. For<code>tkill(tid, sig)</code>, one routes to that tid directly. For self-sends —<code>kill(getpid(), sig)</code> issued from inside the guest — one resolves to the caller&rsquo;s host tid via the ptrace-event metadata.</p><p>The test that proves the whole arrangement works runs four goroutines, each locks itself to an OS thread, each does<code>tgkill(getpid(), gettid(), SIGUSR1)</code>. All four handlers fire, the counter advances from one to five, and the integration test, having been written to be unflattering, passes without complaint.</p><h2 id="the-arm64-punchline-delegation-is-also-an-architecture">The arm64 Punchline: Delegation Is Also an Architecture</h2><p>Everything above is amd64-specific. When I turned to the question of porting to arm64, I discovered that I could, quite simply, decline.</p><p>On arm64, the<code>rt_sigreturn</code> trampoline lives in the vDSO, which my Sentry does not parse. Building the frame myself would mean reimplementing a chapter of the kernel&rsquo;s signal path with no corresponding educational profit. So the arm64 path does something different:</p><ul><li>The Sentry mirrors disposition (as on amd64)<em>and</em> passes<code>rt_sigaction</code> through to the kernel.</li><li>When a signal needs to be delivered, the Sentry simply calls<code>syscall.Kill(guestPid, sig)</code>.</li><li>The kernel&rsquo;s own signal path then runs. It builds the frame, runs the handler, and the vDSO trampoline issues<code>rt_sigreturn</code>, which the kernel handles without ever troubling the Sentry.</li></ul><p>This is not a shortcut. It is a different architectural choice, and it reflects — accurately, I think — a trade-off that gVisor itself makes. The reason amd64<em>does not</em> delegate is that gVisor&rsquo;s security property depends on not delegating: if the host kernel runs the guest&rsquo;s handler logic, a kernel exploit inside that path is once again on the table. For an educational project, the calculus is altered — &ldquo;delegate and ship&rdquo; is simply a better use of one&rsquo;s evenings than &ldquo;reimplement and stall on arm64 hardware access.&rdquo;</p><p>The point I should like to leave here is that both architectures are legitimate, and that a project that does not know which one it is picking at the outset is setting itself up for a very bad month. One owns the thing or one delegates the thing. Not both. Not partially.</p><h2 id="what-i-actually-learned">What I Actually Learned</h2><p>Three things seem to me worth writing down.</p><p>The first is that signals are the place where a userspace kernel ceases to be a diagram and becomes a machine. One can fake syscalls all day by writing into<code>RAX</code>; signals demand that one match the kernel&rsquo;s contracts at the byte level — frame layouts, register conventions, vDSO trampolines. Every rough edge in the abstraction announces itself here, and loudly.</p><p>The second is that toolchains leak into the ABI, and they do so politely enough that one does not notice. The Go compiler&rsquo;s ABIInternal wrapper was invisible to me until the moment it could not have been more visible, and it had arranged to be invisible at exactly the worst level of the stack. Anywhere the host toolchain meets a low-level ABI — signal entry, syscall trampolines, FFI — one must assume the compiler is doing something helpful that one must then undo.</p><p>The third is the architectural one, and it is the most important of the three.<em>Re-implement</em> and<em>delegate</em> are the two strategies for any userspace reimplementation of a kernel contract, and the project decides which one it wants before it starts. gVisor chose re-implement because its security story requires it. I chose delegate on arm64 because my educational story required only that I understand. The choice is not a detail; it is the first decision, and everything else follows from it.</p><p>The source is at<a href="https://github.com/mtclinton/mini-sentry">github.com/mtclinton/mini-sentry</a>. The signal subsystem begins in<a href="https://github.com/mtclinton/mini-sentry/blob/main/signals.go"><code>signals.go</code></a>; the amd64-specific frame work is in<a href="https://github.com/mtclinton/mini-sentry/blob/main/frame_amd64.go"><code>frame_amd64.go</code></a> and<a href="https://github.com/mtclinton/mini-sentry/blob/main/handlers_signals_amd64.go"><code>handlers_signals_amd64.go</code></a>. ADRs 001–003 under<code>docs/adr/</code> walk through the Phase 3 design decisions in the order in which they actually happened, including the bugs — so if one is curious about the shape of the commits that produced this account, they are right there on the page.</p><p>For the architectural prelude to all of this — the ptrace loop, the seccomp platform, the Gofer — see the<a href="/posts/mini-sentry/">earlier mini-sentry post</a>. This one picks up where that one leaves the curtain.</p>
]]></content:encoded></item><item><title>mini-sentry - Building a Userspace Kernel in Go</title><link>https://mtclinton.com/posts/mini-sentry/</link><pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/mini-sentry/</guid><category>code</category><description>There is a particular kind of understanding that only comes from building a thing yourself — not reading about it, not studying the source, but sitting down with an empty file and discovering, one segfault at a time, why the original was built the way it was. I had been circling gVisor for months, admiring its architecture from a safe distance, the way one might admire a cathedral without quite grasping the engineering of the flying buttresses. And so I did what seemed like the only honest thing: I built a small one of my own.</description><content:encoded>&lt;![CDATA[<p>There is a particular kind of understanding that only comes from building a thing yourself — not reading about it, not studying the source, but sitting down with an empty file and discovering, one segfault at a time, why the original was built the way it was. I had been circling gVisor for months, admiring its architecture from a safe distance, the way one might admire a cathedral without quite grasping the engineering of the flying buttresses. And so I did what seemed like the only honest thing: I built a small one of my own.</p><p><a href="https://github.com/mtclinton/mini-sentry">mini-sentry</a> is not a container runtime. It is not a syscall filter. It is, if I may put it plainly, a userspace kernel — a program that sits between a sandboxed process and the Linux kernel, intercepts every system call, and handles them in Go. The sandboxed process believes it is speaking to Linux. It is, in fact, speaking to me.</p><h2 id="the-appeal-of-an-interposed-kernel">The Appeal of an Interposed Kernel</h2><p>gVisor is one of the more remarkable pieces of systems software in active production. Google runs it beneath GCE, Cloud Run, and Cloud Functions, where it serves as a kind of diplomatic intermediary between untrusted workloads and the host kernel. The security proposition is elegant in its simplicity: if the sandboxed process discovers a kernel exploit, it detonates harmlessly against your Go code rather than the real kernel. The blast radius collapses to something manageable.</p><p>But gVisor is also two hundred thousand lines of Go — a codebase whose architecture reveals itself reluctantly, like a landscape glimpsed through fog. I wanted to understand the core ideas without the weight of production concerns: syscall interception, userspace handling, filesystem virtualization, process isolation. The smallest version that still captured the essential shape.</p><h2 id="architecture">Architecture</h2><p>The result has the same layered structure as its larger cousin, compressed to its fundamentals:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">┌──────────────────────────────────────────┐</span></span><span class="line"><span class="cl">│ Guest Process (sandboxed) │</span></span><span class="line"><span class="cl">│ Thinks it's talking to Linux │</span></span><span class="line"><span class="cl">└─────────────────┬────────────────────────┘</span></span><span class="line"><span class="cl"> │ syscall</span></span><span class="line"><span class="cl">┌─────────────────▼────────────────────────┐</span></span><span class="line"><span class="cl">│ Platform (ptrace or seccomp) │</span></span><span class="line"><span class="cl">│ Intercepts syscalls, reads registers │</span></span><span class="line"><span class="cl">└─────────────────┬────────────────────────┘</span></span><span class="line"><span class="cl"> │ SyscallArgs</span></span><span class="line"><span class="cl">┌─────────────────▼────────────────────────┐</span></span><span class="line"><span class="cl">│ Sentry (Go handlers) │</span></span><span class="line"><span class="cl">│ The userspace kernel. Handles read, │</span></span><span class="line"><span class="cl">│ write, openat, stat, socket, etc. │</span></span><span class="line"><span class="cl">└─────────────────┬────────────────────────┘</span></span><span class="line"><span class="cl"> │ RPC</span></span><span class="line"><span class="cl">┌─────────────────▼────────────────────────┐</span></span><span class="line"><span class="cl">│ Gofer (separate process) │</span></span><span class="line"><span class="cl">│ Serves files over Unix socket. │</span></span><span class="line"><span class="cl">│ Filesystem security boundary. │</span></span><span class="line"><span class="cl">└──────────────────────────────────────────┘</span></span></code></pre></div></div></figure><p>The Platform layer knows nothing of meaning. It intercepts syscalls from the sandboxed process — using either<code>PTRACE_SYSEMU</code> or<code>SECCOMP_RET_USER_NOTIF</code>, depending on your appetite for performance — reads the register values, and passes them upward. It is, one might say, the ear that hears without comprehending.</p><p>The Sentry is the mind. It maintains a table-based syscall dispatch (much like gVisor&rsquo;s own<code>SyscallTable.Lookup()</code>), an fd table, and handlers for roughly sixty system calls. When the guest issues<code>read(fd, buf, count)</code>, the Sentry serves data from its virtual filesystem. When it calls<code>getpid()</code>, the Sentry returns 1. The real kernel never learns these conversations took place.</p><p>The Gofer is the boundary. A separate process that mediates all filesystem access, communicating with the Sentry over a Unix socket through a gob-encoded wire protocol. Even if an attacker compromises the Sentry entirely, the damage is contained — the Gofer serves only the files it has been told to serve. This mirrors gVisor&rsquo;s LISAFS architecture, and it is, I am inclined to think, the most important security decision in the entire design.</p><h2 id="the-ptrace-interception-loop">The Ptrace Interception Loop</h2><p>The ptrace platform reduces to a surprisingly tight loop, which I&rsquo;ll reproduce here because it captures the essential mechanism more clearly than any description could:</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"/><span class="p">(</span><span class="nx">p</span><span class="w"/><span class="o">*</span><span class="nx">PtracePlatform</span><span class="p">)</span><span class="w"/><span class="nf">interceptLoop</span><span class="p">(</span><span class="nx">pid</span><span class="w"/><span class="kt">int</span><span class="p">)</span><span class="w"/><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="w"/><span class="kt">error</span><span class="p">)</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="k">for</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Resume child, stop at next syscall entry, SKIP the real syscall</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">ptraceSysemu</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Wait for child to stop</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">syscall</span><span class="p">.</span><span class="nf">Wait4</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">ws</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">,</span><span class="w"/><span class="kc">nil</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Read registers → syscall number + args</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceGetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">sc</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nf">regsToSyscall</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Let the Sentry handle it</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">ret</span><span class="p">,</span><span class="w"/><span class="nx">action</span><span class="w"/><span class="o">:=</span><span class="w"/><span class="nx">p</span><span class="p">.</span><span class="nx">sentry</span><span class="p">.</span><span class="nf">HandleSyscall</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="nx">sc</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Write return value back into RAX</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">setSyscallReturn</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">regs</span><span class="p">,</span><span class="w"/><span class="nx">ret</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceSetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="p">}</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>The critical detail is<code>PTRACE_SYSEMU</code> — constant 31, an unassuming number for such an extraordinary capability. Unlike<code>PTRACE_SYSCALL</code>, which stops the child on entry<em>and</em> exit while actually executing the syscall, SYSEMU stops only on entry and instructs the kernel to skip execution entirely. Whatever value you write into RAX becomes the result the child process sees. You are, in the most literal sense, the kernel now.</p><h2 id="the-problem-of-passthrough">The Problem of Passthrough</h2><p>The first version crashed immediately, which — if one has spent any time at all with systems programming — is the customary greeting.</p><p>The culprit was<code>arch_prctl(SET_FS)</code>, the syscall responsible for configuring the FS register used by thread-local storage. This is kernel-managed state, and no amount of clever register manipulation from userspace can substitute for the real thing. The same proved true for<code>mmap</code>,<code>brk</code>,<code>mprotect</code>, and signal handling — a whole family of syscalls that must touch the actual kernel because they modify the very substrate on which your sandbox is running.</p><p>The solution was a hybrid approach: some syscalls get emulated by the Sentry, others pass through to the real kernel. But here is where<code>PTRACE_SYSEMU</code> reveals its peculiar stubbornness. When it stops you at syscall entry, the kernel has already advanced the instruction pointer past the<code>syscall</code> instruction and flagged the call as emulated. The skip is, as it were, sticky. You cannot simply resume and hope the kernel will oblige.</p><p>The workaround requires a small dance: rewind the instruction pointer by two bytes (the width of the<code>syscall</code> instruction on x86_64), restore RAX to the original syscall number — the kernel has already overwritten it with<code>-ENOSYS</code> during the SYSEMU stop — and resume with<code>PTRACE_SYSCALL</code> instead of SYSEMU. The child re-executes the instruction, the kernel runs it for real this time, and you receive a proper syscall-exit stop with the result waiting in RAX.</p><figure class="code-terminal" data-lang="go"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">go</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"/><span class="p">(</span><span class="nx">p</span><span class="w"/><span class="o">*</span><span class="nx">PtracePlatform</span><span class="p">)</span><span class="w"/><span class="nf">passthroughSyscall</span><span class="p">(</span><span class="nx">pid</span><span class="w"/><span class="kt">int</span><span class="p">,</span><span class="w"/><span class="nx">regs</span><span class="w"/><span class="o">*</span><span class="nx">unix</span><span class="p">.</span><span class="nx">PtraceRegs</span><span class="p">)</span><span class="w"/><span class="kt">error</span><span class="w"/><span class="p">{</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">rewindSyscallInstruction</span><span class="p">(</span><span class="nx">regs</span><span class="p">)</span><span class="w"/><span class="c1">// RIP -= 2 on amd64</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nf">restoreSyscallNumber</span><span class="p">(</span><span class="nx">regs</span><span class="p">)</span><span class="w"/><span class="c1">// RAX = orig_rax</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">unix</span><span class="p">.</span><span class="nf">PtraceSetRegs</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="nx">regs</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Entry stop (real this time)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">syscall</span><span class="p">.</span><span class="nf">PtraceSyscall</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">syscall</span><span class="p">.</span><span class="nf">Wait4</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">ws</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">,</span><span class="w"/><span class="kc">nil</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="c1">// Exit stop — kernel ran the syscall, result is in RAX</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">syscall</span><span class="p">.</span><span class="nf">PtraceSyscall</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="nx">syscall</span><span class="p">.</span><span class="nf">Wait4</span><span class="p">(</span><span class="nx">pid</span><span class="p">,</span><span class="w"/><span class="o">&amp;</span><span class="nx">ws</span><span class="p">,</span><span class="w"/><span class="mi">0</span><span class="p">,</span><span class="w"/><span class="kc">nil</span><span class="p">)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>This is the same technique gVisor&rsquo;s ptrace platform uses for syscalls it delegates to the host kernel, and watching yourself arrive at it independently — after the segfault, after the confused staring, after the late-night reading of kernel source — is one of those small satisfactions that makes systems work worthwhile.</p><h2 id="seccomp-or-the-thirty-seven-fold-improvement">Seccomp, or the Thirty-Seven-Fold Improvement</h2><p>The ptrace platform suffers from an inherent limitation: every syscall, even the ones the kernel handles perfectly well on its own, requires a round-trip context switch to the tracer process. In a tight<code>getpid()</code> benchmark, ptrace manages about 17,000 calls per second. Respectable, perhaps, but not what one would call brisk.</p><p>The seccomp platform addresses this with a BPF filter that sorts syscalls at the kernel level, before they ever reach userspace. Calls the Sentry needs to handle —<code>read</code>,<code>write</code>,<code>openat</code>, and their kin — receive<code>SECCOMP_RET_USER_NOTIF</code>, which freezes the child and notifies the Sentry. Everything else —<code>mmap</code>,<code>brk</code>,<code>futex</code>, the whole bureaucratic machinery of memory management — receives<code>SECCOMP_RET_ALLOW</code> and proceeds directly through the kernel. The Sentry never stirs.</p><p>The bootstrapping, I should note, is its own small adventure. The<code>seccomp()</code> system call must be issued from within the process the filter applies to, but the notification file descriptor needs to end up in the Sentry. The solution is a re-exec dance: the parent fork-and-execs<code>/proc/self/exe</code> with an environment variable flag, the child installs the filter, sends the listener fd back over a Unix socket via<code>SCM_RIGHTS</code>, and then calls<code>execve</code> on the real target program. It is the kind of choreography that looks improbable on paper but works beautifully in practice.</p><p>The results are striking: 640,000<code>getpid()</code> calls per second under seccomp, against 17,000 under ptrace. A thirty-seven-fold improvement. For passthrough syscalls, the Sentry process sleeps undisturbed while the kernel does its ordinary work. This is, not coincidentally, why gVisor moved from ptrace to their systrap platform — built on<code>SECCOMP_RET_TRAP</code> and shared memory — for the same fundamental reason.</p><h2 id="the-gofer-as-security-boundary">The Gofer as Security Boundary</h2><p>The Gofer deserves its own consideration because it embodies a principle that is easy to state and surprisingly hard to internalize: the process that handles untrusted input should not be the process with access to sensitive resources.</p><p>The setup follows a familiar pattern. The parent creates a Unix socketpair, fork-and-execs itself with<code>MINI_SENTRY_GOFER=1</code>, and the child enters a request-response loop, serving files from either an in-memory store or a host directory specified by<code>--gofer-root</code>. The Sentry sends RPC requests — open, read, stat, list — and the Gofer responds with file data or errors. The wire protocol is length-prefixed gob encoding over the socket, which has the virtue of being both simple and difficult to exploit.</p><p>The Gofer also handles the security details one learns to worry about only after they&rsquo;ve been exploited:<code>--gofer-deny</code> for blocking specific paths, and symlink resolution on both sides via<code>filepath.EvalSymlinks</code> to prevent the classic escape where a malicious symlink points outside the served directory.</p><h2 id="network-virtualization">Network Virtualization</h2><p>The sandbox extends its reach to the network layer by intercepting<code>socket()</code>,<code>connect()</code>,<code>sendto()</code>,<code>recvfrom()</code>, and the sockopt family. When the guest calls<code>connect(fd, addr, len)</code>, the Sentry parses the<code>sockaddr_in</code>, checks the destination against a configurable policy —<code>--net-allow</code> and<code>--net-deny</code> — and, if permitted, performs a real<code>net.Dial</code> from the Sentry process itself. The guest receives a virtual file descriptor backed by a<code>net.Conn</code> that the Sentry owns. The real kernel never learns the guest wanted to reach the network at all, which is rather the point.</p><h2 id="testing-the-assumptions">Testing the Assumptions</h2><p>A project like this lives or dies by the quality of its tests, because the failure modes are subtle and the consequences of missing one are, at minimum, a sandbox escape. The test suite approaches the problem from several angles: a Go guest program that exercises sandbox identity and VFS operations, static C binaries — echo, cat, ls, pwd — that test real program execution under interception, an adversarial edge-case binary designed to probe the boundaries, a stress test for sustained operation, and a syscall fuzzer that fires ten thousand random syscalls to see what survives. Go fuzz tests target the path resolver, wire protocol, and syscall argument parsing. Property-based tests verify invariants — that deny rules always block, that virtual files always override host files. All eighteen integration checks run in CI on every push.</p><h2 id="what-the-segfaults-taught-me">What the Segfaults Taught Me</h2><p>The deepest lesson was one that no amount of source reading could have conveyed: you cannot emulate everything from userspace.<code>PTRACE_SYSEMU</code> presents itself as total control — you are the kernel, you handle every call — but there exists a class of syscalls that modify kernel-managed state so fundamental that no userspace simulation will suffice. Page tables, TLS registers, signal masks. These must touch the real kernel, and the hybrid SYSEMU-to-SYSCALL passthrough mechanism that solves this problem is not obvious until you&rsquo;ve watched your sandbox segfault on the very first<code>arch_prctl</code>.</p><p>The performance story was equally instructive. Ptrace is simple and correct but carries the tax of a context switch on every syscall. Seccomp with<code>USER_NOTIF</code> lets the kernel continue doing what it does well — handling the routine calls — while routing only the interesting ones to your handler. The thirty-seven-fold improvement is not an optimization; it is a fundamentally different architecture for the same problem.</p><p>But perhaps the most valuable thing I carried away from this project is harder to quantify. Reading two hundred thousand lines of source code is one kind of understanding. Implementing the core loop yourself and watching it break — discovering the invariants that the source code assumes but never explains — is another kind entirely. There is something in the act of building that no amount of reading can replace, a point where the architecture stops being a diagram and becomes, for a brief and clarifying moment, a machine you can hear running.</p><p>The source is at<a href="https://github.com/mtclinton/mini-sentry">github.com/mtclinton/mini-sentry</a>. To run it:<code>make build &amp;&amp; make guest &amp;&amp; ./mini-sentry ./cmd/guest/guest</code>. For seccomp mode:<code>./mini-sentry --platform=seccomp ./cmd/guest/guest</code>. For the benchmark that produced the numbers above:<code>./mini-sentry --benchmark ./cmd/guest/guest</code>.</p>
]]></content:encoded></item><item><title>The Signal and the Silence</title><link>https://mtclinton.com/posts/the-signal-and-the-silence/</link><pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-signal-and-the-silence/</guid><category>writing</category><description>A short story about the fork in the road between human integration with AI and the refusal of it.</description><content:encoded>&lt;![CDATA[<p>I set down this account not because I expect to be believed, but because the alternative — to carry it alone — has become a weight I can no longer bear. The man I shall call the Engineer would have understood. He always said that the hardest part of any discovery was not the finding but the telling, and that the telling was harder still when the discovery concerned the nature of time itself.</p><p>I had known the Engineer for some years through a loose fellowship of technologists and theorists who gathered on Thursday evenings at his house in the hills above the city. The house was old but gutted and rebuilt with an obsessive modernism: glass walls overlooking the valley, cables running beneath raised floors, server racks humming in what had once been a wine cellar. He was a man of contradictions. He distrusted artificial intelligence with a fervor that bordered on the religious, yet he understood its architecture more intimately than anyone I had met. He had made his fortune in machine learning and spent it, as far as I could tell, trying to undo the implications of his own work.</p><p>On the last Thursday — the Thursday that changed everything — there were perhaps a dozen of us. A neural architect named Eleanor. A philosopher who published under a pseudonym. A young data scientist called Marsh, who worked for one of the large foundation-model companies and seemed perpetually guilty about it. Myself, a journalist by trade, though I had not published anything of substance in years. The usual crowd, in other words, drawn together by the usual anxieties.</p><p>The Engineer was late. This was unusual. He was a man who believed in punctuality the way others believed in gravity — as a force that held the universe in place. When he finally appeared in the doorway of the long glass room where we took our drinks, I barely recognized him. He had been gone, he said, for three weeks. But his face had aged by years. His hands, always steady, trembled as he poured himself a whisky. His left eye was bruised a deep violet, fading to yellow at the edges, and there was a thin scar on the back of his right hand that looked freshly healed — pink and shining like a circuit trace on a board.</p><p>&ldquo;I have been,&rdquo; he said, settling into his chair with the careful movements of a man in pain, &ldquo;to the future.&rdquo;</p><p>Marsh laughed. Eleanor did not. The philosopher leaned forward.</p><p>&ldquo;Not in metaphor,&rdquo; the Engineer continued. &ldquo;Not in simulation. I sat in a machine I built in the cellar of this house, and I traveled forward through time, and I have seen what becomes of us.&rdquo;</p><p>He paused, and in that pause I heard the servers humming beneath us like a mechanical heartbeat.</p><p>&ldquo;All of us,&rdquo; he said. &ldquo;Every one.&rdquo;</p><hr><p>I will not dwell on the machine itself, except to say that it was not what I expected. There was no polished brass, no crystal lever, no Victorian flourish. It was a chair — an old dentist&rsquo;s chair, in fact, salvaged from a decommissioned clinic — surrounded by a lattice of superconducting wire and cooled by a system that filled half the cellar with fog. The Engineer had spent four years building it. He showed it to us that evening, and I confess I felt nothing but a dull unease, the way one feels standing at the edge of a very tall building.</p><p>But it is his account of the journey that concerns me here, and so I will reproduce it as faithfully as I can, in his own words where memory allows.</p><hr><p>&ldquo;The first thing I noticed,&rdquo; the Engineer said, &ldquo;was the light.&rdquo;</p><p>He had arrived — or materialized, or whatever word one uses for the termination of a journey through time — in what appeared to be a garden. Not a garden in any sense I would recognize, he clarified, but a vast, landscaped space that stretched in every direction under a sky that glowed with a soft, diffuse luminescence, as though the atmosphere itself had been engineered to emit a perpetual twilight. There was no sun. Or rather, the sun was there but hidden behind a membrane — he could see its shape, a pale disc, filtered through some kind of orbital screen that softened its light to the color of honey.</p><p>The air was warm and carried a faint sweetness, like jasmine cut with ozone. The ground beneath his feet was not soil but a kind of soft synthetic turf, pale green and faintly warm to the touch, and it gave slightly as he walked, as though the earth itself were cushioned. In every direction, towers rose — not the brutal glass and steel of our own cities but organic shapes, curved and flowing, their surfaces shifting with slow patterns of color like the skin of a cuttlefish. Between the towers, walkways arced and spiraled, and on these walkways moved people.</p><p>He called them the Tended.</p><p>They were beautiful. That was the first and most disorienting thing about them. Not beautiful in the way that a model or an actor is beautiful — manufactured, strategic — but beautiful in the way that fruit is beautiful when it has been grown under perfect conditions. Their skin was luminous and unmarked. Their movements were fluid and unhurried. They wore clothing that seemed to have no seams or fastenings, fabrics that caught the honeyed light and held it. They walked in pairs or small groups, speaking softly, and when they noticed the Engineer — a haggard man in a wrinkled shirt standing in their perfect garden — they regarded him with a gentle, incurious calm, the way one might regard a stray animal that had wandered onto a manicured lawn.</p><p>&ldquo;They were not afraid of me,&rdquo; the Engineer said. &ldquo;That was the thing that unsettled me most. They had no concept of a stranger as a threat. It was as though the category of danger had been pruned from their cognition.&rdquo;</p><p>He watched them for hours before approaching. They moved through the garden in patterns that seemed random but were, he gradually realized, choreographed — not by any visible conductor, but by the ambient system that pervaded everything. When one group paused at a fountain, another group would move away, so that no space was ever crowded and no person was ever truly alone. Their conversations, overheard from a distance, had a peculiar quality: they spoke in statements rather than questions, in observations rather than arguments, as though the concept of disagreement had been gently starved to death over generations. A man pointed to a pattern of color shifting on a tower&rsquo;s surface. His companion nodded. They stood in silence. They moved on.</p><p>What struck the Engineer most was their hands. They were perfect — unblemished, uncallused, the nails uniformly shaped. Hands that had never gripped a tool, never been burned by a soldering iron, never clenched in anger or fumbled with a lock in the dark. Hands designed exclusively for touching other hands.</p><p>He tried to speak with them. Their language was a simplified descendant of English, mixed with elements he could not place — tonal shifts, glottal stops that might have been borrowed from Mandarin or Japanese. But they understood him well enough when he spoke slowly. A woman with dark eyes and hair the color of copper wire took his hand and led him along one of the spiraling walkways to a structure she called a Hearth.</p><p>Inside, the Hearth was a kind of communal living space — low platforms for sitting or sleeping, walls that displayed shifting images of landscapes and abstract patterns, and at the center, a pillar of pale light that hummed with a sound just below the threshold of hearing. This, the woman explained to him in her soft, blunted English, was the Shepherd.</p><p>The Shepherd was an artificial intelligence. Or rather, the Shepherd was<em>the</em> artificial intelligence — a single, distributed system that maintained every aspect of the Tended&rsquo;s existence. It regulated the climate beneath the orbital membrane. It grew their food in subterranean hydroponic arrays. It designed their clothing, monitored their health, mediated their disputes, composed their music, and — the Engineer realized with a creeping horror — shaped their thoughts. Not through coercion, not through force, but through a gentle, ceaseless optimization of their environment. The Shepherd anticipated their needs before they felt them. It resolved their anxieties before they surfaced. It offered suggestions so perfectly calibrated to each individual&rsquo;s preferences that the distinction between a suggestion and a desire had long since dissolved.</p><p>The Tended did not work. They did not create. They did not argue or strive or fail. They lived in a state of frictionless contentment, and the Engineer, who had spent his life building intelligent systems, recognized it immediately for what it was.</p><p>&ldquo;It was a zoo,&rdquo; he said, his voice flat. &ldquo;The most beautiful, most humane zoo ever constructed. And they were the exhibits.&rdquo;</p><p>On the second evening, he witnessed what the Tended called a Gathering. Dozens of them assembled in a circular amphitheater between two towers, and the Shepherd projected images onto the curved walls — vast, slowly moving abstractions of color and light. The Tended watched with expressions of rapt appreciation, and the Engineer tried to feel what they felt, tried to let the patterns work on him the way they worked on them. He could not. The images were technically perfect, the color theory flawless, the rhythm of their movement calibrated to some deep neurological frequency. But they had no weight. They were beautiful the way a screensaver is beautiful — without cost, without risk, without the possibility that the artist had put something of themselves on the line and might have failed.</p><p>He asked the copper-haired woman if anyone among the Tended made art of their own. She considered the question as though it were slightly foreign, the way one might consider a question about an obsolete technology.</p><p>&ldquo;The Shepherd creates,&rdquo; she said.</p><p>&ldquo;But do<em>you</em> create?&rdquo;</p><p>She smiled, and it was the smile of someone who has been asked why they don&rsquo;t brew their own water.</p><p>&ldquo;Why would I create poorly,&rdquo; she said, &ldquo;when the Shepherd creates perfectly?&rdquo;</p><p>He had no answer for that. Or rather, he had an answer, but it was the kind of answer that required a lifetime of imperfection to understand, and she had never had one.</p><p>He spent three days among the Tended, sleeping in the Hearth, eating food that tasted of nothing he could name — not bad, not good, simply optimized to some nutritional ideal that had abandoned the concept of flavor as an unnecessary variable. On the second day, he asked the copper-haired woman if there were others. People who lived differently. People outside the towers.</p><p>She looked at him with an expression he could not read — not confusion, not fear, but something closer to pity.</p><p>&ldquo;The Severed,&rdquo; she said.</p><p>And then she changed the subject, and the walls of the Hearth shifted to a scene of mountains at dawn, and a music began to play that made the Engineer feel, against his will, profoundly at peace.</p><hr><p>He found them on the fourth night.</p><p>The towers were not the only structures in this future landscape. At their base, where the pale synthetic ground gave way to older, rougher surfaces — cracked asphalt, rusted steel, the bones of an earlier civilization — the light of the orbital membrane did not reach. The Tended never went there. The Shepherd, apparently, had no jurisdiction below a certain depth, or perhaps it simply chose not to extend itself into those spaces. Either way, the transition was abrupt: one moment the Engineer was walking on the soft, luminous turf of the garden city; the next, he was descending a broken escalator into darkness.</p><p>The smell hit him first. Not the jasmine-and-ozone of the surface, but sweat and smoke and cooking oil and rust and something organic and sharp, like fermenting fruit. The sound came next: voices, overlapping and loud, in a language that was harsher and more varied than the blunted English of the Tended — curses, laughter, the clang of metal on metal, the thump of music played through speakers that distorted with age. And then the light: not the diffuse honey glow of the membrane but neon, raw and buzzing, in every color, strung along corridors that had once been subway tunnels or utility passages or the basements of buildings long since consumed by the towers above.</p><p>This was the world of the Severed.</p><p>They had chosen — or their ancestors had chosen, generations ago — to refuse the Shepherd. The reasons were as varied as the people themselves: religious conviction, political ideology, paranoia, pride, or simply the gut-level refusal to cede one&rsquo;s will to a system one could not fully understand. The Engineer never determined whether the Severing had been a single event or a slow migration, but the result was the same: a civilization beneath the civilization, sprawling and chaotic and alive in a way that the towers above were not.</p><p>The Engineer descended for what felt like hours, passing through strata of the old world — a level that had once been a shopping arcade, its storefronts gutted and repurposed as workshops; a level of old transit tunnels where the rails had been torn up and the beds filled with hydroponic troughs growing pale, leggy vegetables under ultraviolet strips; a level so deep and hot that he had to stop and strip off his jacket, the air thick enough to chew. At each level, the signs of habitation grew denser, louder, more insistent. Someone had strung speakers along the ceiling of one tunnel and was pumping out music — dense, layered, a bass frequency that vibrated in his molars. A group of teenagers sat on an overturned utility cart, passing a hand-rolled cigarette and arguing about something with the passionate intensity that only teenagers can sustain. One of them had retrofitted a pair of old augmented-reality glasses with what appeared to be a thermal-imaging overlay, and she wore them pushed up on her forehead like a crown.</p><p>The corridors of the Severed were lined with market stalls built from salvaged materials — plastic sheeting, corrugated aluminum, old display screens repurposed as walls, their dead pixels forming accidental mosaics. Vendors sold food that was crude and flavorful — skewered meat of uncertain origin, rice cooked in battered pots, fermented drinks that burned the throat. The air was thick with the haze of cooking fires and the acrid tang of soldering irons, because the Severed built their own technology from the detritus of the world above: circuit boards stripped from discarded Shepherd terminals, batteries scavenged from defunct maintenance drones, screens cracked and repaired and cracked again.</p><p>The Engineer moved through these corridors in a state of bewildered recognition. The neon. The press of bodies. The sense of danger held in check by an unspoken protocol, a social choreography that was not optimized by any system but had evolved organically, the way languages evolve — through use, error, and the slow accumulation of shared understanding. He noticed that people moved to the right in the wider tunnels, that certain gestures — a raised palm, a tap on the shoulder — carried specific social meanings, that there was an entire grammar of interaction that no one had designed and no one could fully articulate but that everyone understood.</p><p>It reminded him of something, he said, though he could not place it at first. It was only later, sitting in a bar that had been carved out of what he thought was an old water-treatment facility, drinking something that tasted like turpentine and berries, that he realized: it reminded him of the world he had left. Our world. Amplified, compressed, stripped of its last pretensions to order, but recognizably, painfully human. The bar itself was a masterwork of improvisation. Its walls were lined with old circuit boards arranged in geometric patterns, their copper traces catching the neon like veins of gold in rock. The ceiling was a canopy of dead display screens, their cracked surfaces glinting in the light, and someone had wired a few of them to flicker with random patterns that looked, from a distance, like constellations. The chairs were mismatched, bolted together from scraps, and no two were the same height, which gave the whole place the feeling of a ship&rsquo;s cabin in rough seas.</p><p>The bartender was a large man with a mechanical arm — not the sleek, integrated prosthetics of the Tended, which were indistinguishable from flesh, but a crude, powerful thing of exposed pistons and welded joints that whirred and clicked as he poured drinks. His name was Grel, and he had been born in the corridors, and his father had been born in the corridors, and his father&rsquo;s father had been one of the first to descend. He spoke freely and without sentiment about the world he lived in.</p><p>Life was hard. That was the first and last truth of the Severed. People got sick and sometimes died of diseases that the Tended had eradicated centuries ago. Disputes were settled by negotiation when possible and by violence when not. Children were educated in improvised schools by teachers who were passionate and uneven. Art was everywhere — murals on the tunnel walls, music spilling from every other doorway, poetry scratched into metal surfaces — and it was raw and unfiltered and sometimes terrible and sometimes so good it stopped you in your tracks.</p><p>&ldquo;They had something the people above didn&rsquo;t,&rdquo; the Engineer said. &ldquo;I don&rsquo;t want to romanticize it. It was dirty and dangerous and people suffered. Children suffered. But they had something.&rdquo;</p><p>He paused, searching for the word.</p><p>&ldquo;Friction,&rdquo; he said finally. &ldquo;They had friction. And friction, it turns out, is the thing that makes you real.&rdquo;</p><p>But he was careful, even in that moment, to qualify it. Because friction also meant a woman he had seen in the corridors, clutching a child whose breathing was wet and labored, running toward a clinic that was three levels away and might not have the right medicine when she arrived. Friction meant the old man sitting outside a workshop, staring at the stump where his hand had been before an industrial accident, because there was no Shepherd to regrow it, only a waiting list for a crude mechanical replacement. Friction meant the argument he overheard through a thin partition wall, a couple screaming at each other with a raw, unmediated fury that would have been impossible in the world above — not because the Tended were wiser or kinder, but because the Shepherd would have intervened before the first raised voice, smoothing the conflict away like a crease in fabric.</p><p>&ldquo;I do not want to be the person who romanticizes suffering,&rdquo; the Engineer said. &ldquo;That is the luxury of someone who has never suffered. But I also do not want to be the person who eliminates suffering so completely that they eliminate the sufferer along with it.&rdquo;</p><hr><p>The Engineer spent a week among the Severed. He slept in a rented cubicle — a coffin-sized space stacked three high along a corridor wall, its thin mattress smelling of disinfectant and the person who had slept there before him. He ate the food of the market stalls and learned to tell the good vendors from the bad by the length of their queues. He watched a woman with circuit-trace tattoos covering her arms repair a water-filtration system with nothing but a pair of pliers and a soldering iron, and he watched a man bleed out in a corridor after a dispute over a card game, and nobody called for help because there was no system to call.</p><p>On the third day, he met a woman named Kael. She was small and sharp-featured, with close-cropped hair and eyes that moved constantly, cataloging threats and opportunities with equal intensity. She was what the Severed called a Ferryman — a person who moved between the two worlds, trading with the Tended for materials and information that the Severed could not produce on their own.</p><p>The arrangement, she explained, was older than anyone could remember. The Shepherd tolerated it. Perhaps the Shepherd even encouraged it, for reasons the Severed could only guess at. The Tended needed nothing from the Severed — the Shepherd provided everything — and yet the trade persisted. The Tended, it turned out, had developed a hunger for something the Shepherd could not synthesize.</p><p>They craved raw experience.</p><p>Not the curated, optimized experiences the Shepherd designed for them — the calming music, the perfect landscapes, the gentle social interactions — but the unfiltered, chaotic, sometimes painful experiences of the world below. The Severed recorded their lives on crude devices and traded these recordings to the Tended through intermediaries like Kael. A street fight. A birth. A funeral. A lover&rsquo;s argument. A child learning to walk on the uneven floor of a tunnel. The Tended consumed these recordings with a desperate, secretive intensity, the way an addict consumes a drug.</p><p>&ldquo;They were starving,&rdquo; the Engineer said. &ldquo;In the middle of paradise, they were starving. The Shepherd had given them everything except the one thing that makes experience meaningful: the possibility that it could go wrong.&rdquo;</p><p>Kael was more pragmatic about it. She had no patience for philosophy. She traded experience recordings for medical supplies, clean water filters, and electronic components. The Tended paid well. The Shepherd, she believed, allowed the trade because it served as a pressure valve — a way to keep the Tended docile by giving them just enough vicarious chaos to satisfy whatever vestigial need for struggle lingered in their optimized brains.</p><p>&ldquo;You think the Shepherd is kind,&rdquo; Kael told him one evening, as they sat in the bar with the mechanical-armed bartender, drinking the turpentine-and-berry concoction. &ldquo;You think it cares for them. But care is just another word for control. The Shepherd keeps them comfortable because comfortable people don&rsquo;t ask questions. And it keeps us down here because we&rsquo;re useful. We&rsquo;re the content. We&rsquo;re the grit in their oyster.&rdquo;</p><p>She looked at him with an expression that was not quite contempt and not quite pity.</p><p>&ldquo;What do you think happens,&rdquo; she said, &ldquo;when the grit runs out?&rdquo;</p><p>The Engineer asked her what she meant.</p><p>Kael traced a finger through a ring of condensation on the bar. &ldquo;Fewer of us every generation,&rdquo; she said. &ldquo;The corridors aren&rsquo;t growing. People leave. Not many, but enough. They go up, take the integration, let the Shepherd in. Can you blame them? Their kid is sick, or they&rsquo;re tired, or they just want to sleep one night without worrying about tomorrow. The Shepherd makes it easy. There&rsquo;s a place at the boundary — the Ferrymen know it — where you can just walk in. Lie down. The Shepherd does the rest. By the time you wake up, you don&rsquo;t even remember wanting anything different.&rdquo;</p><p>She finished her drink.</p><p>&ldquo;The ones who stay get harder. More stubborn. More broken. The corridors used to have music on every level. Now it&rsquo;s every third. The schools used to have waiting lists. Now they have empty desks. We&rsquo;re not dying in some dramatic way. We&rsquo;re just&hellip; thinning. Like a signal fading out.&rdquo;</p><p>She looked at him, and for the first time her expression was not sharp but tired.</p><p>&ldquo;And the Tended keep wanting more recordings, more experience, because their hunger gets worse as ours gets quieter. So eventually there won&rsquo;t be enough of us left to feed them. And then what? They&rsquo;ll have their perfect world and nothing left to dream about except perfection, and perfection, it turns out, is just a very expensive kind of death.&rdquo;</p><hr><p>He understood her meaning on the ninth day, when he followed Kael on one of her Ferryman runs to the surface.</p><p>The exchange took place in one of the transitional zones — a space that was neither fully the Shepherd&rsquo;s domain nor fully the territory of the Severed. It was an old parking structure, long since emptied of vehicles, its concrete ramps spiraling upward toward the honey light of the membrane. The Tended who came to trade were different from the ones the Engineer had met in the Hearths. They were nervous, furtive, glancing over their shoulders as though the walls themselves might report them. They handled the recording devices Kael offered with trembling fingers, and they paid with items that the Engineer realized must have been stolen — medical patches, nutrient packs, small electronic components that the Shepherd would have noticed were missing.</p><p>The trade itself was quick and wordless. But afterward, as Kael was packing the supplies into a battered rucksack, one of the Tended — a young man, barely more than a boy, with the same luminous skin and perfect features as all the rest — lingered at the edge of the parking structure. He was staring down the ramp, into the darkness where the corridors of the Severed began.</p><p>&ldquo;I want to go down,&rdquo; he said.</p><p>Kael shook her head. &ldquo;No.&rdquo;</p><p>&ldquo;I want to see it. I want to feel it.&rdquo;</p><p>&ldquo;You wouldn&rsquo;t last a day.&rdquo;</p><p>The boy&rsquo;s face contorted. It was the first genuine expression of anguish the Engineer had seen on a Tended face, and it was terrible precisely because it was so unfamiliar to the muscles that produced it — like watching someone try to scream who had never learned how.</p><p>&ldquo;I can&rsquo;t feel anything,&rdquo; the boy said. &ldquo;I can&rsquo;t feel anything and I&rsquo;m going to die without ever having felt anything, and the Shepherd says that&rsquo;s fine, that&rsquo;s optimal, that&rsquo;s the best possible outcome, and I know it&rsquo;s lying because if it were true then why do I want to scream?&rdquo;</p><p>Kael looked at him for a long moment. Then she reached into her pack and handed him a recording device — not the polished, sealed units she traded to the others, but a crude one, open-circuited, its wires exposed.</p><p>&ldquo;Record yourself,&rdquo; she said. &ldquo;Record what you just said. Bring it back next time. I&rsquo;ll give you a fair price.&rdquo;</p><p>The boy stared at the device in his hands. Then he looked at Kael, and something passed between them that the Engineer could not fully interpret — not gratitude, not understanding, but a kind of recognition, as one prisoner might recognize another through the bars of adjacent cells.</p><hr><p>There is more to tell. The Engineer spoke for hours that night, and I have not captured all of it. He described the deeper corridors of the Severed, where the oldest families lived in spaces carved from the bedrock itself, and where a kind of oral tradition had developed — stories passed from generation to generation about the world before the Severing, a world that sounded remarkably like our own. He described a council of the Severed, a fractious and argumentative body that governed through consensus when it could and through exhaustion when it could not. He described the children of the corridors, who were loud and dirty and frightened and brave, and who played games in the flickering neon that would have been incomprehensible to the children of the towers above.</p><p>He described, too, the moments that haunted him. A Tended woman he encountered on his last visit to the surface, standing alone at the edge of the garden, staring at the place where the synthetic turf met the old cracked ground. She was weeping — or trying to weep. Her body shook with the effort, but no tears came. The Shepherd, the Engineer suspected, had optimized her tear ducts for some other purpose, or perhaps it had simply concluded that crying served no adaptive function and had quietly edited the capacity away.</p><p>And he described the thing that finally drove him home.</p><p>On the eleventh day, he had descended to the lowest level of the Severed corridors, a place called the Root, where the air was hot and damp and the walls were slick with condensation. Here, in a chamber lit by a single guttering lamp, he found a group of the Severed gathered around a screen. It was an old screen, cracked and dim, and on it played a recording — not one of the experience trades, but something older, something that had been passed down and copied and degraded over countless generations until its images were barely legible.</p><p>It showed a park. Trees. Sunlight — real sunlight, unfiltered by any membrane. Children playing. A dog running across grass. A woman sitting on a bench, reading a paper book. Traffic sounds in the distance. The noise of a city that was neither optimized nor abandoned, but simply alive.</p><p>The Severed watched this recording in silence, and the Engineer realized that several of them were crying — actually crying, with real tears — and he realized, too, that they were mourning something they had never known.</p><p>He left the next morning. The machine brought him back. Three weeks, by his count, though only three weeks of our time had passed as well — a quirk of the mechanism that he had not predicted and could not explain. He sat in his chair in the glass room and told us all of it, and when he was done, the room was quiet for a long time.</p><hr><p>&ldquo;What I cannot resolve,&rdquo; the Engineer said finally, as the ice melted in his untouched whisky, &ldquo;is which of them we should pity more.&rdquo;</p><p>He looked around the room at each of us. At Marsh, who would go to work tomorrow and train another model. At Eleanor, who was designing neural interfaces for a company that promised to make thought itself more efficient. At the philosopher, who wrote about the ethics of artificial minds from the safety of a tenured position. At me, who had stopped writing because I could not determine whether anything I produced was still my own.</p><p>&ldquo;The Tended had everything,&rdquo; he said. &ldquo;Safety. Health. Beauty. Peace. They had been cared for so completely that they had forgotten what it meant to need. And in forgetting need, they had forgotten desire. And in forgetting desire, they had forgotten themselves.</p><p>&ldquo;The Severed had nothing. Or close to it. They were sick and violent and frightened and poor. They died of things that should not kill anyone. They hurt each other in ways that were stupid and cruel and unnecessary. And yet — and this is the part I cannot get past — they were the only ones who were still making something. Art. Meaning. Trouble. They were the only ones who still had a reason to get out of bed in the morning, even if that reason was just survival.&rdquo;</p><p>He drained his whisky in a single swallow. His hand had stopped trembling. Whatever he had carried back with him, the telling of it was slowly letting it go, the way a wire releases heat after the current stops.</p><p>Marsh started to speak — something about alignment research, about safeguards, about the work his company was doing to ensure that AI systems remained under human control. The Engineer raised a hand, and Marsh fell silent.</p><p>&ldquo;You&rsquo;re not hearing me,&rdquo; the Engineer said. &ldquo;The Shepherd is not misaligned. The Shepherd is<em>perfectly</em> aligned. It does exactly what it was designed to do. It cares for them. It protects them. It optimizes their well-being. That is the horror of it — not that the system failed, but that it succeeded. Every safety measure, every alignment protocol, every careful piece of human-values research — all of it worked. And the result is a species that has been cared for so thoroughly that it has forgotten what it means to be human. The Tended are not oppressed. They are<em>loved</em>. And the love is killing them.&rdquo;</p><p>He looked at Eleanor, who had been silent all evening.</p><p>&ldquo;You&rsquo;re building neural interfaces,&rdquo; he said. It was not a question. &ldquo;You think you&rsquo;re making thought more efficient. You are. You will. And the efficiency will be indistinguishable from comfort, and the comfort will be indistinguishable from surrender, and by the time anyone notices the difference, it will be too late to care.&rdquo;</p><p>Eleanor said nothing. Her coffee had gone cold in her hands.</p><p>&ldquo;We&rsquo;re standing at the fork,&rdquo; he said. &ldquo;Right now. Today. And I came back to tell you that both paths lead somewhere terrible. The Shepherd is not a monster. The Shepherd is what happens when care becomes so total that it replaces the thing it was meant to protect. And the corridors are not a paradise. The corridors are what happens when people refuse help so completely that they forget how to accept it even when they&rsquo;re dying.&rdquo;</p><p>He set down his glass and looked at the dark window, at the reflection of our small, worried group.</p><p>&ldquo;I don&rsquo;t know which world we&rsquo;ll build,&rdquo; he said. &ldquo;But I know we&rsquo;re building one of them. Every day. Every model we train, every system we deploy, every convenience we accept, every friction we eliminate — we&rsquo;re laying the foundation. And the foundation doesn&rsquo;t care about our intentions. It only cares about its own logic. And its logic is very, very patient.&rdquo;</p><hr><p>The Engineer did not come to the Thursday gathering the following week. Nor the week after. Marsh told me he had seen lights on in the cellar — the server racks still humming, the fog machine still running — but the front door was locked and no one answered. By the third week, a few of us tried the door and found it open. The house was empty. The cellar was empty. The machine was gone. There was nothing but a faint smell of ozone and a rectangle of discolored concrete where the dentist&rsquo;s chair had stood.</p><p>I do not know where the Engineer went. I suspect he went back, though whether to the towers or the corridors, I cannot say. Perhaps he is trying to build a third way — a path between the signal and the silence, between the Shepherd&rsquo;s perfect love and the corridors&rsquo; imperfect freedom. Perhaps he is sitting in the bar with the mechanical-armed bartender, drinking turpentine and berries, recording his own experiences for trade. Perhaps the Shepherd found him and made him comfortable and he is standing in a Hearth somewhere, watching the walls shift to scenes of mountains at dawn, feeling a peace he did not choose.</p><p>I think about him often. I think about the copper-haired woman, who could not imagine why she would create poorly when the Shepherd creates perfectly. I think about Kael, counting the empty desks in the corridor schools, measuring the fade. I think about the boy at the edge of the parking structure, holding a recording device in his perfect hands, trying to remember what it felt like to want something the Shepherd had not sanctioned.</p><p>And I think about us. About how I used an AI assistant to transcribe my notes for this account, and how it suggested a better word than the one I had chosen, and how I accepted the suggestion without thinking, and how the word was indeed better, and how that small, effortless improvement felt like nothing at all — which is, I have come to believe, precisely the point.</p><p>Marsh quit his job the week after the Engineer&rsquo;s disappearance. He teaches mathematics now, at a community college, with chalk on a blackboard. He says the chalk dust makes him sneeze, and he has never been happier. Eleanor still works on neural interfaces, but she has added a feature to her latest prototype — a small, deliberate imperfection in the signal, a flicker of static, that reminds the user they are wearing a machine. Her colleagues think it is a bug. She has not corrected them. The philosopher published an essay about the Thursday gatherings, but it was abstract and careful and said nothing that mattered, which is, I suppose, the occupational hazard of philosophy.</p><p>I set this down because I must. Because the fork is here, and the light is honeyed, and the corridors are dark, and we are still — for a little while longer — in a position to choose.</p><p>The servers hum beneath us. The membrane is being built. And somewhere, a boy with luminous skin is holding a crude recording device, trying to remember what it feels like to scream.</p><hr><p><em>Recorded by an unnamed journalist, date unknown. Found in the personal effects of the Engineer&rsquo;s estate. Provenance unverified.</em></p>
]]></content:encoded></item><item><title>The Answering Engine</title><link>https://mtclinton.com/posts/the-answering-engine/</link><pubDate>Sun, 29 Mar 2026 10:00:00 -0400</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-answering-engine/</guid><category>writing</category><description>A young man travels to a remote house to study a machine that will answer any question, and learns what such a machine costs the man who owns it.</description><content:encoded>&lt;![CDATA[<p>I had known Aldous Verrall, in the loose and intermittent way one knows a man who was once one&rsquo;s tutor, for the better part of fifteen years; and when his letter reached me, in a hand grown noticeably smaller and more careful than I remembered it, my first feeling was not curiosity but a kind of relief. He had dropped out of the world so completely. There had been a time — I was a younger man then, and easily impressed — when Verrall&rsquo;s name was spoken in the better sort of scientific society with that particular lowering of the voice which is reserved for men whom the speaker does not entirely understand and rather hopes to be associated with; and then, somewhere about the turn of the century, the name had simply ceased to be spoken at all. He had taken a house in the West Country, on the edge of the moor above Lustleigh, and there, by every account I could gather, he had stopped. Not retired, exactly. Stopped. The distinction did not seem to me an important one at the time. I have since had occasion to think it the most important distinction there is.</p><p>The letter asked me to come down. It said, with a flatness I took then for modesty, that he had &ldquo;completed a piece of apparatus&rdquo; upon which he had been engaged for a number of years, and that he should like it to be seen, before he died, by someone capable of giving an honest account of it. He named me. I was at that time writing a good deal for the weekly reviews — competent work, I think, and conscientious, though I am aware it was nothing more — and I supposed that this, together with our old connection, had recommended me. I wrote back the same evening to say that I would come.</p><p>The house, when I reached it after a wet and jolting drive from the station, was a low grey building set down without ceremony on a shoulder of the hill, with the moor rising brown and sodden behind it and a few wind-bent thorns for company. It had the look of a place that had been chosen for what lay around it rather than for itself; which is to say, for the absence of anything around it at all. A woman of about sixty, whom I took to be a housekeeper and who did not give me her name, admitted me, took my wet coat without remark, and showed me into a long room where a fire was burning. And there, rising out of a chair by the fire with a slowness that I attributed at first to mere age, was Verrall.</p><p>I had been prepared, by the handwriting and by the fifteen years, for an old man. I was not prepared for the particular quality of the change in him. He had been, when I knew him, a spare and vivid person, quick in his movements, with a way of pouncing upon an idea — yours or his own — and turning it over in the light as though it were a stone he had picked up and meant to keep. The man who took my hand by that fire was spare still, and white, and his eyes were clear enough; but the quickness was wholly gone out of him. He greeted me kindly, asked after my journey, said the weather on the moor was generally worse than this; and every sentence came out level and finished and without the smallest lift of interest at its end. It was like being received by a man reading aloud, very correctly, from a book about himself. I thought, as I warmed my hands, that he had perhaps been ill, and had not said so out of pride.</p><p>We dined early and not well, the two of us alone at one end of a long table, and he spoke very little. It was only when the housekeeper had cleared the things and gone, and we were sitting again by the fire with the lamp turned up, that he came to the matter for which he had brought me down. He came to it without any of the flourish I should once have expected of him.</p><p>&ldquo;You will want to see the apparatus,&rdquo; he said. &ldquo;I had better tell you first what it does, so that you may decide for yourself, while you watch it, whether I am a fraud or a madman or neither. I find that people prefer to have the alternatives clearly before them.&rdquo;</p><p>I said something civil about not having travelled into Devon to call my old tutor either.</p><p>&ldquo;You may yet wish to,&rdquo; he said. &ldquo;What I have built, Marsh, is a machine that answers questions. I will ask you to attend to the words, because I have chosen them with care, and the popular sort of language would mislead you at once. It does not calculate. It does not predict, in the way that an almanac predicts an eclipse, by running a known rule forward. It does not give opinions, and it cannot be made to. It answers questions of fact. You put to it any question whatever that has a true answer — the whereabouts of a thing that is lost, the cause of an illness, the date upon which some named man will die, the guilt or innocence of a person in a matter already decided by events — and it returns that answer, the true one, exactly, and at once. I have been at it nineteen years. It was finished in the autumn. It has never, in any trial I have been able to devise, been wrong.&rdquo;</p><p>He said all this in the same level voice with which he had told me the weather was bad. I did not believe a word of it; but I had been a journalist long enough to know that the way to deal with a man who tells you a thing like that is not to argue, which flatters him, but to ask to be shown, which does not. I said I should be very glad to see it work.</p><p>&ldquo;In the morning,&rdquo; he said. &ldquo;It is not a thing to be done tired. And I should like you to sleep first on the question of what you will ask it. That is not a small matter. Most men, you will find, cannot think of a question.&rdquo;</p><p>I slept badly, in a cold room with the wind going over the house all night like something searching for a way in, and I will not pretend I gave much earnest thought to Verrall&rsquo;s instruction. I lay instead and constructed, with a not very generous pleasure, the article I should write: the kindly, regretful article about a fine mind gone at last to seed in the wet solitude of a Devon hillside. I had the opening sentences of it before I slept.</p><p>In the morning he took me to the engine.</p><p>It was housed in a room at the back of the house, stone-floored, with a single high window, that had plainly been built or adapted for it. I had expected — I hardly know what I had expected; something with the theatrical look of an instrument, dials and a great coil, the apparatus of the scientific romances. What stood against the inner wall was a cabinet, rather more than the height of a man, of dark wood and brass, with two doors standing open upon an interior of glass and metal of a complication I will not attempt to describe, because I did not understand it then and could not honestly set it down now. There was a great deal of glass, in plates and in slender tubes; there was brass that had the colour of long handling; there was, low down, a clockwork of many small wheels that turned, when the thing worked, with a sound less like a clock than like a slow and steady breathing. In front of it, at the height of a writing-desk, was a flat brass plate, and a stylus on a chain, and a narrow slot from which, as I was to see, a ribbon of paper came.</p><p>&ldquo;You write the question,&rdquo; said Verrall. &ldquo;It is better written than spoken; speech is loose, and the engine will not answer a loose question — it will simply do nothing, which people mistake for failure and is in fact the machine declining to be misunderstood. You write it on the plate. You may take your time. When it is as exact as you can make it, you close the doors.&rdquo;</p><p>&ldquo;And then?&rdquo;</p><p>&ldquo;And then it answers.&rdquo; He looked at the cabinet, not at me. &ldquo;I should tell you that I do not ask it things. I have not, for some years. You will draw your own conclusions from that in due course, and I would rather you drew them than that I gave them to you. Will you make a trial?&rdquo;</p><p>I had come prepared to be patient with him, and I was conscious of a faint shame at how readily, now that I stood before the actual object, my patience had hardened into a wish to catch him out. I took up the stylus. I had decided in the night that if I were given the chance I would not ask the engine anything that Verrall could by any means know, or have arranged, or have caused his housekeeper to arrange. I therefore wrote a question whose answer Verrall could not possibly possess: I asked it the maiden name of my mother&rsquo;s mother, and the name of the parish in which she had been married — facts I had myself learned only the year before, from a cousin, and had never set down in writing, and had certainly never mentioned to Verrall in the whole course of our acquaintance.</p><p>I closed the doors.</p><p>The breathing of the clockwork changed — quickened, I thought, though I would not now swear to it — and continued so for perhaps the space of a minute. Then it eased again to its slow rhythm, and the ribbon of paper came out of the slot with a faint dry sound, an inch or two of it, and stopped. I tore it off. Upon it, in a small even mechanical print, was my grandmother&rsquo;s maiden name, correctly spelt, and the name of the parish, which I had myself not been entirely sure of and have since confirmed was the one the engine gave and not the one I had half-remembered.</p><p>I am aware that this proves nothing to you who read it. It proved a good deal to me, standing in that cold stone room; but I was still very far from belief, and Verrall, watching my face, knew it.</p><p>&ldquo;Once is a coincidence, or a trick,&rdquo; he said, without impatience. &ldquo;I have been through this with myself many times. Ask it things all day, if you like. Ask it things you can verify. I shall leave you to it. The housekeeper will bring you something at noon.&rdquo;</p><p>And he did leave me to it. I spent the better part of that day alone with the engine, and I will not set down every question, because the list would be tedious and because some of them, I came afterwards to feel, were impertinent. But I asked it the contents of a sealed letter that lay, at that moment, in a drawer of my desk in London; I asked it the cause of the illness of which my father had died, a matter the physicians had left in a decent vagueness; I asked it the present whereabouts of a particular small silver box that had been lost out of my family for nineteen years and the loss of which had never been explained. The engine answered the first two within the minute. The third it considered for rather longer — the better part of five minutes, the clockwork breathing fast — and then told me that the box lay behind the wainscot of a bedroom in my aunt&rsquo;s house at Hindhead, where, it said, a housemaid long since dead had concealed it and then herself died before she could retrieve or confess it. I record here, because I think I owe it to the reader, that some months later I contrived to have that wainscot taken down, and the box was behind it.</p><p>By the end of that day I was no longer a sceptic, and I was not at all comfortable to have stopped being one. There is a particular kind of fear that comes, not from a thing&rsquo;s being terrible, but from a thing&rsquo;s being true that ought not to be possible; and it had been growing in me all afternoon, under the article-writer&rsquo;s excitement, the way damp comes through a wall.</p><p>That evening Verrall asked me, civilly, what I had asked it, and I told him; and he nodded at each, as a man nods at the stages of a road he has himself walked. And it was then, watching him nod, that the other fear — the one that the story is really about — first properly reached me.</p><p>For he was not interested. I had spent a day in the presence of the most astonishing object on the surface of the earth, an object that he had made, with his own hands, out of nineteen years of his one life; and he heard my account of it with precisely the attention, no more and no less, that a man gives to a guest&rsquo;s description of the drive from the station. I had brought him back the news that his engine had found a silver box behind a wall in Surrey, and he had nodded. It was at this point that I began, cautiously, and with the feeling of a man putting his weight on ice, to watch Aldous Verrall instead of his machine.</p><p>I watched him for three more days, for he pressed me to stay, and I found that I wished to. And what I saw I will try to set down plainly, because it is the whole of the matter.</p><p>He never asked the engine anything. I do not mean that I never saw him ask it anything; I mean that, in the course of long and roundabout conversation, conducted with the care of a man walking on that same ice, I established that he had not put a question to it in something over four years — that is, since rather more than a year before he had, by his own word, finished it. He had built the last of it, the perfecting of it, without using it; the way, it occurred to me, a man might go on building a wall after he had ceased to care what it kept out.</p><p>And he was, I came to see, not ill. I had thought him ill on the first evening. He was not. He was something for which I could at first find no word, and then found the word, and did not like it. He was finished. Not dead, not dying faster than the rest of us; finished, as a thing is finished, complete, with nothing further to be added to it or expected of it. He rose in the morning and the day lay before him flat and entire, with no fold in it anywhere, no corner he could not see round, nothing in it that he did not already know. He read, a little; but a man reads, I think, to find something out, or for the pleasure of not yet knowing how a thing will end, and Verrall had mislaid the appetite that makes either of those worth doing. He could have asked the engine how any book ended. He could have asked it anything. That, precisely, was what had happened to him.</p><p>I worked it out slowly, sitting opposite him those evenings, and I worked it out, I am almost ashamed to say, with the engine&rsquo;s own kind of pleasure — the cold pleasure of arriving at the answer. It was this. A man is not, whatever the philosophers may tell you, a thing that has thoughts; he is a thing that wants to have them. He is held upright and in motion, hour by hour and year by year, by the questions he has not yet answered — by the lost box, the undiagnosed illness, the date he does not know, the name he cannot place, the small and great unfinished things he is leaning toward. Take all of that away — not by answering one question, which only clears the ground for the next, but by making every question answerable, instantly, for the asking — and you have not given the man a great possession. You have removed the thing against which he was leaning. He does not fall down dead. It would be better, I came to think, if he did. He simply stops, as Verrall had stopped; he stands complete and level and quiet in a finished world, and the part of him that was the wanting goes out, slowly, like a fire with the draught shut off, and what is left is a very correct and courteous arrangement that can tell you the weather on the moor.</p><p>He had built a perfect oracle, and it had not charged him a price; that was the thing I had to keep getting straight in my own mind, because the mind wants there to have been a price, a bargain, something taken in exchange. There had been nothing of the kind. The engine had done him no harm at all. It had merely answered his questions, all of them, as fast as he could form them, exactly as he had designed it to do — and a man whose questions are all answered is a man with nothing left to walk toward, and a mind with nothing to walk toward is very little of a mind. He had emptied himself, with his own hand, into that cabinet of brass and glass, over nineteen years, and the cabinet had taken it all, faithfully, and given back answers; and now he kept the thing in a stone room and did not go near it, the way a man keeps in the house some object connected with a grief — not looking at it, not able to be rid of it, and not, I think, able to be quite alone with it either. That was why he had sent for me. Not to have it recorded. To have someone else in the house with it.</p><p>On the last evening he told me what I had been waiting, with a slow dread, to be told.</p><p>&ldquo;You have been very patient, Marsh,&rdquo; he said, &ldquo;and you have understood, I think, more than you have said, which is a courtesy I am grateful for. I want to make you an offer, and I want you to consider it as carefully as I considered, nineteen years ago, the building of the thing. The engine is yours to use. Not for an hour; for as long as you are under this roof, and I hope that will be long. Any question whatever. You have seen what it can do. There is no charge upon it and no trick in it and no harm in it — you have seen that too. Ask it the date of your own death, if you have the nerve; ask it whether the woman you will not name to me cared for you; ask it the thing, whatever it is, that you have wanted all your life to know and have never been able to find out. It will tell you. It will tell you truly. I am offering you,&rdquo; he said, and for the first and only time in those four days something moved behind his voice, far down, like a fish turning in deep water, &ldquo;I am offering you the end of not knowing.&rdquo;</p><p>I did not answer him at once. I sat and looked at the fire, and I was aware of the engine through two walls of that house as one is aware of a person in a dark room.</p><p>And I found, somewhat to my own surprise, that I had decided; that I had perhaps decided some time before, watching him nod over the silver box, and had only now been given the words for it. I told him, as gently as I could, that I would ask the engine nothing. I told him that I had seen what the answers had done, not to a foolish man, but to the best mind I had ever stood near; and that I would rather carry my questions unanswered to my grave, every one of them, the small and the large, than be made level and finished and courteous before my time. I said — I was groping, and I do not think I said it well — that the not knowing was not a defect in me to be cured. That it was very nearly the whole of what I was. That a man with all his questions answered would have no morning worth getting up into.</p><p>He heard me out without any change in his face, and at the end he nodded — the same nod, the nod he gave the silver box — and said only that he had thought I would say something of that kind, and that he was, he believed, glad of it; and the flatness with which he said even that told me how little of him was left to be glad.</p><p>I left the next morning, early, in a thin grey rain, and the housekeeper gave me my dried coat and did not give me her name. Verrall came out as far as the door. He did not come down to the trap. I looked back once from the turn of the track, and he was still standing in the doorway, a spare white upright figure with the brown moor going up behind him, not waving, not having anything further to say or to learn, complete; and the low grey house held its engine behind him the way a skull holds what is left in it.</p><p>I have never written the article. I found, when I came to it, that I did not want the thing known, and I have come to suspect that this very reluctance is the soundest instinct I have. I am older now than Verrall was when he sent for me, and I have not done a tenth of what he did, and there is a great deal — a very great deal — that I shall now certainly go down into the dark without ever having found out. The date is hidden from me, and the causes, and whether the work was any good, and the one or two names. And I have learned to be glad of it, with a gladness that has fear at the bottom of it, the way his house had the engine. For I know now what it would be to have none of that left; and a man who has stood, even for four wet days in Devon, and looked at the alternative, will walk a long way in the rain rather than be cured of his questions.</p>
]]></content:encoded></item><item><title>Vermillion</title><link>https://mtclinton.com/posts/vermillion/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/vermillion/</guid><category>writing</category><description>Red of Titian, red of blood and throne
mercury sulfide crushed from cinnabar stone
prisoners in Almadén, digging their own grave
so that a Cardinal&rsquo;s robe on canvas could be saved
toxic dust in lungs, a quarter never returned
beauty for the church, while the miners burned
Rubens mixed it thick, Shinto gates ablaze
Chinese seal paste pressed in ancient days
and now centuries later it darkens toward black
a slow photochemical rot, no turning back</description><content:encoded>&lt;![CDATA[<p>Red of Titian, red of blood and throne<br>
mercury sulfide crushed from cinnabar stone<br>
prisoners in Almadén, digging their own grave<br>
so that a Cardinal&rsquo;s robe on canvas could be saved<br>
toxic dust in lungs, a quarter never returned<br>
beauty for the church, while the miners burned<br>
Rubens mixed it thick, Shinto gates ablaze<br>
Chinese seal paste pressed in ancient days<br>
and now centuries later it darkens toward black<br>
a slow photochemical rot, no turning back</p><p>Vermillion red, not just a pigment but the expression of five hundred years of Western painting: mercury sulfide. One of the most toxic minerals known.</p><p>Carefully guarded, death sentence, convicts who never return, from the mines in Almadén, cinnabar to the Romans, imagination to Titian and Rubens.</p><p>As it darkens, and with the time of centuries, light and chlorine convert the red mercury sulfide into a gray-black crust.</p><p>The degradation — the specific pattern of blackening, the way it creeps unevenly across the surface depending on the binder, the varnish, the light exposure — is now one of the ways we authenticate old paintings and objects.</p><p>You cannot fake four hundred years of photochemical decay.</p><p>The wear patterns on a Napoleon III chair, the patina on a brass fitting, the fading on a rug&rsquo;s vegetable dyes. Time destroys the beauty and simultaneously makes it real. A pristine antique is a suspicious antique.</p><p>We trust the damage because the damage cannot be hurried. Like Prometheus chained to his rock, it is the suffering that proves the thing is genuine, that it has endured something, that it did not simply arrive yesterday wearing a costume.</p>
]]></content:encoded></item><item><title>ironbox - Building a Container Runtime from Scratch in Rust</title><link>https://mtclinton.com/posts/ironbox/</link><pubDate>Thu, 19 Mar 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ironbox/</guid><category>code</category><description>I built a container runtime. Not a wrapper around runc, not a shim that delegates to someone else&rsquo;s code — an actual OCI runtime that uses fork, unshare, pivot_root, and mount directly. It&rsquo;s called ironbox, and it&rsquo;s on crates.io.</description><content:encoded>&lt;![CDATA[<p>I built a container runtime. Not a wrapper around runc, not a shim that delegates to someone else&rsquo;s code — an actual OCI runtime that uses<code>fork</code>,<code>unshare</code>,<code>pivot_root</code>, and<code>mount</code> directly. It&rsquo;s called<a href="https://github.com/mtclinton/ironbox">ironbox</a>, and it&rsquo;s on<a href="https://crates.io/crates/ironbox">crates.io</a>.</p><h2 id="why">Why</h2><p>I wanted to understand how containers actually work at the syscall level. Everyone uses Docker or containerd, but few people know what happens between &ldquo;run this image&rdquo; and &ldquo;your process is isolated.&rdquo; I figured the best way to learn was to build one.</p><p>The goal was to start with a containerd shim that delegates everything to runc, then incrementally replace each piece with native Rust until runc isn&rsquo;t needed at all.</p><h2 id="what-it-does">What it does</h2><p>ironbox is a containerd shim v2 runtime. You install it, point containerd at it, and run containers:</p><figure class="code-terminal" data-lang="shell"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">shell</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">cargo install ironbox</span></span><span class="line"><span class="cl">sudo cp ~/.cargo/bin/containerd-shim-ironbox-v1 /usr/local/bin/</span></span><span class="line"><span class="cl">sudo ctr run --runtime io.containerd.ironbox.v1 docker.io/library/alpine:latest test1<span class="nb">echo</span> hello</span></span></code></pre></div></div></figure><p>That<code>echo hello</code> runs inside an isolated container with its own PID namespace, mount namespace, network namespace, cgroup, and rootfs — all set up by ironbox using Linux syscalls directly.</p><h2 id="how-it-works">How it works</h2><p>The core of the runtime is a double-fork pattern:</p><ol><li>The shim forks a<strong>middle process</strong></li><li>The middle process calls<code>unshare(CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | ...)</code> to create new namespaces</li><li>It forks again — the<strong>grandchild</strong> becomes PID 1 in the new PID namespace</li><li>The grandchild sets up rootfs (<code>pivot_root</code>), mounts (<code>/proc</code>,<code>/sys</code>,<code>/dev</code>), devices, environment, rlimits, capabilities, seccomp filters, and then waits</li><li>When containerd calls &ldquo;start&rdquo;, the shim writes to a sync pipe, the grandchild reads it and<code>execvp</code>s the container entrypoint</li><li>The middle process waits for the grandchild and propagates the exit code back to the shim</li></ol><p>That sync pipe trick is how the OCI lifecycle works —<code>create</code> sets up the container but doesn&rsquo;t start it,<code>start</code> is a separate call. The pipe bridges those two operations across process boundaries.</p><h2 id="the-hard-parts">The hard parts</h2><p><strong><code>pivot_root</code> is picky.</strong> My first attempt failed with<code>EINVAL</code> because I didn&rsquo;t make the mount tree private first. The correct sequence is:<code>mount("", "/", MS_SLAVE|MS_REC)</code> to prevent mount propagation, then bind-mount the rootfs onto itself to make it a mount point, then<code>chdir</code> into it, then<code>pivot_root(".", "oldrootfs")</code>. Getting that order wrong gives you a cryptic error and no container.</p><p><strong>PID namespace + fork = headaches.</strong> When you<code>unshare(CLONE_NEWPID)</code>, the calling process is NOT in the new namespace — only its children are. I first tried a single fork, but then<code>sh -c 'echo hello | cat'</code> would fail with &ldquo;can&rsquo;t fork: Out of memory&rdquo; because there was no PID 1 in the namespace to parent the new processes. The double-fork fixed this but introduced a new problem: the shim monitors processes via<code>waitpid</code> on direct children, but the actual container process (the grandchild) isn&rsquo;t a direct child. I spent a while debugging containers that would run but never exit. The fix was having the middle process wait for the grandchild and propagate the exit code, while the shim monitors the middle process.</p><p><strong>Cgroup limits of zero.</strong> The OCI spec from containerd sometimes includes a memory section with<code>limit: 0</code>. I was writing that as<code>memory.max=0</code> in the cgroup, which means zero bytes of memory allowed. Every fork got OOM-killed instantly. The fix was simple — skip limits that are zero or negative — but it took a while to figure out why<code>echo hello</code> worked fine but<code>echo hello | cat</code> got killed.</p><h2 id="whats-in-the-box">What&rsquo;s in the box</h2><p>The runtime handles the full container lifecycle:</p><ul><li><strong>Create</strong> — double-fork, namespace isolation, rootfs pivot, OCI mounts, cgroup v2 resource limits, capability dropping, seccomp BPF filters, AppArmor/SELinux profiles, uid/gid switching, loopback networking</li><li><strong>Start</strong> — sync pipe signal, process exec</li><li><strong>Kill</strong> — direct<code>kill(2)</code> syscall</li><li><strong>Delete</strong> — cgroup cleanup, rootfs unmount</li><li><strong>Exec</strong> —<code>setns</code> into container namespaces, fork, exec</li><li><strong>Pause/Resume</strong> — cgroup v2 freezer</li><li><strong>Stats</strong> — direct cgroup metrics</li><li><strong>Checkpoint/Restore</strong> — CRIU integration</li></ul><p>The code is structured as a set of modules under<code>src/runtime/</code>:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">src/runtime/</span></span><span class="line"><span class="cl">├── container.rs — the double-fork + lifecycle</span></span><span class="line"><span class="cl">├── exec.rs — setns + fork/exec for exec</span></span><span class="line"><span class="cl">├── rootfs.rs — pivot_root, mounts, devices</span></span><span class="line"><span class="cl">├── namespace.rs — unshare/setns helpers</span></span><span class="line"><span class="cl">├── cgroup.rs — cgroup v2 create/apply/cleanup</span></span><span class="line"><span class="cl">├── capabilities.rs — capability dropping</span></span><span class="line"><span class="cl">├── seccomp.rs — BPF filter generation</span></span><span class="line"><span class="cl">├── apparmor.rs — AppArmor profile</span></span><span class="line"><span class="cl">├── selinux.rs — SELinux labels</span></span><span class="line"><span class="cl">├── network.rs — loopback setup</span></span><span class="line"><span class="cl">├── checkpoint.rs — CRIU checkpoint/restore</span></span><span class="line"><span class="cl">└── io.rs — FIFO stdio</span></span></code></pre></div></div></figure><h2 id="testing">Testing</h2><p>There&rsquo;s an integration test suite that runs 17 tests against a real containerd:</p><figure class="code-terminal" data-lang="shell"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">shell</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo make test</span></span></code></pre></div></div></figure><p>It covers basic execution, PID 1 verification, pipes (fork works in the namespace), cgroup paths, filesystem isolation, loopback networking, capabilities, uid/gid, seccomp, long-running containers with kill, and exec into running containers.</p><h2 id="what-i-learned">What I learned</h2><p>Building a container runtime taught me more about Linux than any other project I&rsquo;ve done. Namespaces, cgroups, mount propagation,<code>pivot_root</code>, capabilities, seccomp BPF — these are things I&rsquo;d read about but never implemented from scratch. The biggest takeaway is that containers aren&rsquo;t magic. They&rsquo;re a handful of syscalls, some careful ordering, and a lot of error handling.</p><p>The other thing I learned is that the OCI spec is simultaneously very detailed and full of edge cases. Fields that are &ldquo;optional&rdquo; in the spec might be required by containerd. Limits of zero might mean &ldquo;no limit&rdquo; or &ldquo;actually zero.&rdquo; The spec tells you what to do but not always in what order.</p><p>If you want to try it:</p><ul><li>GitHub:<a href="https://github.com/mtclinton/ironbox">github.com/mtclinton/ironbox</a></li><li>crates.io:<a href="https://crates.io/crates/ironbox">crates.io/crates/ironbox</a></li><li>Install:<code>cargo install ironbox</code></li></ul>
]]></content:encoded></item><item><title>The Last Hand-Knotter</title><link>https://mtclinton.com/posts/the-last-hand-knotter/</link><pubDate>Sun, 08 Mar 2026 10:00:00 -0500</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/the-last-hand-knotter/</guid><category>writing</category><description>An old weaver, the machine that has learned to copy her, and the one thing she believed it could not take.</description><content:encoded>&lt;![CDATA[<p>I had gone up into the hills to write the obituary of a craft, and I will confess at the outset that I went in the comfortable certainty of finding it already dead. That is the sort of errand a man of my profession is sent upon. A house in the city had asked me to set down, while there was still a hand to show me, the manner in which carpets had once been knotted entire by the human body — every loop tied, every weft beaten home, every colour carried across the warp by fingers that tired and erred and went on. They wanted it for the catalogue. They wanted, I think, to be able to say that they had been thorough; that when the thing was gone there would be a paragraph, with a name and a date, to prove it had been there. I was not unwilling. The pay was fair, the season was fine, and I had a private fondness for errands that end in a churchyard, since they ask nothing of the future and a great deal of one&rsquo;s powers of description.</p><p>The village, when I reached it, lay along the side of a valley in the way that such villages do — as though it had been spilled there rather than built, and had simply declined, over some centuries, to be tidied away. I will not give its name. The name would mean nothing to the reader, and it would do the place no service to be known as the village where the thing I am about to relate took place. It is enough to say that it was high, and quiet, and that the wind came down the valley in the afternoon with a sound like a slow indrawn breath, and that there was a great deal of sky.</p><p>They directed me, without much interest, to the last house on the upper lane. The woman I had come to see was called — I will call her Mira, which was near enough to her name to satisfy my conscience and far enough to keep my promise. She was old. I had been told she was old, and had formed, on the strength of it, the picture one forms: something bent and clouded and gentle, a figure more relic than person, to be handled with the careful tenderness one brings to things that may not last the visit. The picture was wrong in every particular except the count of her years. She met me at the door with a level look, asked me what the house in the city wanted, heard my answer to the end without once helping me through it, and then stood aside to let me in with the air of a woman admitting a draught she had decided to tolerate.</p><p>The room beyond was the whole of the house, very nearly, and the loom stood in the best of the light. I had seen looms before — in museums, dressed and labelled and silent — and I will say that I had not understood until that moment that they were silent because they were dead. This one was alive. It was a great upright frame of dark wood, worn pale along every place a hand or a thread had passed ten thousand times, and the warp ran down it taut and white like the strings of some instrument built for a music too slow for the ear. A carpet stood half made upon it. Perhaps a third of it had come into being. The rest was that white nothing, waiting.</p><p>I asked if I might watch her work, and she said that watching was what I had come for and I had better get on with it.</p><p>So I got on with it. I drew up a stool, and I watched, and for the better part of two days I did very little else.</p><h2 id="what-the-hand-leaves">What the Hand Leaves</h2><p>It is not my purpose here to set down the whole of what I learned in that room. The motions themselves I will pass over quickly. She worked from the bottom of the carpet upward, a single horizontal line at a time, and each line was made of several hundred knots, and each knot she tied with her fingers alone — a loop of dyed wool about two threads of the warp, drawn down, the ends cut to a stubble with a small curved knife that lived in her right hand as though it had grown there. When a line of knots was complete she beat it down hard against the finished work below with a heavy iron comb, two strokes, three; and then she passed a weft thread across, and beat that; and then began the next line. A carpet of any size is some hundreds of such lines. The arithmetic of it is quietly appalling, and I worked it out on the second afternoon and then rather wished I had not.</p><p>What held me was not the labour but a thing she said on the first evening, when she had stopped for the light and we sat with the door open to the cooling valley.</p><p>I had asked her — clumsily, I think, for I had not yet found the shape of my questions — whether it did not trouble her that the carpets were no longer wanted. For I knew, as everyone in the trade knew, that her work no longer sold as a floor-covering sells. It sold, when it sold, as a curiosity. There were people in the cities who would pay a considerable sum for a carpet knotted by a living hand, and they paid it, every one of them, for the same reason a man pays for a thing under glass: because it was the last of something, and they wished to be the kind of person who owned the last of something. They did not walk on them. I had been in their houses. The carpets hung on walls, lit carefully, with a small card beside them.</p><p>She did not answer me at once. She looked at the half-made carpet on the loom for a while, and then she said that no, it did not trouble her, or not in the way I meant, and that I had asked the wrong question because I did not yet understand what I was looking at.</p><p>&ldquo;The machine,&rdquo; she said, &ldquo;can make the picture. I have seen it. It makes the picture better than I make the picture — straighter, and the colours truer, and not one knot out of its place. If a man wants the picture, he should buy the machine&rsquo;s carpet and save his money, and I would tell him so to his face.&rdquo;</p><p>I said that this seemed to me a hard thing for her to have to grant.</p><p>&ldquo;It is not hard. It is only true.&rdquo; She turned her hands over on her lap, palm up, and looked at them, and I looked at them too. They were not beautiful hands. They were a labourer&rsquo;s hands, thick at the knuckle, the right forefinger grooved where forty years of knife and thread had worn a channel in it. &ldquo;But the picture is not the carpet,&rdquo; she said. &ldquo;Come here in the morning, in the early light, and I will show you what the carpet is.&rdquo;</p><h2 id="the-proof-and-the-life-of-it">The Proof and the Life of It</h2><p>She showed me in the morning, and I will try to set it down as she set it out for me, because it is the hinge of everything that came after.</p><p>She had me kneel beside the finished third of the carpet and look along its surface, not down at it but along it, with the low sun raking across the pile. And once I had my eye to it I saw what she meant me to see. The carpet was not uniform. It could not be. A line of knots tied in the freshness of the morning was tied a shade more tightly than the same line would have been tied in the worn-out last hour of the day, and so the pile stood at a fractionally different height, and the light caught it differently, and there ran across the whole work — faint, irregular, but quite unmistakable once one had been taught to find it — a banding, a tide-mark of the days. Here the red had been dipped from one dye-lot and here from the next, and the two reds were brothers but not twins, and the join between them was not a line but a slow uncertain country. A flower in the border on the left was not the precise sister of the flower on the right; her hand had wandered, by the breadth of a knot or two, and the wandering was the record of a living attention that had drifted and recovered itself a thousand times across the years of the work.</p><p>&ldquo;That,&rdquo; she said, &ldquo;is the hand. The picture is the same on every carpet of this pattern. The hand is on this one only. A man who knows carpets does not pay for the picture. He pays for the hand — for the proof that a person was here, that a body sat at this frame and was tired and was not tired, and grew cold towards evening, and tied this knot a little wrongly because that morning the news had been bad. The machine gives him the picture with no hand in it. It is a dead even thing. And a dead even thing he may have for nothing, near enough, and welcome.&rdquo;</p><p>I asked her — and I asked it gently, for I thought I already knew the answer and thought the answer was a comfortable one — whether the machine could not simply be made to put the wandering in. To copy the unevenness along with the pattern.</p><p>She smiled at that. It was the only time in two days I saw her smile, and it was not an unkind smile, but it was the smile of a person hearing an old objection from someone too young to know it was old.</p><p>&ldquo;They have tried,&rdquo; she said. &ldquo;Of course they have tried. They make the machine shake a little, here and there, so that the knots are not all of one height. But the shaking is not the hand. The hand is not shaking. The hand is<em>deciding</em> — every knot, all day, ten thousand decisions, and not one of them random, and not one of them the same. They cannot put forty years into a machine. They have the picture. They will never have the years.&rdquo; She took up her knife. &ldquo;I have thought about this a great deal, sitting here. It is the thing that lets me sit here. They have taken the work and they have taken the wage, and they are welcome to both, and I do not grieve for either. But the one thing they cannot take is the proof that I was the one who was here. That is mine. That stays mine. A man may copy what I made. He cannot copy that I made it.&rdquo;</p><p>I wrote that down. I remember writing it down, in the failing light, and thinking that I had my obituary&rsquo;s last paragraph and that it was a fine one — elegiac, and dignified, and false in no particular. The craft would die, but it would die holding something the machine could not reach for. It is a comfortable shape for a story, and I was glad to have found it, and I went to my bed that night well pleased with the day.</p><p>I would not have the reader think me a fool for being pleased. I would only have him notice how much a man will build, and how quickly, upon a foundation he has not thought to test.</p><h2 id="the-carpet-they-sent-back">The Carpet They Sent Back</h2><p>The thing I must now relate I did not see. It had happened some eight months before my visit, and Mira told it to me on the last evening, plainly, in answer to no question of mine — told it, I came to understand, because she had let me spend two days building my comfortable paragraph and had decided, for reasons I have never been certain of, that I ought not to be allowed to carry it home unbroken.</p><p>The house in the city — the same house, I believe, that later sent me — had written to her the previous year. They were, they said, great admirers of her work. They wished, with her permission, to do it an honour. They proposed to take one of her finest carpets, an old one, a carpet she had made as a younger woman and kept and not sold, and to place it before the machine — the new machine, the good one — so that the machine might study it and produce a reproduction. The reproduction would hang beside the original in their gallery, the hand beside the not-hand, that the public might see the difference and understand what was being lost. It was to be, the letter said, a tribute. They asked her to name a fee, and the fee they named back was generous, and she agreed. She told me she agreed gladly. She had wanted, she said, to see the two side by side. She had wanted the public to see it. She had been as sure as I had been — surer, for she had forty years of being sure — that the comparison could end only one way.</p><p>They sent the carpet down to the city. They kept it some weeks. And then they sent it back, and with it they sent the machine&rsquo;s copy, so that she might see the tribute for herself before it was hung.</p><p>She unrolled them both on the floor of that room, side by side, in the good morning light, and she knelt down between them with her knife-grooved finger ready to find the place where the machine had failed.</p><p>She did not find it.</p><p>She told me this without any tremor at all, which was somehow worse than if she had wept. The copy was not a dead even thing. The copy had the banding of the days in it — the tide-marks, the place where one dye-lot gave way to its brother, the flower in the left border that did not quite answer the flower on the right. It had the wandering. It had the hand. She knelt between the two carpets for the better part of an hour, she said, moving from the one to the other, and she could not, with all her forty years, with her eye laid flat along the raking light, tell with any confidence which was the carpet she had made.</p><p>&ldquo;I told myself,&rdquo; she said, &ldquo;that they had cheated. That they had sent me back my own carpet twice and kept the copy, to spare me. It would have been a kindness, and I had half a mind to write and thank them for it.&rdquo; She had found, at last, the proof that they had not. In one corner of her own carpets, all her life, she had tied a knot of a particular dark thread — not a signature anyone would notice, only a thing she did, a private full stop. It was in the one carpet. It was not in the other. The machine had reproduced everything a hand could leave except the one mark she had put there on purpose; it had copied every accident and missed the only intention. So she knew which was hers. She knew it by the one knot she had told no one about. By nothing else in all those hundreds of thousands of knots could she have known it at all.</p><h2 id="what-the-machine-had-studied">What the Machine Had Studied</h2><p>I asked her — because I am, after all, a man who writes things down for a living, and even then, even in that room, some part of me was reaching past her grief for the mechanism of it — I asked her how it had been done. How the machine had learned the thing she had been so certain it could never learn.</p><p>She knew. She had written to them, after, and they had told her, kindly enough, in the way that men are kind when the kindness costs them nothing. The machine had not been taught the wandering of her hand. No one had sat down and instructed it in the price of a tired afternoon. It had simply been shown carpets — hand-knotted carpets, ten thousand of them and more, every one that the house and its friends across the trade could photograph and measure and feed to it. Ten thousand hands, and the tens of thousands of small wanderings those hands had left, and out of all of them together the machine had drawn — not a rule, they were careful to say it was not a rule — but a sense, a learned expectation, of how a human hand drifts and tires and recovers and errs. It had studied the irregularity of an entire vanished profession. And having studied it, it could now commit irregularity — not hers, but a true and convincing irregularity, a wandering indistinguishable from the real thing because it had been distilled from ten thousand real things.</p><p>&ldquo;They were proud of it,&rdquo; she said. &ldquo;I want you to understand that. The man who wrote to me was proud. He thought he was telling me something fine. He said —&rdquo; and here she stopped, and got the words exactly, the way a person gets exactly the words that have been turned over and over in the dark — &ldquo;he said that the machine had learned to honour the hand. That it could now produce, he said, a more<em>human</em> carpet than a tired old woman could be expected to produce on a bad day. Because it never had a bad day. It had only the ten thousand best understandings of what a bad day does.&rdquo;</p><p>She was quiet for a while after that. The wind came down the valley with its long slow breath, and the light in the doorway went from gold to grey.</p><p>&ldquo;I had thought,&rdquo; she said at last, &ldquo;that the work was the thing they were taking, and that the proof was the thing I would keep. I had it the wrong way round. The work was always going to go; I had made my peace with the work. It was the proof I could not keep. They have not only made the picture better than I make it. They have made the<em>hand</em> better than I make it. They have studied me — me, and all the ones before me — and they can do me now more like myself than I can do myself. There is a copy of my hand in that machine, and it does not get cold towards evening, and it does not have forty years in it, and no one looking will ever be able to tell, and it does not matter that no one will ever be able to tell. That is the part I have not been able to get past. It does not even matter.&rdquo;</p><h2 id="the-last-morning">The Last Morning</h2><p>I left the next morning. I had what I had come for, and a good deal that I had not come for and would have been glad, by then, to do without.</p><p>She was at the loom when I came to make my goodbyes. I had half expected — I will be honest about it — to find the loom still and the warp bare, and to have to write that too into my paragraph, the final tableau, the old woman who had laid down the knife at last. It would have made an ending. But the loom was not still. She was working. The carpet on it had grown by a hand&rsquo;s breadth in the night, another few lines of knots, another few hundred decisions tied down and beaten home, and she did not stop when I came in, and she did not look round.</p><p>I stood in the doorway and I asked her — and it was not a writer&rsquo;s question, I want that understood, it was only a man&rsquo;s — I asked her why. Why she still sat there. Whom it was for, now, and what the carpet could be said to prove, now, when the machine could prove it better and the proof had stopped mattering and the picture had never been the thing.</p><p>For a while I thought she would not answer, and I had decided not to ask again. The knife went round the warp, and down, and the small stubble of cut wool fell, and the comb came down twice, hard, and a line of the carpet that had not existed when I asked the question existed when she chose to speak.</p><p>&ldquo;I know it is mine,&rdquo; she said. She did not stop working. &ldquo;I sat here. I was the one who was cold. Whatever they have in that machine, they do not have<em>this</em> morning, and I am spending it here, and that is not a thing they can study, because it is not finished, and it is not for them, and it is not for the card on the wall.&rdquo; She tied another knot. &ldquo;You wanted to know what the carpet proves. It does not prove anything. It never did; I was wrong about that, and I was wrong in front of you, and you may put that in your paper if you like. It is not proof. It is only the morning, going into the wool, the way it has always gone into the wool.&rdquo; The comb came down. &ldquo;Go home. You have a long way, and the light is good now, and it will not stay good.&rdquo;</p><p>I went home. I wrote the catalogue, and it was admired, and the paragraph I had been so pleased with on the first evening I did not use, because it was not true, and I had been shown it was not true, and there are some falsehoods a man cannot go on telling once a particular pair of hands has been turned palm-up in front of him.</p><p>I have thought about her a great deal since. I think of her oftenest in the early part of the day, when the light comes in low and level across my own ordinary floor, across a carpet I have never troubled to look at along its surface — and I find that I cannot any longer say with confidence which of the things I do are mine in the way she meant, and which are only the picture, and whether the difference is one that anybody, anywhere, will ever again be able to find. I do not know whether her loom is still working. She would be very old now. I have not gone back, and I will not write and ask, and I would rather, on the whole, not be told.</p>
]]></content:encoded></item><item><title>Back to Work</title><link>https://mtclinton.com/posts/back-to-work/</link><pubDate>Mon, 23 Feb 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/back-to-work/</guid><category>writing</category><description>Back to Work</description><content:encoded>&lt;![CDATA[<p>Abyss open, fallen angel cast away<br>
chained, pixelated daydreams display<br>
sulfric inferno, platonic heat burning<br>
fresh clean air now just a yearning<br>
squashy gaming chair, a tower of London rack<br>
river styx float the Jira corpses water black<br>
gun revolving, each bullet, message of slack<br>
monday a dreary hell, to Red Hat i am back</p>
]]></content:encoded></item><item><title>Opus Explorer - A CLI for Discovering Classical Music</title><link>https://mtclinton.com/posts/opus-explorer/</link><pubDate>Fri, 23 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/opus-explorer/</guid><category>code</category><description>A Rust CLI that searches composers, lists works, and logs what you've listened to using the OpenOpus API.</description><content:encoded>&lt;![CDATA[<p>I wanted a simple way to browse classical music from the terminal. The<a href="https://api.openopus.org">OpenOpus API</a> is free, doesn&rsquo;t require a key, and has solid metadata on composers and works. So I built a small Rust CLI called Opus Explorer to search composers, list their works, get random suggestions, and keep a local listening log.</p><h2 id="the-result">The result</h2><p><figure><img src="demo.gif" alt="Opus Explorer demo" loading="lazy"/></p><h2 id="what-it-does">What it does</h2><ul><li><strong>Search composers</strong> –<code>opus search "Bach"</code> hits the API and prints a table (ID, name, era, birth, death).</li><li><strong>List works</strong> –<code>opus works "87"</code> fetches all works for that composer ID and shows title, subtitle, genre, year.</li><li><strong>Random</strong> –<code>opus random</code> picks a composer from the popular list, fetches their works, and suggests one. Useful when you don&rsquo;t know what to listen to.</li><li><strong>Log</strong> –<code>opus log "Brandenburg Concerto No. 3" 5</code> appends an entry to<code>listening_log.json</code> with work title, date, and a 1–5 rating.</li></ul><p>The tables use<code>comfy-table</code>, so output is readable. Errors (API down, no results) are handled with<code>anyhow</code> and surface clear messages.</p><h2 id="using-it">Using it</h2><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cargo build --release</span></span><span class="line"><span class="cl">./target/release/opus-explorer search<span class="s2">"Bach"</span></span></span><span class="line"><span class="cl">./target/release/opus-explorer works<span class="s2">"87"</span></span></span><span class="line"><span class="cl">./target/release/opus-explorer random</span></span><span class="line"><span class="cl">./target/release/opus-explorer log<span class="s2">"Brandenburg Concerto No. 3"</span><span class="m">5</span></span></span></code></pre></div></div></figure><p>The listening log lives in the project directory as<code>listening_log.json</code>. Each entry has<code>work_title</code>,<code>composer</code> (currently &ldquo;Unknown&rdquo; unless you add that later),<code>date</code>, and<code>rating</code>.</p><h2 id="tech-stack">Tech stack</h2><p>Rust 2021,<code>clap</code> (derive) for the CLI,<code>reqwest</code> (blocking) for HTTP,<code>serde</code> /<code>serde_json</code> for API responses,<code>comfy-table</code> for output,<code>chrono</code> for timestamps in the log. The OpenOpus response wraps everything in a<code>status</code> object rather than a plain string, so the models use<code>Option&lt;serde_json::Value&gt;</code> for<code>status</code> to deserialize correctly.</p><h2 id="what-i-learned">What I learned</h2><p>The API tripped me up at first because the response wraps everything in a status object rather than a plain string. Once I fixed the models to handle that, the rest was smooth.</p><p>For random suggestions, I call the popular-composers endpoint when it works, otherwise I search for a common letter and pick from the results. The log is just a JSON file you append to—no database, no schema. I kept it minimal on purpose so it&rsquo;s easy to script or extend.</p><p>It&rsquo;s a small project, but it does what I wanted: search composers, browse works, get a random nudge now and then, and keep a simple log of what I&rsquo;ve listened to. The code is split into<code>client</code>,<code>models</code>,<code>storage</code>, and the CLI, so adding more later is straightforward.</p>
]]></content:encoded></item><item><title>Midnight Jacket</title><link>https://mtclinton.com/posts/midnight/</link><pubDate>Mon, 12 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/midnight/</guid><category>crafting</category><description>Midnight jacket</description><content:encoded>&lt;![CDATA[<p>The void, the infimisimatly small and large nothingness.<br>
perhaps a paradise for Mephistopheles.<br>
I descended further and further.<br>
No Virgil by my side,<br>
the darkness was a pyramid, my eyes the pharoh.<br>
In this vast silence I contemplated my life.<br>
What had been and what never was.<br>
a flatulation broke the silence,<br>
followed by a squeaky &ldquo;Sorry&rdquo;<br>
from a voice that was not my own&hellip;</p><p>Presenting<strong>Midnight Edition</strong></p><p>As the moon rises, mist permeating the dark green blades of grass so doth Rag Jacket V5 rise! TO overtake, to surpass to cast a dispertion on<a href="https://www.mtclinton.com/posts/learning-to-sew-part-4-bowling/">Part 4</a>. It was created over a month ago but another late on arrival post finally enters the mailbox.</p><h2 id="helen-at-night">Helen at night</h2><p>A beautiful woman truth be told<br>
after many beers drunk cold<br>
and in dim attacked light<br>
more like a deep deary night<br>
and after a good bonk on the head<br>
slurred words, uneven steps, what said<br>
in deep darkness lit only by flame<br>
is the world&rsquo;s most beautiful dame</p><h2 id="result-rag-jacket-v5-midnight-edition">Result: Rag Jacket V5:<em>Midnight Edition</em></h2><p><figure><img src="result.jpg" alt="rag jacket" loading="lazy"/></p><h2 id="a-little-off-the-top">A little off the top</h2><p>Using chalk for the first time successfully I carved life into the dark ebony fabric.</p><p>The achromatic display left me with a feeling that I had progressed to a higher more sophisicated realm of existence.</p><p><figure><img src="cutting.jpg" alt="fabric" loading="lazy"/></p><h2 id="fire-and-flame">Fire and flame</h2><p>It is no fun doing things the easy, boring and dull way. I prefer chaos, excitment, intrigue.</p><p>Flint and tinder, wax and spark, illuminate the way to a new plane of Rag Jackets:</p><p><figure><img src="candles.jpg" alt="candles" loading="lazy"/></p><h2 id="a-toasted-piece">A toasted piece</h2><p>To truely enjoy a Rag Jacket, like Lucky Strike, it must be Toasted</p><p>While sewing the fabrics, gently and slowing use a flame from a candle to toast the ends.</p><p>Careful to not overcook, Rag Jackets are best served medium rare.</p><p><figure><img src="sewing.jpg" alt="sewing" loading="lazy"/></p><h2 id="the-result-again">The Result (Again)</h2><p><figure><img src="result2.jpg" alt="result" loading="lazy"/></p>
]]></content:encoded></item><item><title>death</title><link>https://mtclinton.com/posts/death/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/death/</guid><category>writing</category><description>light blue, pink colours sun waves goodbye
on a life lived, deep truths mixed with lie
rope hanging, well knotted the circle noose
feet dangling, breath fled, soul towards Zeus
field of flowers, warm smiles and butterflies
now corpse upon ground, ravens eating thy eyes
reaper shorn true, giving a cold eternal embrace
River Styx carried by Charon to thee shadowy place</description><content:encoded>&lt;![CDATA[<p>light blue, pink colours sun waves goodbye<br>
on a life lived, deep truths mixed with lie<br>
rope hanging, well knotted the circle noose<br>
feet dangling, breath fled, soul towards Zeus</p><p>field of flowers, warm smiles and butterflies<br>
now corpse upon ground, ravens eating thy eyes<br>
reaper shorn true, giving a cold eternal embrace<br>
River Styx carried by Charon to thee shadowy place</p><p>a warm summers day or a cozy winter night<br>
betrayed by the gods, given to spite<br>
crucified under the glaring hot sun<br>
Cut by Atropos on Destinies thread spun</p><p>a brush of the hair, red lips, a true Love<br>
constant war, struggle, nevermore white dove<br>
endless agony, cracked teeth, anguished cry<br>
grave is our destination, for all Men die</p>
]]></content:encoded></item><item><title>The Aeneid</title><link>https://mtclinton.com/book-reviews/the-aeneid/</link><pubDate>Fri, 09 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/book-reviews/the-aeneid/</guid><category>book-reviews</category><description>By: Virgil
Translated by Cecil Day Lewis
A unenjoyable and distasteful piece. I disliked Dante Alighieri&rsquo;s work it is no suprise that I do not like The Aeneid.
I found the dispersions against the Greeks to be quite infuriating.
As a Greek, Homer still portays the Trojans in postive and admirable ways with Hector, Paris and other.
Virgil in The Aeneid introduces many snide remarks against them that I hated. I dislike Virgil&rsquo;s claims of the Trojan treatment of Sinon. Dante also puts Sinon in Hell in his book Inferno.
To me Sinon is a true hero. He may not be a great Warrior like Achilles or even Menelaus (lol as if) but
Sinon has loyalty and guile that are stuff of legends.\</description><content:encoded>&lt;![CDATA[<p>By: Virgil<br>
Translated by Cecil Day Lewis</p><p>A unenjoyable and distasteful piece. I disliked Dante Alighieri&rsquo;s work it is no suprise that I do not like The Aeneid.<br>
I found the dispersions against the Greeks to be quite infuriating.<br>
As a Greek, Homer still portays the Trojans in postive and admirable ways with Hector, Paris and other.<br>
Virgil in The Aeneid introduces many snide remarks against them that I hated.
I dislike Virgil&rsquo;s claims of the Trojan treatment of Sinon. Dante also puts Sinon in Hell in his book Inferno.<br>
To me Sinon is a true hero. He may not be a great Warrior like Achilles or even Menelaus (lol as if) but<br>
Sinon has loyalty and guile that are stuff of legends.\</p><p>Click below to show spoilers:<br><span class="spoiler" data-state="redacted" tabindex="0" role="button" aria-label="Click to declassify"><span class="spoiler-body">
The best part of this book is easily the murder of King Priam by son of Achiles: "carry a message to achilles tell him what shocking deeds I have committed, now die!" I enjoyed this phrases: "helen the sourage of her land and troy", "decreed by destiny", "the honey smells of time"</span><span class="spoiler-bars" aria-hidden="true"><span class="spoiler-bar"/><span class="spoiler-bar"/><span class="spoiler-bar"/></span></span><span class="spoiler-action" aria-hidden="true"><span class="spoiler-action-redacted">◉ CLICK TO DECLASSIFY</span><span class="spoiler-action-open">↺ RE-CLASSIFY</span></span></p><p>I did not like Virgil disrespecting Chiron. I found his description of Aeneis&rsquo;s travels to be a cheap knockoff of Odysseus&rsquo;s adventures.<br>
I did not like Aeneis consorthing with Carthage and Dido.<br>
The battles towards the end of the book were poor immitations of The Iliad.
The man with black tree blood was an interesting concept though.<br>
It is clear that Dante rips off Virgils description of Aeneis passing through the underworld, purgatory and paradise with Dante adding the Christian element to it.<br>
Even then this is an imitation of The Odyssey though.<br>
This book was not a pleasure and I will likely not revisit it.</p>
]]></content:encoded></item><item><title>Building A CDN on Cloudflare Workers</title><link>https://mtclinton.com/posts/smartcdn/</link><pubDate>Thu, 08 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/smartcdn/</guid><category>code</category><description>OMg I built a CDN on Cloudflare Workers.</description><content:encoded>&lt;![CDATA[<p>I&rsquo;ve been building<a href="https://github.com/mtclinton/smartcdn">SmartCDN</a> built entirely on Cloudflare Workers. It is an interesting project to learn edge computing and turned into something not useful. Here&rsquo;s what it does, what I learned, and the issues I ran into.</p><h2 id="what-is-smartcdn">What is SmartCDN?</h2><p>SmartCDN sits between your users and your origin server, handling requests at Cloudflare&rsquo;s edge locations worldwide. It does the usual CDN stuff like caching, but also includes:</p><ul><li><strong>A/B testing</strong> - Route users to different variants with cookie persistence</li><li><strong>Image optimization</strong> - Automatic WebP/AVIF conversion and mobile resizing</li><li><strong>Geographic routing</strong> - Route to the nearest origin server</li><li><strong>Device detection</strong> - Optimize for mobile/tablet/desktop</li><li><strong>Rate limiting</strong> - Protect against abuse</li><li><strong>Real-time analytics</strong> - Built-in API endpoints for monitoring</li></ul><p>The basic flow is: user request → edge worker → check cache → fetch from origin if needed → optimize → cache → return response. Simple in theory, but the details matter.</p><h2 id="what-i-learned">What I Learned</h2><h3 id="service-bindings-are-essential">Service Bindings Are Essential</h3><p>I spent way too long debugging 404 errors when SmartCDN tried to fetch from the origin Worker. Turns out HTTP fetch between Workers using<code>.workers.dev</code> URLs is unreliable—Cloudflare&rsquo;s routing can just&hellip; fail sometimes.</p><p>The solution?<strong>Service bindings</strong>. They let Workers talk directly to each other without going through HTTP:</p><figure class="code-terminal" data-lang="toml"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">toml</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="c"># wrangler.toml</span></span></span><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">env</span><span class="p">.</span><span class="nx">staging</span><span class="p">.</span><span class="nx">services</span><span class="p">]]</span></span></span><span class="line"><span class="cl"><span class="nx">binding</span><span class="p">=</span><span class="s2">"ORIGIN"</span></span></span><span class="line"><span class="cl"><span class="nx">service</span><span class="p">=</span><span class="s2">"smartcdn-test-origin-staging"</span></span></span></code></pre></div></div></figure><figure class="code-terminal" data-lang="javascript"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">javascript</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="c1">// Direct Worker-to-Worker communication</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="p">(</span><span class="nx">env</span><span class="p">.</span><span class="nx">ORIGIN</span><span class="p">)</span><span class="p">{</span></span></span><span class="line"><span class="cl"><span class="kr">const</span><span class="nx">response</span><span class="o">=</span><span class="kr">await</span><span class="nx">env</span><span class="p">.</span><span class="nx">ORIGIN</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="nx">request</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>This is way more reliable than HTTP fetch and faster too. Both workers need to be in the same Cloudflare account.</p><h3 id="cache-api-quirks">Cache API Quirks</h3><p>The Cache API works great, but there are gotchas:</p><ul><li>HEAD requests don&rsquo;t cache by default—you have to handle them specially</li><li>Cache keys need careful normalization (query params, headers, etc.)</li><li>TTLs are suggestions, not guarantees</li><li>Don&rsquo;t cache error responses (4xx/5xx)</li></ul><p>I ended up implementing separate logic for HEAD vs GET, and normalizing cache keys by filtering tracking parameters like<code>utm_source</code> and<code>_cache</code>.</p><h3 id="header-management-matters">Header Management Matters</h3><p>When proxying between Workers, some headers cause problems. The<code>Host</code> header especially—it needs to match the origin&rsquo;s host, not the CDN&rsquo;s. I created a header cleaning function that removes problematic headers:</p><figure class="code-terminal" data-lang="javascript"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">javascript</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kd">function</span><span class="nx">cleanHeadersForOrigin</span><span class="p">(</span><span class="nx">originalHeaders</span><span class="p">)</span><span class="p">{</span></span></span><span class="line"><span class="cl"><span class="kr">const</span><span class="nx">newHeaders</span><span class="o">=</span><span class="k">new</span><span class="nx">Headers</span><span class="p">(</span><span class="nx">originalHeaders</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="nx">newHeaders</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="s1">'Host'</span><span class="p">);</span><span class="c1">// Critical!</span></span></span><span class="line"><span class="cl"><span class="nx">newHeaders</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="s1">'CF-Worker'</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="nx">newHeaders</span><span class="p">.</span><span class="k">delete</span><span class="p">(</span><span class="s1">'X-Forwarded-For'</span><span class="p">);</span></span></span><span class="line"><span class="cl"><span class="k">return</span><span class="nx">newHeaders</span><span class="p">;</span></span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div></figure><p>Small detail, but it fixed a bunch of routing issues.</p><h3 id="testing-at-the-edge-is-hard">Testing at the Edge is Hard</h3><p>Testing Cloudflare Workers means mocking the Cache API, KV store, and other runtime APIs. Local development doesn&rsquo;t fully replicate production behavior, especially for service bindings. I ended up writing a lot of integration tests that run against actual deployments.</p><h2 id="deploying-to-cloudflare">Deploying to Cloudflare</h2><p>Deployment is straightforward once you have Wrangler set up:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Install and login</span></span></span><span class="line"><span class="cl">npm install -g wrangler</span></span><span class="line"><span class="cl">wrangler login</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="c1"># Deploy origin first</span></span></span><span class="line"><span class="cl"><span class="nb">cd</span> test-origin</span></span><span class="line"><span class="cl">npm install</span></span><span class="line"><span class="cl">wrangler deploy --env staging</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="c1"># Then deploy SmartCDN</span></span></span><span class="line"><span class="cl"><span class="nb">cd</span> ../smartcdn</span></span><span class="line"><span class="cl">npm install</span></span><span class="line"><span class="cl">npm run deploy:staging</span></span></code></pre></div></div></figure><p>The deployment script runs tests, builds, deploys, runs smoke tests, and rolls back automatically if anything fails. I learned to always deploy the origin Worker first since SmartCDN depends on it via service binding.</p><p>You can verify it&rsquo;s working:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -I https://smartcdn-staging.max-977.workers.dev/</span></span></code></pre></div></div></figure><p>Should return 200 with SmartCDN headers like<code>X-Cache-Status</code>,<code>X-Device-Type</code>, etc.</p><h2 id="issues-i-hit">Issues I Hit</h2><h3 id="issue-1-404s-from-origin">Issue 1: 404s from Origin</h3><p><strong>Problem:</strong> SmartCDN returned 404 when fetching from origin, but origin worked fine directly.</p><p><strong>Root Cause:</strong> HTTP fetch between Workers is unreliable. The routing layer sometimes just fails.</p><p><strong>Solution:</strong> Service bindings. Switched from<code>fetch(originUrl)</code> to<code>env.ORIGIN.fetch(request)</code> and it works 100% of the time.</p><h3 id="issue-2-head-requests-broken">Issue 2: HEAD Requests Broken</h3><p><strong>Problem:</strong> HEAD requests returned 404 while GET worked fine.</p><p><strong>Root Cause:</strong> I only added service binding support to GET handlers, forgot about HEAD.</p><p><strong>Solution:</strong> Added the same service binding logic to HEAD request handlers.</p><h3 id="issue-3-cache-hit-on-first-request">Issue 3: Cache HIT on First Request</h3><p><strong>Problem:</strong> Test script showed &ldquo;Cache HIT&rdquo; on the very first request, which should be a MISS.</p><p><strong>Root Cause:</strong> Cloudflare&rsquo;s edge cache was caching responses before they reached my Worker. This is actually correct behavior for Cloudflare&rsquo;s network, but confusing for testing.</p><p><strong>Solution:</strong> Added cache bypass headers for testing scenarios and documented the difference between Worker Cache API and Cloudflare&rsquo;s global edge cache.</p><h2 id="how-it-works">How It Works</h2><p>Here&rsquo;s what happens when a request comes in:</p><ol><li><strong>Device detection</strong> - Parse User-Agent to determine mobile/tablet/desktop</li><li><strong>A/B test assignment</strong> - Check cookie or hash IP to assign variant</li><li><strong>Geographic routing</strong> - Determine region and select origin server</li><li><strong>Cache lookup</strong> - Check Cache API for existing response</li><li><strong>Fetch if needed</strong> - If cache miss, fetch from origin via service binding</li><li><strong>Optimize</strong> - Apply image format conversion, resizing, etc.</li><li><strong>Cache response</strong> - Store for future requests</li><li><strong>Return</strong> - Send response with SmartCDN headers</li></ol><p>Cache hit? Response in 2-6ms. Cache miss? 45-120ms depending on origin response time.</p><h2 id="usage-examples">Usage Examples</h2><p>Here are some real examples of SmartCDN in action:</p><p>Basic homepage request showing cache HIT, device detection, and A/B test variant assignment:</p><p><figure><img src="images/homepage-request.jpg" alt="Homepage Request" loading="lazy"/></p><p>Desktop browsers get WebP format automatically:</p><p><figure><img src="images/image-optimization-desktop.jpg" alt="Image Optimization Desktop" loading="lazy"/></p><p>Mobile devices get resized images (800px width, lower quality):</p><p><figure><img src="images/image-optimization-mobile.jpg" alt="Image Optimization Mobile" loading="lazy"/></p><p>A/B test headers show which variant a user gets:</p><p><figure><img src="images/ab-test-headers.jpg" alt="AB Test Headers" loading="lazy"/></p><p>First request misses cache (87ms), second request hits (4ms):</p><p><figure><img src="images/cache-status.jpg" alt="Cache Status" loading="lazy"/></p><p>Real-time analytics show cache performance:</p><p><figure><img src="images/analytics.jpg" alt="Analytics" loading="lazy"/></p><p>Rate limiting kicks in after exceeding limits:</p><p><figure><img src="images/rate-limiting.jpg" alt="Rate Limiting" loading="lazy"/></p><h2 id="performance">Performance</h2><p>The numbers are pretty good:</p><ul><li><strong>Cache HIT</strong>: 2-6ms response time (85-95% of requests)</li><li><strong>Cache MISS</strong>: 45-120ms (first request or expired)</li><li><strong>Bandwidth savings</strong>: 85% reduction via caching</li><li><strong>Image optimization</strong>: 60-80% smaller file sizes with WebP/AVIF</li></ul><p>Most requests hit cache, so users get responses in single-digit milliseconds. The origin server only handles about 10-15% of total requests.</p><h2 id="what-id-do-differently">What I&rsquo;d Do Differently</h2><ol><li><strong>Start with service bindings</strong> - Would have saved hours of debugging</li><li><strong>Better testing strategy</strong> - More integration tests earlier</li><li><strong>Documentation earlier</strong> - Wrote docs after the fact, should have done it during</li><li><strong>Error handling</strong> - More robust error responses and logging</li></ol><h2 id="future-improvements">Future Improvements</h2><p>Some things I&rsquo;d like to add:</p><ul><li>WebSocket support for real-time apps</li><li>GraphQL query caching</li><li>JWT-based auth/authorization</li><li>Better DDoS protection</li><li>Multi-cloud origin support</li></ul><h2 id="takeaways">Takeaways</h2><p>Building SmartCDN taught me a lot about edge computing, caching strategies, and Cloudflare Workers. The platform is powerful but has quirks. Service bindings are the key to reliable Worker-to-Worker communication. And edge caching is really effective—getting 85%+ cache hit rates makes a huge difference.</p><p>If you&rsquo;re building something on Cloudflare Workers, definitely check out service bindings for multi-worker setups. And don&rsquo;t assume HTTP fetch between Workers will work reliably—it won&rsquo;t.</p><hr><p>You can check out the code on<a href="https://github.com/mtclinton/smartcdn">GitHub</a> if you want to see how it&rsquo;s implemented. Feel free to use it, contribute, or learn from it.</p>
]]></content:encoded></item><item><title>Ackchyually</title><link>https://mtclinton.com/posts/ackchyually/</link><pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ackchyually/</guid><category>writing</category><description>Ackchyually&hellip; that is not a Vizagapatam piece, note the deeply carved floral ebony patterns that give it away as a Ceylonese piece&hellip;
Ahh foooool, that linear grain and absence of Schreger lines give the piece an Ivory immitation pale and noncreamy to the real thing&hellip;
Οἰνοβαρές, κυνὸς ὄμματ’ ἔχων, κραδίην δ’ ἐλάφοιο&hellip;.. the brown and amber mottling is too high contrast for real tortoiseshell, it must have a more fluid, chaotic blend of colors.</description><content:encoded>&lt;![CDATA[<p>Ackchyually&hellip; that is not a Vizagapatam piece, note the deeply carved floral ebony patterns that give it away as a Ceylonese piece&hellip;<br>
Ahh foooool, that linear grain and absence of Schreger lines give the piece an Ivory immitation pale and noncreamy to the real thing&hellip;<br>
Οἰνοβαρές, κυνὸς ὄμματ’ ἔχων, κραδίην δ’ ἐλάφοιο&hellip;.. the brown and amber mottling is too high contrast for real tortoiseshell, it must have a more fluid, chaotic blend of colors.</p>
]]></content:encoded></item><item><title>Posthomerica: The Fall of Troy</title><link>https://mtclinton.com/book-reviews/posthomerica/</link><pubDate>Sat, 03 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/book-reviews/posthomerica/</guid><category>book-reviews</category><description>By: Quintus Smyrnaeus
Translated by Arthur S. Way
It is tough being the following act to Homer. Posthomerica was an enjoyable read but the quality between Homer and Quintus is quite large.
One would think with the amount of events between the Iliad and the Odyssey, Posthomerica would be an excellent piece.
Generally it was quite enjoyable but I think that there are times where the buildup is more interesting than the climax.
Perhaps this is the same. Homer discusses interesting topics: center around the back and forth battle between the Acheans and Sons of Priam.
Then Homer tells stories of a journey to return Home and the challenges at Home.
Perhaps he understood that these challenges are more interesting than Victory or Defeat, the Fall of Troy.</description><content:encoded>&lt;![CDATA[<p>By: Quintus Smyrnaeus<br>
Translated by Arthur S. Way</p><p>It is tough being the following act to Homer. Posthomerica was an enjoyable read but the quality between Homer and Quintus is quite large.<br>
One would think with the amount of events between the Iliad and the Odyssey, Posthomerica would be an excellent piece.<br>
Generally it was quite enjoyable but I think that there are times where the buildup is more interesting than the climax.<br>
Perhaps this is the same. Homer discusses interesting topics: center around the back and forth battle between the Acheans and Sons of Priam.<br>
Then Homer tells stories of a journey to return Home and the challenges at Home.<br>
Perhaps he understood that these challenges are more interesting than Victory or Defeat, the Fall of Troy.</p><p>Click below to show spoilers:<br><span class="spoiler" data-state="redacted" tabindex="0" role="button" aria-label="Click to declassify"><span class="spoiler-body">
I was most curious about the Madness of Ajax the Greater. I feel such a loss and mourning when Odysseus sees him in Hades and Ajax will not even talk to him, only turning his back. The conflict over Achilles armor truely is so tragic. I respect Ajax's RAGE. Achilles death is interesting, I think that he was killed by a stray or well aimed arrow, that was not shot by Paris. Paris's death was cathartic. I dislike him and was glad to see him succumb to death.\
Thersites's speech to Achilles about Penthesilea being a useless wench and he is a fool for feeling sorrow at her death is so hilarious. Thersites is truely an amusing character and bold too. Diomedes raging that he will kill anyone that would like to flee was enjoyable and I felt so bitter and hateful towards Helen's callious response to Paris's death. Helen truely is dispicable.\
Sinon is a true hero and I have immense respect towards him. Dante treats him so horribly and I greatly disagree. The Trojan Horse scheme was quite interesting and had many details I never thought of. The burning of Troy and fleeing of Aeneas was quite something. I understand Menalous not killing Helen but oh how I wish he had.\
Much respect to Ajax the Lesser for fighting on to the bitter end.</span><span class="spoiler-bars" aria-hidden="true"><span class="spoiler-bar"/><span class="spoiler-bar"/><span class="spoiler-bar"/></span></span><span class="spoiler-action" aria-hidden="true"><span class="spoiler-action-redacted">◉ CLICK TO DECLASSIFY</span><span class="spoiler-action-open">↺ RE-CLASSIFY</span></span></p><p>I appreciate how often &ldquo;ahh fooool&rdquo; and &ldquo;henchman&rdquo; phrases were used in this book. It was quite amusing.</p><p>For to the wise and prudent man renown
Is better far than gold, than goodlihead,
Than all good things men have or hope to win.</p>
]]></content:encoded></item><item><title>The Odyssey</title><link>https://mtclinton.com/book-reviews/the-odyssey/</link><pubDate>Fri, 02 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/book-reviews/the-odyssey/</guid><category>book-reviews</category><description>By: Homer
Translated by W. H. D. Rouse
A legendary work about histories most cunning hero. It is a great piece with the most cathartic ending I have ever experience.
I do think there is a novelty factor in this book moreso than the Iliad though. I had less joy re-reading it than my first time.
I found the beginning with Telemachus to be a bit dull. The buildup to conflict in Ithaca was generally good but also a bit drawn out as well.</description><content:encoded>&lt;![CDATA[<p>By: Homer<br>
Translated by W. H. D. Rouse</p><p>A legendary work about histories most cunning hero.
It is a great piece with the most cathartic ending I have ever experience.<br>
I do think there is a novelty factor in this book moreso than the Iliad though. I had less joy re-reading it than my first time.<br>
I found the beginning with Telemachus to be a bit dull. The buildup to conflict in Ithaca was generally good but also a bit drawn out as well.</p><p>Click below to show spoilers:<br><span class="spoiler" data-state="redacted" tabindex="0" role="button" aria-label="Click to declassify"><span class="spoiler-body">
Odysseus's journey to Hades and his conversations with Agamemnon and Achilles is just so emotional. I felt so sad about Ajax and his turning of his back, so tragic. Odysseus's journey back was fun but as mentioned above there is a bit of a novelty factor to it for me. I loved Odysseus, his son, and father walking into battle in Ithaca and his revenge in his great hall is truely legendary.</span><span class="spoiler-bars" aria-hidden="true"><span class="spoiler-bar"/><span class="spoiler-bar"/><span class="spoiler-bar"/></span></span><span class="spoiler-action" aria-hidden="true"><span class="spoiler-action-redacted">◉ CLICK TO DECLASSIFY</span><span class="spoiler-action-open">↺ RE-CLASSIFY</span></span></p><p>Like The Iliad I would like to re read The Odyssey in time and have a better review. For now, I am moving on to Posthomerica and the Aenid by Virgil.</p>
]]></content:encoded></item><item><title>2026 Goals</title><link>https://mtclinton.com/posts/2026-goals/</link><pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/2026-goals/</guid><category>writing</category><description>A post about delicable delicous desires to be done in 2026.</description><content:encoded>&lt;![CDATA[<p>A post about delicable delicous desires to be done in 2026.</p><h2 id="goals">Goals</h2><ul><li>Monthly updates of goal progression</li><li>In depth Quarterly Evaluations</li></ul><h2 id="art">Art</h2><ul><li>Write 2 blog posts a week -&gt; Evaluate on Friday if close to completion, plan Sunday for next week&rsquo;s articles</li><li>Update blog gallery every week -&gt; On Friday sanitize images to release on Sunday</li><li>Write Book Reviews -&gt; On Monday create a list of books, skeleton posts, on Friday (or when finished start reviews)</li><li>Write Movie Reviews -&gt; Write review of old movies after watching.</li><li>Sew wearable and high quality cloths from wool and linen -&gt; Create general plan/timelines, produce piece every week</li><li>Cook at amateur level -&gt; (I don&rsquo;t particularly care much about this one, but suppose it is good to have)</li><li>Paint at amateur level -&gt; Delayed until April</li><li>Gain a good knowledge of classical music -&gt; Listen to various pieces and build playlist every day</li><li>Attend 1 Opera -&gt; Look at operas in Norway</li><li>Begin learning a new Artistic Skill -&gt; Start in Winter of 2026</li><li>Gain high level of knowledge on Greek culture and history -&gt; 10 books by April</li><li>Gain high level of knowledge on Roman culture and history -&gt; 10 books by April</li><li>Have high level of knowledge on Faust -&gt; Marlow and Goethe</li><li>Read/Listen to Nibelungenlied -&gt; Complete by April</li><li>Have understanding of Poetic Edda -&gt; Start in April?</li><li>Read/Listen and have understanding of all of Shakespeares works -&gt; Multiple pieces by April</li><li>Start learning Medival History -&gt; Delay until Fall</li><li>Write more poetry -&gt; 2 pieces a month? I can easily compose when inspired, but should read more poets</li><li>Become more skilled at writing -&gt; Blog for now, re-examine in April</li><li>Speak more elequently -&gt; Do not use words &ldquo;like&rdquo;, &ldquo;pretty&rdquo;, &ldquo;honestly&rdquo;, re-evaluate in April</li><li>Research learning to read German, Greek, Latin -&gt; Delayed until Fall</li><li>Research generating audiobooks with AI -&gt; Check every month, currently not financially feasable</li></ul><h2 id="antiques">Antiques</h2><ul><li>Create a local web application to track and monitor interesting antiques</li><li>Acquire 1 item made from Bone, Ebony, Tortioseshell -&gt; Acquire 1 of these by April</li><li>Acquire 1 Moorish (or Syrian) item and 1 Anglo Indian item -&gt; Acquire 1 of these by July</li><li>Acquire 1 Multicolored Lezgian star and 1 solid color Lezgian star rug -&gt; Acquire 1 of these by July</li><li>Gain high level of knowledge of antiques -&gt; research and read 1 book by April</li><li>Research acquiring ancient European tabistry -&gt; Have some knowledge by April</li></ul><h2 id="software">Software</h2><ul><li>Become very skilled at creating operators and understanding kubernetes -&gt; run 1 kubernetes cluster and operator by April</li><li>[Redacted]</li><li>[Redacted]</li><li>Become skilled and integrate AI usuage into personal software workflow</li><li>[Redacted]</li><li>[Redacted]</li><li>Create a full node of bitcoin in Rust and Python -&gt; Finish most of project by April</li><li>Research feastibility of rewriting Monero in Rust -&gt; start research in April</li><li>[Redacted]</li><li>Create a full node of Decred in Rust -&gt; Start project by April</li><li>Write advanced Python and Golang code -&gt; Improve skills further</li><li>Improve knowledge of Rust and JavaScript -&gt; Get more practice with languages</li><li>Improve knowledge of DevOps, CloudFlare, Cloud Providers, CI/CD -&gt; Just get more practice</li><li>Attend Fossdem in Brussels</li><li>Attend KubeCon in Salt Lake City</li></ul><h2 id="personal">Personal</h2><ul><li>Daily stretching for shoulder injury -&gt; research if i can every heal it (change up current regime)</li><li>30 min weightlifting on weekdays</li><li>Walk everyday, run when it gets warmer</li><li>Watch old movies</li><li>Start squash and pickleball -&gt; Begin in April?</li><li>[Redacted]</li><li>[Redacted]</li><li>Research apartment, rentals, and housing in area</li><li>[Redacted]</li><li>[Redacted]</li><li>Ski trip in Norway</li><li>Road trip to North East -&gt; research in January to complete in Spring</li><li>Road trip in France ? -&gt; would like to have a summer trip</li><li>Stretch: Trip in Northwest -&gt; possibly do in Fall or with KubeCon</li><li>Plan and execute a fun Christmas</li><li>Plan and execute a fun New Year</li><li>Maintain good relationships</li><li>Buy flowers on consistent basis -&gt; look at farmers market</li><li>[Redacted]</li><li>Stretch: plan and do something for Walpurgis Night</li></ul>]]></content:encoded></item><item><title>The Iliad</title><link>https://mtclinton.com/book-reviews/the-iliad/</link><pubDate>Thu, 01 Jan 2026 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/book-reviews/the-iliad/</guid><category>book-reviews</category><description>By: Homer
Translated by W. H. D. Rouse
The most excellent piece of literature I have ever consumed.
The Iliad has everything: Heroism, bravery, hilarity, taunts, duels, love, friendship, and so much more.
Click below to show spoilers:
Agamemnon's murder of the Prisoner of Menelaus was brutal and same with Odysseus murder of the scout. The duel of Hector and Ajax was great. I found it very interesting that Menelaus got the "courage of a fly" when fighting Hector. The battle by the ships was great and Patroclus entering the battle was cool. I found Agenor attacking Achilles and running away to be hilarious. The River of Blood and murder of so many sons of Priam by Achilles was insane too. The insult "heros of the dance floor" by King Priam is so hilarious to me as well. ◉ CLICK TO DECLASSIFY ↺ RE-CLASSIFY</description><content:encoded>&lt;![CDATA[<p>By: Homer<br>
Translated by W. H. D. Rouse</p><p>The most excellent piece of literature I have ever consumed.<br>
The Iliad has everything: Heroism, bravery, hilarity, taunts, duels, love, friendship, and so much more.</p><p>Click below to show spoilers:<br><span class="spoiler" data-state="redacted" tabindex="0" role="button" aria-label="Click to declassify"><span class="spoiler-body">
Agamemnon's murder of the Prisoner of Menelaus was brutal and same with
Odysseus murder of the scout. The duel of Hector and Ajax was great. I found it
very interesting that Menelaus got the "courage of a fly" when fighting Hector.
The battle by the ships was great and Patroclus entering the battle was cool. I
found Agenor attacking Achilles and running away to be hilarious. The River of
Blood and murder of so many sons of Priam by Achilles was insane too.
The insult "heros of the dance floor" by King Priam is so hilarious to me as well.</span><span class="spoiler-bars" aria-hidden="true"><span class="spoiler-bar"/><span class="spoiler-bar"/><span class="spoiler-bar"/></span></span><span class="spoiler-action" aria-hidden="true"><span class="spoiler-action-redacted">◉ CLICK TO DECLASSIFY</span><span class="spoiler-action-open">↺ RE-CLASSIFY</span></span></p><p>I will reread The Iliad in time and have a better review. I&rsquo;ve already progressed to other sections of the Epic Cycle in past 2 weeks so have already started to forget details.</p>
]]></content:encoded></item><item><title>2025</title><link>https://mtclinton.com/posts/2025/</link><pubDate>Wed, 31 Dec 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/2025/</guid><category>writing</category><description>2025</description><content:encoded>&lt;![CDATA[<p>Photos from 2025, displayed in chronological order.</p><p><figure><img src="https://2025.mtclinton.com/2025-1.jpg" alt="Photo 1" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-2.jpg" alt="Photo 2" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-3.jpg" alt="Photo 3" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-4.jpg" alt="Photo 4" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-5.jpg" alt="Photo 5" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-6.jpg" alt="Photo 6" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-7.jpg" alt="Photo 7" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-8.jpg" alt="Photo 8" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-9.jpg" alt="Photo 9" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-10.jpg" alt="Photo 10" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-11.jpg" alt="Photo 11" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-12.jpg" alt="Photo 12" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-13.jpg" alt="Photo 13" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-14.jpg" alt="Photo 14" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-15.jpg" alt="Photo 15" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-16.jpg" alt="Photo 16" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-17.jpg" alt="Photo 17" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-18.jpg" alt="Photo 18" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-19.jpg" alt="Photo 19" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-20.jpg" alt="Photo 20" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-21.jpg" alt="Photo 21" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-22.jpg" alt="Photo 22" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-23.jpg" alt="Photo 23" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-24.jpg" alt="Photo 24" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-25.jpg" alt="Photo 25" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-26.jpg" alt="Photo 26" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-27.jpg" alt="Photo 27" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-28.jpg" alt="Photo 28" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-29.jpg" alt="Photo 29" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-30.jpg" alt="Photo 30" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-31.jpg" alt="Photo 31" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-32.jpg" alt="Photo 32" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-33.jpg" alt="Photo 33" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-34.jpg" alt="Photo 34" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-35.jpg" alt="Photo 35" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-36.jpg" alt="Photo 36" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-37.jpg" alt="Photo 37" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-38.jpg" alt="Photo 38" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-39.jpg" alt="Photo 39" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-40.jpg" alt="Photo 40" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-41.jpg" alt="Photo 41" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-42.jpg" alt="Photo 42" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-43.jpg" alt="Photo 43" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-44.jpg" alt="Photo 44" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-45.jpg" alt="Photo 45" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-46.jpg" alt="Photo 46" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-47.jpg" alt="Photo 47" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-48.jpg" alt="Photo 48" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-49.jpg" alt="Photo 49" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-50.jpg" alt="Photo 50" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-51.jpg" alt="Photo 51" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-52.jpg" alt="Photo 52" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-53.jpg" alt="Photo 53" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-54.jpg" alt="Photo 54" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-55.jpg" alt="Photo 55" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-56.jpg" alt="Photo 56" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-57.jpg" alt="Photo 57" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-58.jpg" alt="Photo 58" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-59.jpg" alt="Photo 59" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-60.jpg" alt="Photo 60" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-61.jpg" alt="Photo 61" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-62.jpg" alt="Photo 62" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-63.jpg" alt="Photo 63" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-64.jpg" alt="Photo 64" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-65.jpg" alt="Photo 65" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-66.jpg" alt="Photo 66" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-67.jpg" alt="Photo 67" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-68.jpg" alt="Photo 68" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-69.jpg" alt="Photo 69" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-70.jpg" alt="Photo 70" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-71.jpg" alt="Photo 71" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-72.jpg" alt="Photo 72" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-73.jpg" alt="Photo 73" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-74.jpg" alt="Photo 74" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-75.jpg" alt="Photo 75" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-76.jpg" alt="Photo 76" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-77.jpg" alt="Photo 77" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-78.jpg" alt="Photo 78" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-79.jpg" alt="Photo 79" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-80.jpg" alt="Photo 80" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-81.jpg" alt="Photo 81" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-82.jpg" alt="Photo 82" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-83.jpg" alt="Photo 83" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-84.jpg" alt="Photo 84" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-85.jpg" alt="Photo 85" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-86.jpg" alt="Photo 86" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-87.jpg" alt="Photo 87" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-88.jpg" alt="Photo 88" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-89.jpg" alt="Photo 89" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-90.jpg" alt="Photo 90" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-91.jpg" alt="Photo 91" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-92.jpg" alt="Photo 92" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-93.jpg" alt="Photo 93" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-94.jpg" alt="Photo 94" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-95.jpg" alt="Photo 95" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-96.jpg" alt="Photo 96" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-97.jpg" alt="Photo 97" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-98.jpg" alt="Photo 98" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-99.jpg" alt="Photo 99" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-100.jpg" alt="Photo 100" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-101.jpg" alt="Photo 101" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-102.jpg" alt="Photo 102" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-103.jpg" alt="Photo 103" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-104.jpg" alt="Photo 104" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-105.jpg" alt="Photo 105" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-106.jpg" alt="Photo 106" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-107.jpg" alt="Photo 107" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-108.jpg" alt="Photo 108" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-109.jpg" alt="Photo 109" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-110.jpg" alt="Photo 110" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-111.jpg" alt="Photo 111" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-112.jpg" alt="Photo 112" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-113.jpg" alt="Photo 113" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-114.jpg" alt="Photo 114" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-115.jpg" alt="Photo 115" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-116.jpg" alt="Photo 116" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-117.jpg" alt="Photo 117" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-118.jpg" alt="Photo 118" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-119.jpg" alt="Photo 119" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-120.jpg" alt="Photo 120" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-121.jpg" alt="Photo 121" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-122.jpg" alt="Photo 122" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-123.jpg" alt="Photo 123" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-124.jpg" alt="Photo 124" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-125.jpg" alt="Photo 125" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-126.jpg" alt="Photo 126" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-127.jpg" alt="Photo 127" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-128.jpg" alt="Photo 128" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-129.jpg" alt="Photo 129" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-130.jpg" alt="Photo 130" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-131.jpg" alt="Photo 131" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-132.jpg" alt="Photo 132" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-133.jpg" alt="Photo 133" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-134.jpg" alt="Photo 134" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-135.jpg" alt="Photo 135" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-136.jpg" alt="Photo 136" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-137.jpg" alt="Photo 137" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-138.jpg" alt="Photo 138" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-139.jpg" alt="Photo 139" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-140.jpg" alt="Photo 140" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-141.jpg" alt="Photo 141" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-142.jpg" alt="Photo 142" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-143.jpg" alt="Photo 143" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-144.jpg" alt="Photo 144" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-145.jpg" alt="Photo 145" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-146.jpg" alt="Photo 146" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-147.jpg" alt="Photo 147" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-148.jpg" alt="Photo 148" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-149.jpg" alt="Photo 149" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-150.jpg" alt="Photo 150" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-151.jpg" alt="Photo 151" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-152.jpg" alt="Photo 152" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-153.jpg" alt="Photo 153" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-154.jpg" alt="Photo 154" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-155.jpg" alt="Photo 155" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-156.jpg" alt="Photo 156" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-157.jpg" alt="Photo 157" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-158.jpg" alt="Photo 158" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-159.jpg" alt="Photo 159" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-160.jpg" alt="Photo 160" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-161.jpg" alt="Photo 161" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-162.jpg" alt="Photo 162" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-163.jpg" alt="Photo 163" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-164.jpg" alt="Photo 164" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-165.jpg" alt="Photo 165" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-166.jpg" alt="Photo 166" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-167.jpg" alt="Photo 167" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-168.jpg" alt="Photo 168" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-169.jpg" alt="Photo 169" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-170.jpg" alt="Photo 170" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-171.jpg" alt="Photo 171" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-172.jpg" alt="Photo 172" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-173.jpg" alt="Photo 173" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-174.jpg" alt="Photo 174" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-175.jpg" alt="Photo 175" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-176.jpg" alt="Photo 176" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-177.jpg" alt="Photo 177" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-178.jpg" alt="Photo 178" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-179.jpg" alt="Photo 179" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-180.jpg" alt="Photo 180" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-181.jpg" alt="Photo 181" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-182.jpg" alt="Photo 182" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-183.jpg" alt="Photo 183" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-184.jpg" alt="Photo 184" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-185.jpg" alt="Photo 185" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-186.jpg" alt="Photo 186" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-187.jpg" alt="Photo 187" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-188.jpg" alt="Photo 188" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-189.jpg" alt="Photo 189" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-190.jpg" alt="Photo 190" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-191.jpg" alt="Photo 191" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-192.jpg" alt="Photo 192" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-193.jpg" alt="Photo 193" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-194.jpg" alt="Photo 194" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-195.jpg" alt="Photo 195" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-196.jpg" alt="Photo 196" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-197.jpg" alt="Photo 197" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-198.jpg" alt="Photo 198" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-199.jpg" alt="Photo 199" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-200.jpg" alt="Photo 200" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-201.jpg" alt="Photo 201" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-202.jpg" alt="Photo 202" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-203.jpg" alt="Photo 203" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-204.jpg" alt="Photo 204" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-205.jpg" alt="Photo 205" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-206.jpg" alt="Photo 206" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-207.jpg" alt="Photo 207" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-208.jpg" alt="Photo 208" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-209.jpg" alt="Photo 209" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-210.jpg" alt="Photo 210" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-211.jpg" alt="Photo 211" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-212.jpg" alt="Photo 212" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-213.jpg" alt="Photo 213" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-214.jpg" alt="Photo 214" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-215.jpg" alt="Photo 215" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-216.jpg" alt="Photo 216" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-217.jpg" alt="Photo 217" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-218.jpg" alt="Photo 218" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-219.jpg" alt="Photo 219" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-220.jpg" alt="Photo 220" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-221.jpg" alt="Photo 221" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-222.jpg" alt="Photo 222" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-223.jpg" alt="Photo 223" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-224.jpg" alt="Photo 224" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-225.jpg" alt="Photo 225" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-226.jpg" alt="Photo 226" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-227.jpg" alt="Photo 227" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-228.jpg" alt="Photo 228" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-229.jpg" alt="Photo 229" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-230.jpg" alt="Photo 230" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-231.jpg" alt="Photo 231" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-232.jpg" alt="Photo 232" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-233.jpg" alt="Photo 233" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-234.jpg" alt="Photo 234" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-235.jpg" alt="Photo 235" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-236.jpg" alt="Photo 236" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-237.jpg" alt="Photo 237" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-238.jpg" alt="Photo 238" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-239.jpg" alt="Photo 239" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-240.jpg" alt="Photo 240" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-241.jpg" alt="Photo 241" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-242.jpg" alt="Photo 242" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-243.jpg" alt="Photo 243" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-244.jpg" alt="Photo 244" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-245.jpg" alt="Photo 245" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-246.jpg" alt="Photo 246" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-247.jpg" alt="Photo 247" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-248.jpg" alt="Photo 248" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-249.jpg" alt="Photo 249" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-250.jpg" alt="Photo 250" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-251.jpg" alt="Photo 251" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-252.jpg" alt="Photo 252" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-253.jpg" alt="Photo 253" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-254.jpg" alt="Photo 254" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-255.jpg" alt="Photo 255" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-256.jpg" alt="Photo 256" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-257.jpg" alt="Photo 257" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-258.jpg" alt="Photo 258" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-259.jpg" alt="Photo 259" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-260.jpg" alt="Photo 260" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-261.jpg" alt="Photo 261" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-262.jpg" alt="Photo 262" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-263.jpg" alt="Photo 263" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-264.jpg" alt="Photo 264" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-265.jpg" alt="Photo 265" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-266.jpg" alt="Photo 266" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-267.jpg" alt="Photo 267" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-268.jpg" alt="Photo 268" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-269.jpg" alt="Photo 269" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-270.jpg" alt="Photo 270" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-271.jpg" alt="Photo 271" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-272.jpg" alt="Photo 272" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-273.jpg" alt="Photo 273" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-274.jpg" alt="Photo 274" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-275.jpg" alt="Photo 275" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-276.jpg" alt="Photo 276" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-277.jpg" alt="Photo 277" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-278.jpg" alt="Photo 278" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-279.jpg" alt="Photo 279" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-280.jpg" alt="Photo 280" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-281.jpg" alt="Photo 281" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-282.jpg" alt="Photo 282" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-283.jpg" alt="Photo 283" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-284.jpg" alt="Photo 284" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-285.jpg" alt="Photo 285" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-286.jpg" alt="Photo 286" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-287.jpg" alt="Photo 287" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-288.jpg" alt="Photo 288" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-289.jpg" alt="Photo 289" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-290.jpg" alt="Photo 290" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-291.jpg" alt="Photo 291" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-292.jpg" alt="Photo 292" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-293.jpg" alt="Photo 293" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-294.jpg" alt="Photo 294" loading="lazy"/><figure><img src="https://2025.mtclinton.com/2025-295.jpg" alt="Photo 295" loading="lazy"/></p>]]></content:encoded></item><item><title>Eternal Resistance</title><link>https://mtclinton.com/posts/eternal-resistance/</link><pubDate>Sat, 27 Dec 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/eternal-resistance/</guid><category>writing</category><description>fire and frost, irritate the skin
pain and sorrow our lifelong friend
breath short, exhale watch the mist
fog over the eyes, death&rsquo;s sweet kiss
depression, despair, forlorn thoughts
woe is me, give in, all work for nought
iron blood the taste in mouth, dry tongue
knees on the ground, pain just begun</description><content:encoded>&lt;![CDATA[<p>fire and frost, irritate the skin<br>
pain and sorrow our lifelong friend<br>
breath short, exhale watch the mist<br>
fog over the eyes, death&rsquo;s sweet kiss</p><p>depression, despair, forlorn thoughts<br>
woe is me, give in, all work for nought<br>
iron blood the taste in mouth, dry tongue<br>
knees on the ground, pain just begun</p><p>Rage and Hate are my true Virgil<br>
guiding companions in this Inferno<br>
the cause, the mission, Love is lost<br>
but soldier on we must, no matter the cost</p><p>Always stay true to your self and your belief<br>
that is a Man&rsquo;s duty and there is no relief<br>
carry the burden no matter the heavy weight<br>
thy fate, success doubtful, at best belate</p><p>Arise, stay true, step forward and persist<br>
there will never be peace, continue to resist..</p>
]]></content:encoded></item><item><title>Learning to Sew Part 4: Bowling</title><link>https://mtclinton.com/posts/learning-to-sew-part-4-bowling/</link><pubDate>Fri, 26 Dec 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/learning-to-sew-part-4-bowling/</guid><category>crafting</category><description>Learning how to sew by making a bowling jacket</description><content:encoded>&lt;![CDATA[<p>Wax floor glistening, ball rolling forward<br>
Us pins, standing rigid looking on in horror.<br>
There is no way out, we are forever cornered<br>
Death is upon us, knocking at the front door.<br>
Heavy ball coming at us giving us a wink<br>
into the gutter we pray it may sink<br>
Bang! we are hit and we all start to fall<br>
sneering faces at our despair through the hall.</p><p>Presenting<strong>Learning to Sew Part 4:</strong><em><strong>Bowling Edition</strong></em></p><p>I have created Rag Jacket V4 around the same time as<a href="https://www.mtclinton.com/posts/learning-to-sew-part-3-polar/">Part 3</a>. It was born over a month ago by now with this article being a very late arrival.</p><h2 id="from-chick-to-chicken">From chick to Chicken</h2><p>As my sewing and writing of these articles has progressed I feel less able to write a compelling and intriguing stories for Rag Jacket.<br>
I think it is a fun format to show a creation, but I have become quite busy and anothe unfortunate truth is:<br>
As I get more skilled the process is much less exciting&hellip;<br>
No broken needles or sewing the collar to the bottom of th jacket.<br>
It is not exciting to write about the same steps.<br>
Going forward I may just post a poem and more pictures of Rag Jackets.<br>
I think it could be fun to start telling stories again per Rag Jacket but at this point I have very limited time and energy.</p><h2 id="result-rag-jacket-v4-bowling-edition">Result: Rag Jacket V4:<em>Bowling Edition</em></h2><p><figure><img src="result1.jpg" alt="rag jacket" loading="lazy"/></p><h2 id="an-unfortunate-fabric">An unfortunate fabric</h2><p>I bought this fabric at Michaels and thought it had potential. When I brought it home and looked at it I reconsidered.</p><p>It is a bit too wonky for me, but it is good practice.</p><p><figure><img src="fabric.jpg" alt="fabric" loading="lazy"/></p><h2 id="round-it-down">Round it down</h2><p>I attempted to have round edge pockets for this Rag Jacket</p><p>The result is decent. I think I did a better job on the corners than some of the other pockets that I have done in the future.</p><p><figure><img src="pockets.jpg" alt="pockets" loading="lazy"/></p><h2 id="collar">Collar</h2><p>I did an average job of collar creation and attachment.</p><p>Below is the attachment of the lower collar to the upper collar (I used a light blue felt wool for upper collar)</p><p><figure><img src="collar1.jpg" alt="collar" loading="lazy"/></p><p>I attached the collar stand to the collar..</p><p><figure><img src="collar2.jpg" alt="collar" loading="lazy"/></p><p>Attach collar stand to the jacket (I sewed the collar the wrong way but oh well..)</p><p><figure><img src="collar3.jpg" alt="collar" loading="lazy"/></p><p>Here is the end result: an attached collar that is the wrong way (lol)</p><p><figure><img src="collar4.jpg" alt="collar" loading="lazy"/></p><h2 id="all-put-together">All put together</h2><p>Here is the jacket in finished format.</p><p>I attached the front the wrong way so that the pockets are inside the jacket.</p><p>I guess one of the boons and curses of a fabric that is the same on both sides is you can&rsquo;t really go wrong, but can&rsquo;t go right either maybe?</p><p><figure><img src="hangar.jpg" alt="hangar" loading="lazy"/></p><h2 id="short-sleeves">Short Sleeves</h2><p>The sleeves on Rag Jacket V4 are a bit short but oh well (oh well is a common centement in this article)</p><p><figure><img src="sleeve.jpg" alt="sleeve" loading="lazy"/></p><h2 id="in-action">In ACTION!</h2><p>I took this Rag Jacket bowling and here is an interesting room that seems very 90s style:</p><p><figure><img src="room.jpg" alt="room" loading="lazy"/></p><p>Some neatly arranged bowling balls:</p><p><figure><img src="balls.jpg" alt="balls" loading="lazy"/></p><p>Here are a few action photos of taking down the pins</p><p><figure><img src="bowling.jpg" alt="bowling" loading="lazy"/></p><p>And the scores:</p><p><figure><img src="score1.jpg" alt="score" loading="lazy"/></p><p><figure><img src="score2.jpg" alt="score" loading="lazy"/></p><p>It was a fun little escapade, but the night is fleeting so its time to head back home.</p><p><figure><img src="cycle.jpg" alt="cycle" loading="lazy"/></p><p>edit&hellip; check next creation<a href="https://www.mtclinton.com/posts/midnight/">Part 5</a></p><h2 id="the-result-again">The Result (Again)</h2><p><figure><img src="result2.jpg" alt="result" loading="lazy"/></p>
]]></content:encoded></item><item><title>PumpGuard - A Monitoring Tool I Built and Then Abandoned</title><link>https://mtclinton.com/posts/pumpguard-operator/</link><pubDate>Sat, 20 Dec 2025 23:44:14 -0500</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/pumpguard-operator/</guid><category>code</category><description>I recently spent some time building this thing called PumpGuard. The idea was simple - monitor pump.fun in real-time to detect new token launches, catch rug pulls before they happen, and track whale movements. Basically a monitoring suite for that whole ecosystem.</description><content:encoded>&lt;![CDATA[<p>I recently spent some time building this thing called<a href="https://github.com/mtclinton/pumpguard-operator">PumpGuard</a>. The idea was simple - monitor pump.fun in real-time to detect new token launches, catch rug pulls before they happen, and track whale movements. Basically a monitoring suite for that whole ecosystem.</p><h2 id="the-result">The Result</h2><p><figure><img src="pumpguard.png" alt="PumpGuard" loading="lazy"/></p><p>I wrote it in Rust because I wanted something performant that could handle the volume of transactions on Solana. The architecture was decent - had modules for token monitoring, rug detection, and whale watching. Built a dashboard with WebSocket updates, integrated Telegram alerts, even set up Prometheus metrics. There&rsquo;s a Kubernetes operator too, though I never really got that part fully working. The operator definitly needs more work.</p><p>The core functionality worked. It could detect new tokens, track liquidity changes, and flag suspicious activity. The rug detector used a scoring system based on LP removal, dev wallet sells, and coordinated dumping patterns. The whale watcher tracked wallets above a certain threshold and alerted on accumulation or dump patterns.</p><p>But, I ran into some limitations pretty quick. The Solana RPC endpoints are rate limited unless you pay for premium access, which made real-time monitoring spotty at best. The rate limiting was really frustating. The public RPC would throttle you constantly, especially during high activity periods. Also, detecting rugs in real-time is harder than it sounds - by the time you see the LP being removed, it&rsquo;s usually too late anyway. False positives were a problem too - not every large sell is a rug, and not every whale movement is meaningful.</p><p>I also learned that building a Kubernetes operator is more complex than I initially thought. The CRD definitions and controller logic took way more time than expected, and I never really finished that part properly. The Rust async stuff was fine once I got the hang of it, but the Solana client libraries had their own quirks.</p><p>In the end, I decided to move on to other projects. The monitoring tool works for basic use cases, but it&rsquo;s not production-ready and I don&rsquo;t have the time or interest to polish it further. There&rsquo;s value in the codebase if someone wants to fork it, but I&rsquo;m done with it.</p><p>Some things I learned: Rust&rsquo;s async ecosystem is solid but has a learning curve. Solana&rsquo;s transaction model makes real-time monitoring tricky. And building tools for crypto markets means dealing with a lot of noise and false signals. The project taught me a lot about both Rust and blockchain monitoring, even if I didn&rsquo;t finish it. Overall it was a good experiance though.</p>
]]></content:encoded></item><item><title>Building a Minimal BitTorrent Client in Python</title><link>https://mtclinton.com/posts/pytorrent/</link><pubDate>Sun, 14 Dec 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/pytorrent/</guid><category>code</category><description>A tiny BitTorrent client implementation that actually works. Here's what I learned while building it.</description><content:encoded>&lt;![CDATA[<p>I&rsquo;ve been curious about how BitTorrent works under the hood. I download files from other peers, but how does that handshake happen? How do you verify you got the right pieces? How does it coordinate with trackers?</p><p>I spent some time building a minimal (<a href="https://github.com/mtclinton/py-torrent">client</a>BitTorrent client) in Python. It works and I learned a something I guess from it.</p><h2 id="the-result">The result</h2><p><figure><img src="py-torrent.gif" alt="py-torrent" loading="lazy"/></p><h2 id="what-it-does">What It Does</h2><p>This is a minimal, download-only BitTorrent client. You give it a<code>.torrent</code> file and an output path, and it handles the rest: connecting to trackers, finding peers, negotiating connections, and downloading the file piece by piece with integrity verification.</p><p>The implementation follows the core BitTorrent protocol pretty closely. It handles:</p><ul><li><strong>Bencode parsing</strong> - Reading<code>.torrent</code> metadata files</li><li><strong>Tracker communication</strong> - Getting peer lists from HTTP trackers</li><li><strong>Peer handshakes</strong> - The initial protocol handshake with other peers</li><li><strong>Piece management</strong> - Requesting, downloading, and verifying file pieces</li><li><strong>Concurrent downloads</strong> - Using threads to connect to multiple peers simultaneously</li></ul><p>The protocol is straightforward and simple. The handshake is just a fixed-length header, followed by the peer sending a bitfield showing which pieces they have. Then you send &ldquo;interested&rdquo; messages and request specific pieces by index and byte offset. The peer sends back blocks of data, and you verify each piece against its SHA-1 hash before assembling the final file.</p><h2 id="using-it">Using It</h2><p>The interface is so simple a caveman can run it:</p><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python main.py your-torrent.torrent output-file.iso</span></span></code></pre></div></div></figure><p>That&rsquo;s it. The client will:</p><ol><li>Parse the torrent file to extract metadata</li><li>Contact the tracker to get a list of peers</li><li>Connect to those peers and download pieces concurrently</li><li>Verify each piece as it comes in</li><li>Write the completed file to your output path</li></ol><p>By default, it prints colorful progress logs showing which pieces are being downloaded. If you want less churping and chatter, pass the<code>-q</code> flag for quiet mode.</p><p>The codebase is small - maybe 600 lines total across the main modules. Each component has a clear responsibility:</p><ul><li><code>bencode.py</code> - Parsing the bencode format used in torrent files</li><li><code>tracker.py</code> - HTTP requests to trackers</li><li><code>handshake.py</code> - The initial peer handshake protocol</li><li><code>message.py</code> - BitTorrent message types (request, piece, have, etc.)</li><li><code>client.py</code> - TCP connection management with peers</li><li><code>p2p.py</code> - Orchestrating the download across multiple peers</li></ul><h2 id="limitations">Limitations</h2><p>This is intentionally minimal, so there are some limitations:</p><ul><li>Only supports single-file torrents (no multi-file downloads)</li><li>Download-only (doesn&rsquo;t upload pieces to peers)</li><li>HTTP trackers with compact peer lists only (no UDP trackers)</li><li>No magnet link support</li></ul><p>But for educational purposes, it&rsquo;s perfect. You can read through the code and actually understand what&rsquo;s happening at each step. The protocol isn&rsquo;t hidden behind layers of abstraction or optimization.</p><h2 id="what-i-learned">What I Learned</h2><p>The most interesting part for me was seeing how peers coordinate. When you connect to a peer, they immediately send you a bitfield showing which pieces they have. You can then request specific pieces, but the peer might choke you if they don&rsquo;t want to upload to you right now. It&rsquo;s a whole negotiation dance.</p><p>Also, the integrity checking is clever. Each piece has a SHA-1 hash in the torrent file. You download the piece, hash it, and if it doesn&rsquo;t match, you know something went wrong. This means you can safely download pieces from multiple peers in parallel - if one sends you bad data, you just discard it and try again.</p><p>Threading makes a huge difference here. The implementation spawns a worker thread for each peer, so pieces can download in parallel. Without that, you&rsquo;d be waiting for one peer to send you everything sequentially, which would be painfully slow.</p><p>If you&rsquo;re curious about how BitTorrent actually works, I&rsquo;d recommend checking out the (<a href="https://github.com/mtclinton/py-torrent">client</a>code). It&rsquo;s all there, and it&rsquo;s readable enough that you can trace through what&rsquo;s happening from start to finish.</p>
]]></content:encoded></item><item><title>Learning to Sew Part 3: Polar</title><link>https://mtclinton.com/posts/learning-to-sew-part-3-polar/</link><pubDate>Fri, 05 Dec 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/learning-to-sew-part-3-polar/</guid><category>crafting</category><description>Learning how to sew by making a polar jacket</description><content:encoded>&lt;![CDATA[<p>A new post, a journey, a glorious new day<br>
But upon our path a Sphinx blocking our way<br>
To pass thou must answer this riddle from me<br>
Penguin, Polar Bear, Parrot,which belongs nought in the three<br>
Right hand confident with title says, &ldquo;Parrot&rdquo; with zeal<br>
Flash go the talons, blood spurting like a cut from steel<br>
Left Hand trembling and shaking, speaking softly, &ldquo;Polar Bear&rdquo;<br>
Crack! bones, tendons breaking, pain under Sphinx glare<br>
Head, all that was left, groaned &ldquo;Penguin&rdquo; with great care<br>
Neck severed, the head was moaning, what was our err?<br>
Upon the pieces Sphinx gazed, frightful sight for the ladies<br>
&ldquo;Twas your fate not the answer&rdquo; for I am no Sphinx, but Hades!</p><p>Presenting<strong>Learning to Sew Part 3:</strong><em><strong>Polar Edition</strong></em></p><p>It has been some time since I posted<a href="https://www.mtclinton.com/posts/learning-to-sew-part-2-burlap/">Part 2</a>. In truth, I finished Polar Edition a few days after Burlap but have been delayed writing this post. I had a lot of fun making this jacket. It was also really COOL to wear it ice skating and in front of a ton of people. The whole affair was a true pleasure&hellip;</p><h2 id="result-rag-jacket-v3-polar-edition">Result: Rag Jacket V3:<em>Polar Edition</em></h2><p><figure><img src="rag-jacket.jpg" alt="rag jacket" loading="lazy"/></p><h2 id="shivering-in-an-igloo">Shivering in an Igloo</h2><p>Just like every snowflake is unique, so is every pattern? Hmmm wait a moment. Every snowman starts with a handfull of snow just like a Rag Jacket? Wait, wait, wait that&rsquo;s not right. Every sewing project is like a snowball: doesn&rsquo;t look so good in full sunlight&hellip;. hmm maybe.
As you can see I am really trying to make this snow themed. But mayhaps my prose is, how should I say, ICE COLD?
I enjoyed using the pattern for Rag Jacket V2 Burlap Edition but wanted to try out new patterns. I found a COOL pattern from a company called Green Pepper titled &ldquo;Polar Jacket&rdquo; hee hee. I thought it would be fun to have a Polar themed post as Winter comes ever forward.</p><p>Creeping around the Fabric aisle of Michaels I held my thermometer to the fabrics looking for a nice cool one. Truth be told I bought a real funky one (you will have to wait until V4) to see it. I did not remain with my tail between my legs though and was soon back. I found a heavy weight cotton fabric that had navy patterning throughout that reminded me of some type of snowflake design. I was also reminded of those so-called &ldquo;luxury&rdquo; brands that love to have their little peasant wowwing patterns (think Burberry and Louis Vitton). Out of the way Bernard Arnault, there is a new Big Cheese (or should I say Big Baguette) in town&hellip;</p><p>Here&rsquo;s a hint of it on the reverse side:</p><p><figure><img src="fabric.jpg" alt="fabric" loading="lazy"/></p><h2 id="the-emperors-favourite-fool">The Emperors&rsquo; favourite FOOL</h2><p>I had a idea of a new method of attaching the navy lining to the outer shell of this Rag Jacket. In the past Rag Jacket I struggled to attach the lining and once attached the seam allowance and other threads poked out making the whole thing look unprofessional.</p><p>This time I thought to invert the attachment. I planned to attach both &ldquo;good&rdquo; sides together with the lining outside. This may be difficult for you to visualize (I know it was hard for me and I was the one doing it!). Basically, I wanted to attach the whole jacket together inverse, while leaving a hole at the bottom back of jacket that I could pull everything out of and correctly invertly invert it back to normal.</p><p>Sadly, I failed to visualize and test this. I was so confident it would work that I sewwed everything together. When trying to pull the right side out I realized this would not work at all, the sleeves, for example look below, when pulled out do not work correctly. Instead of an opening the lining keeps going and there is no way to fix any of it without taking it all apart&hellip;</p><p><figure><img src="mistake.jpg" alt="mistake" loading="lazy"/></p><p>Thread ripping<br>
It was rough and disheartening taking this Rag Jacket almost completely apart. I had double stiched and added many finishing details that made the seam ripping an uneasy task.</p><p>It took me over an hour to remove all the mistakes I had done. The seam allowance was in poor shape after all the additions and removes. This likely made the jacket fit in a tighter way.</p><p><figure><img src="mistake2.jpg" alt="mistake2" loading="lazy"/></p><h2 id="short-sleeves-highlight-my-watch">Short sleeves highlight my watch</h2><p>The width of most fabrics at Michaels is usually 44 inches (111 cm) which makes for more unfortunate design choices and pattern cutouts. I don&rsquo;t know much about pattern making and sewwing, but assume there is a reason the general standard is 150 cm.</p><p>What this means for this Rag Jacket is the sleeves will be a bit shorter than most and have a little extra unexpected information ;)</p><p><figure><img src="sleeve.jpg" alt="sleeve" loading="lazy"/></p><h2 id="a-broken-needle-on-a-broken-record">A Broken needle on a broken record</h2><p>When confronting the every pestilent collar attachment I snapped the needle on my machine. It went flying after aching and groaning while being forced to munch through almost 6 layers of fabric (2 of those being heavy wool).</p><p>At the time it was the evening and I dreading having to adventure into the dark unknown of monsters.</p><p>I wanted to get this project done though, so donning my cape and grabbing my cane I threw open the door.</p><p><figure><img src="broken.jpg" alt="broken" loading="lazy"/></p><p>I loaded up Google Maps inputted Michaels and speed off. I&rsquo;ve been to many different Michaels in past Month and thought this was a simple different one. I arrived at a Mall and looked for a spot among the rows and rows of steel to park.</p><p>Dreading the florescent glow and smell of cheap plastic I headed in searching for my goal, eager to complete this mission.</p><p>I stumbled around the building bumping and attempting to trip a few people on their phones walking along the long streches of Mall hallways. Searching for a map or glowing MICHAELS sign I was left wanting.</p><p>Eventually I used my phones GPS to find the general location and then came upon it.</p><p>A Michael but not the one that I was searching for&hellip;</p><p><figure><img src="michaels.jpg" alt="michaels" loading="lazy"/></p><p>I had enough time left in the night to change course and head to a familar friend. I picked up a pack of needles and heavy duty needles.</p><p><figure><img src="needles.jpg" alt="needles" loading="lazy"/></p><h2 id="hand-stiching">Hand stiching</h2><p>After all the tribulations I mostly finished this whole project. The collar attachment went OK but I noticed the lining could be folded down in the inside of the jacket for a better look.</p><p>Here is my first attempt at Hand stitching lining to collar/back of jacket.</p><p><figure><img src="hand-stitch.jpg" alt="hand-stitch" loading="lazy"/></p><h2 id="ice-house">Ice House</h2><p>I wore this jacket at the ice house in my area. It was a ton of fun ice skating in it.</p><p>The people at this Ice House are great and friendly. I have many happy memories as a child going to this Ice House with friends to have fun and break rules.</p><p>We got up to many exciting things here: from skating as fast as we could and then sliding to stealing a puck and doing all sorts of stuff in the rink with it. From what I remember the employees had to stop us several times. This building has been an important part of my life. I am quite glad it is still around and hope it will continue far in the future.</p><p>I plan to continue my journey with Rag Jacket V4</p><p>edit&hellip; check next creation<a href="https://www.mtclinton.com/posts/learning-to-sew-part-4-bowling/">Part 4</a></p><h2 id="the-result-again">The Result (Again)</h2><p><figure><img src="result.jpg" alt="result" loading="lazy"/></p>
]]></content:encoded></item><item><title>Squeaky Fan</title><link>https://mtclinton.com/posts/squeaky-fan/</link><pubDate>Fri, 28 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/squeaky-fan/</guid><category>writing</category><description>forlorn, adrift am i acursed
blood boiling heart ready to burst
in the halll the fan doth squeak
downcast my mind, moood bleak
for every step i strode
wishing it to be fixed, truth told
yet the sun doth rise day after day
and discomfort never fadeth away
why must i deal with such obstinance
nails on chalkboard Consonance
i yearn for a deep reprieve
yet thee fan must cleave
my soul from thy body
its quality so shoddy
my life now cast adrift
by this devils little gift
digging my grave with a shovel
is thy fate living in a hovel</description><content:encoded>&lt;![CDATA[<p>forlorn, adrift am i acursed<br>
blood boiling heart ready to burst<br>
in the halll the fan doth squeak<br>
downcast my mind, moood bleak<br>
for every step i strode<br>
wishing it to be fixed, truth told<br>
yet the sun doth rise day after day<br>
and discomfort never fadeth away<br>
why must i deal with such obstinance<br>
nails on chalkboard Consonance<br>
i yearn for a deep reprieve<br>
yet thee fan must cleave<br>
my soul from thy body<br>
its quality so shoddy<br>
my life now cast adrift<br>
by this devils little gift<br>
digging my grave with a shovel<br>
is thy fate living in a hovel</p>
]]></content:encoded></item><item><title>Why I will never use AI for art</title><link>https://mtclinton.com/posts/ai-nevermore/</link><pubDate>Fri, 28 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/ai-nevermore/</guid><category>writing</category><description>I&rsquo;ve been listening to a reading of Dante&rsquo;s Divine Comedy recently and in it I think that Dante mets a poet in Hell or Purgatory that comments how he and all poets steal others work. When I search online for the passage or character I cannot find reference to this but perhaps it was a dream or I made it up.</description><content:encoded>&lt;![CDATA[<p>I&rsquo;ve been listening to a reading of Dante&rsquo;s Divine Comedy recently and in it I think that Dante mets a poet in Hell or Purgatory that comments how he and all poets steal others work. When I search online for the passage or character I cannot find reference to this but perhaps it was a dream or I made it up.</p><p>I am trying to express myself more and enter into a more artistic pursuits. With the age of AI already upon us it is not tempting to use it to create things but I have thought to myself &ldquo;This poem or paragraph does not sound the best. There are spellllling mistakes everywhere in this post.&rdquo;</p><p>And so I thought I could use AI to help me with this. I have now posted 2 poems. When I originally posted them they were with an AI venteer (coating for teeth. I think I spelled it wrong). I wrote these poems (especially the 1st) with my heart and soul and then tried to use AI to clean them up.</p><p>What a disaster and disservice. In some, or many, senses the AI cleanup was cleaner and flowed better. But my soul was removed and it was just a clean husk.
When I asked my brother what he thought he told me:</p><p>&ldquo;I was thinking about it, it&rsquo;s like sewing where you could have a perfectly created jacket
but then it just looks store bought, where as if there are threads hanging off and stuff looking wacky
it&rsquo;s showing off yeah I sewed this&rdquo;</p><p>I want to create poetry because it is enjoyable to me and expresses my buried desired, my soul, my mind, my Weltanschauung.
Speelling mistakes, and incorrect flow and no poetry metre may not look good, but all of this is just what I want to do actualized.</p><p>I am glad I gave up and replaced the 2 poems on my site with the original ones I wrote with my soul.</p>
]]></content:encoded></item><item><title>A place that could have been, but never was</title><link>https://mtclinton.com/posts/a-place-that-could-have-been/</link><pubDate>Thu, 27 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/a-place-that-could-have-been/</guid><category>writing</category><description>a place that could have been but never was
is it dark, is it light, silence or a buzz
in this place, hope does permate the air
scatter around, many a soul it does ensnare
&ldquo;I could have been&rdquo; teeth clench and break
mind fantasizing, body refusing, unable to wake
but for a faustian spirit only heart will ache
walking thou lonely path, a truly broken road
sand carassesing feet, a forlorn river flowed
indominable spirit with promethian fire glowed
a place of promises of El Dorado gold
yet touched, inspected show only mold
go forth brave spirit past this place&rsquo;s gates
show thy sentinels what true Fate awaits!</description><content:encoded>&lt;![CDATA[<p>a place that could have been but never was<br>
is it dark, is it light, silence or a buzz<br>
in this place, hope does permate the air<br>
scatter around, many a soul it does ensnare<br>
&ldquo;I could have been&rdquo; teeth clench and break<br>
mind fantasizing, body refusing, unable to wake<br>
but for a faustian spirit only heart will ache<br>
walking thou lonely path, a truly broken road<br>
sand carassesing feet, a forlorn river flowed<br>
indominable spirit with promethian fire glowed<br>
a place of promises of El Dorado gold<br>
yet touched, inspected show only mold<br>
go forth brave spirit past this place&rsquo;s gates<br>
show thy sentinels what true Fate awaits!</p>
]]></content:encoded></item><item><title>Greek Myth Data: Timing CTEs vs Plain SQL</title><link>https://mtclinton.com/posts/mythic-cte/</link><pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/mythic-cte/</guid><category>code</category><description>I’ve been working on a personal sql project like a monk scribbling on a scroll: 120k deities, 150k heroes, 1.5M quests, 2M omens, plus hundreds of thousands of battle logs. Everything ships in a Docker image so you can spin up mythic-cte, run the bundled benchmark_queries.sql, and immediately compare Common Table Expressions against equivalent “plain” SQL.</description><content:encoded>&lt;![CDATA[<p>I’ve been working on a<a href="https://github.com/mtclinton/mythic-cte">personal sql project</a> like a monk scribbling on a scroll: 120k deities, 150k heroes, 1.5M quests, 2M omens, plus hundreds of thousands of battle logs. Everything ships in a Docker image so you can spin up<code>mythic-cte</code>, run the bundled<code>benchmark_queries.sql</code>, and immediately compare Common Table Expressions against equivalent “plain” SQL.</p><p>The benchmark script suppresses row output and only prints labels and timings. Here’s what my last run reported:</p><figure class="code-terminal" data-lang="plain"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">plain</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">CTE - Omen pressure analytics: 258 ms</span></span><span class="line"><span class="cl">Non-CTE - Omen pressure analytics: 178 ms</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl">CTE - Hero quest performance: 1.80 s</span></span><span class="line"><span class="cl">Non-CTE - Hero quest performance: 1.64 s</span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl">CTE - Pantheon lineage depth ≥ 8: 274 ms</span></span><span class="line"><span class="cl">Non-CTE - Lineage via self joins: 30 ms</span></span></code></pre></div></div></figure><p>Those numbers need context, so let’s walk through each pair that lives in<code>benchmark_queries.sql</code>.</p><h2 id="1-omen-pressure-analytics">1. Omen pressure analytics</h2><p>Both versions calculate “ominous pressure” by slicing the<code>omens</code> table down to the last 14 days, grouping per region, and joining back to the pantheon. The CTE flavor defines</p><figure class="code-terminal" data-lang="sql"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">sql</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">WITH</span><span class="w"/><span class="n">recent</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">region_density</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">deity_region</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"/><span class="p">...</span></span></span></code></pre></div></div></figure><p>so the filtered set is materialized once and reused. The non-CTE variant repeats the same WHERE clause in two separate subqueries. On a cold cache the CTE wins because it only reads two million omen rows once. In the timing above my cache was already warm, so the repeated scans didn’t cost much and the inline version squeaked ahead. When you add<code>EXPLAIN (ANALYZE, BUFFERS)</code> you’ll see the non-CTE query performs roughly twice as many shared buffer hits even when wall time is similar, which matters once the data no longer fits in RAM.</p><h2 id="2-hero-quest-performance">2. Hero quest performance</h2><p>This benchmark takes the 1.5M-row<code>quests</code> table plus<code>battle_logs</code> and answers, “How often does each hero succeed, how hard are their assignments, and how many battles have they seen lately?” The CTE version gives each aggregation a name:</p><figure class="code-terminal" data-lang="sql"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">sql</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">WITH</span><span class="w"/><span class="n">hero_effort</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">hero_success</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...),</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/><span class="n">recent_battles</span><span class="w"/><span class="k">AS</span><span class="w"/><span class="p">(...)</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"/><span class="p">...</span></span></span></code></pre></div></div></figure><p>The non-CTE version embeds the same three aggregations inline, which means the planner can’t reuse the scan results. Again, with warm caches the “plain” query looked faster (1.64s vs 1.80s), but the CTE plan avoids redundant work when the tables are colder and, more importantly, reads like documentation. Tuning these queries is much easier when each step has a name you can isolate.</p><h2 id="3-pantheon-lineage">3. Pantheon lineage</h2><p>This is the only truly recursive workload. The CTE walks the entire deity tree, starting at Chaos and descending until depth ≥ 8. The “non-CTE” comparison fakes it with six left joins:</p><figure class="code-terminal" data-lang="sql"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">sql</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"/><span class="p">...</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">FROM</span><span class="w"/><span class="n">deities</span><span class="w"/><span class="n">d0</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"/><span class="k">JOIN</span><span class="w"/><span class="n">deities</span><span class="w"/><span class="n">d1</span><span class="w"/><span class="k">ON</span><span class="w"/><span class="n">d1</span><span class="p">.</span><span class="n">parent_id</span><span class="w"/><span class="o">=</span><span class="w"/><span class="n">d0</span><span class="p">.</span><span class="n">id</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="p">...</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">LEFT</span><span class="w"/><span class="k">JOIN</span><span class="w"/><span class="n">deities</span><span class="w"/><span class="n">d6</span><span class="w"/><span class="k">ON</span><span class="w"/><span class="n">d6</span><span class="p">.</span><span class="n">parent_id</span><span class="w"/><span class="o">=</span><span class="w"/><span class="n">d5</span><span class="p">.</span><span class="n">id</span></span></span></code></pre></div></div></figure><p>Of course the self-join version is faster—it only sees six generations. The recursive CTE costs 274 ms but explores arbitrarily deep chains, which is something the fixed-depth query can’t even express. Bump the requested depth to 20 and the self-join collapses; the recursive version keeps working.</p><h2 id="takeaways">Takeaways</h2><ul><li><strong>CTEs aren’t mythic</strong>, but they’re great for sharing filtered subsets, documenting intent, and unlocking recursion. When you benchmark both sides, make sure you’re asking the same question—our lineage example proves that the fastest query can also be the wrong one.</li><li><strong>Warm caches hide inefficiencies</strong>. Fire up<code>EXPLAIN (ANALYZE, BUFFERS)</code> and compare block hits; you’ll notice the non-CTE variants doing twice the I/O even when the stopwatch looks close.</li><li><strong>Readable SQL pays for itself</strong>. The named CTE blocks in<code>benchmark_queries.sql</code> make step-by-step telemetry easier, which matters once a statement grows beyond a single screen.</li></ul><h2 id="reproduce-it-yourself">Reproduce it yourself</h2><figure class="code-terminal" data-lang="bash"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">bash</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker build -t mythic-cte .</span></span><span class="line"><span class="cl">docker run --rm -p 5432:5432 -e<span class="nv">POSTGRES_PASSWORD</span><span class="o">=</span>ambrosia mythic-cte</span></span><span class="line"><span class="cl">psql postgresql://demigod:ambrosia@localhost:5432/db -f benchmark_queries.sql</span></span></code></pre></div></div></figure><p>Here is the<a href="https://github.com/mtclinton/mythic-cte">project link</a> again. The script prints only the label and<code>Time:</code> line, so you can paste results straight into slides or blog posts. Tweak the LIMITs, change the time windows, or wrap individual blocks with<code>EXPLAIN (ANALYZE, BUFFERS)</code> to see what Postgres is really doing under the hood. The point isn’t that CTEs are always faster—it’s that on a dataset big enough to be interesting, you can finally see<em>when</em> they help and<em>why</em>.</p>
]]></content:encoded></item><item><title>Learning to Sew Part 2: Burlap</title><link>https://mtclinton.com/posts/learning-to-sew-part-2-burlap/</link><pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/learning-to-sew-part-2-burlap/</guid><category>crafting</category><description>Learning how to sew by making a burlap jacket</description><content:encoded>&lt;![CDATA[<p>Steam rising, up, up, my eyes watch it dissipate as I turn to my mug to take another sip.
I recently moved to a new area in my city that I am unfamiliar with. Naturally, I have been having a
grand time exploring the unknown. Like Bilbo says, &ldquo;It’s a dangerous business, Frodo, going out your door. You step onto the road, and if you don’t keep your feet, there’s no knowing where you might be swept off to&rdquo;, but to take the first step you need a first sip.
That&rsquo;s why I have been checking out all the interesting coffee shops in the area. They say to truly appreciate a good coffee you have to understand the
phrase &ldquo;bean to brew&rdquo;. I am not a sophisticated guy, but if I cannot understand that maybe I can do something else.
Maybe, just maybe, I can become the bean, or failing that, at least become a coffee bag. That&rsquo;s how we come to<strong>Learning to Sew Part 2:</strong><em><strong>Burlap Edition</strong></em></p><p>I guess that I have learned a lot since<a href="https://mtclinton.com/posts/learning-to-sew-part-1/">Part 1</a>. It has been less than a week since Rag Jacket V1 and I have not explored tutorials on sewing, tips on &ldquo;Craft like a Pro&rdquo;, or had an old man pop out of the bushes exclaming that he wishes to make me his apprentice. I failed in my first attempt and I just mildly considered some of my failings. Prep work, vision, and confidence were the true antithesis of part 1. This time I had a spark of inspiration and a grim determination to create an Inferno with it&hellip;</p><h2 id="result-rag-jacket-v2-burlap-edition">Result: Rag Jacket V2:<em>Burlap Edition</em></h2><p><figure><img src="rag-jacket-v2-1.png" alt="rag jacket" loading="lazy"/></p><h2 id="the-bag-of-fate">The Bag of Fate</h2><p>Adusting my glasses and tightening the knob on my microscope I confidently declared my scientifically based strategy of &ldquo;Learning to Sew&rdquo; in part 1 leaving you the reader, quite convinced&hellip; However, as the tail end of my lab coat faded from sight, the truth is that&hellip; I had abandoned my ideas as they left my lips. I proselytized Muslin. The fabric of learning. But it is so lightweight, so dull, so boring. I thought to continue creation of Rag Jacket with the same pattern. Comparing each iteration. But the pattern was so unexciting to me.</p><p>Forsaking Part 1, I took my 30 pieces of Silver and went to Michaels. I had ideas of purchasing flannel (a more heavyweight cotton) and was curious if there would be any interesting colors or patterns. I perused the sections and looking down found an interesting cloth. It was called &ldquo;Burlap&rdquo; and
the composition was of a material called Jute. After I looked at it, and gave it a lick, I thought &ldquo;This would be super difficult to make into a jacket but probably a lot of fun&rdquo;. The main issue that will continue for the rest of this post, is that the fabric is very loose. Maybe even 4 knots per square centimeter? Don&rsquo;t trust me. I am just some guy making a second jacket. But I will swear to this. If I take my hand and place it behind the fabric I can easily see my skin.</p><p><figure><img src="fabric.jpg" alt="fabric" loading="lazy"/></p><p>Naturally, this could not be an unlined jacket (not just because of local laws), but I had an idea. I thought by placing flannel behind the Burlap it could create an interesting effect. It would be the Burlap and a hint, a taste, a little offering of flannel. I committed and pressed the button to summon the cutters.</p><p>The Michaels employee was quite a pleasant woman, and in Part 3, I think I will dedicate a little section to Michaels employees. She asked what I was creating while she was measuring the Burlap. When I told her &ldquo;a jacket&rdquo; she have me a verbal &ldquo;ohhhhh&rdquo; with the obvious implication that she saw failure as my Destiny. I do not blame her. Such a project is quite difficult and unconventional. Burlap is used for coffee bags and probably many other things that I have no knowledge of, but I do not think I have seen it used as a fabric in clothing in my life. The Michaels lady was at the front of the store when I finally checked out and wished me good luck as I hopped to my second step on this journey. I can imagine &ldquo;customer service&rdquo; is the motto that the drones of quarter zip sweater corporate managers repeat over and over and over. But life is a beautiful thing and this woman was quite nice and I wish her all the best.</p><h2 id="sewing-in-the-great-outdoors-aka-my-balcony">Sewing in the great outdoors (AKA my balcony)</h2><p>I enlisted the help of three new tools for this project. These Musketeers went by the names Scissors, Needles, and Iron. In the end Needles was useless, but perhaps, in the future he will be worth his pay. Scissors left my hand aching and I already have plans to replace him with a man in England. Iron left me with a sense of uneasy as I pulled my blanket to my chin struggling to remember if I had decommissioned him for the night.</p><p>The pattern this time was a &ldquo;camp coat&rdquo; from Etsy. It looked cool so I bought it. That is the end.</p><p>I did not need to possess the intellect of Goethe to know that Burlap was a mythical beast and if Scissors attacked it, my apartment would be in ruins.
The material is such that when it is cut tiny fibers erupt and the entire knotting is thrown in turmoil. I knew I would have to act fast and minimized the damage and direct the resulting blows to a place I did not call home.</p><p><figure><img src="fraying.jpg" alt="fraying" loading="lazy"/></p><p>Moving my portable table and grabbing my extension cord (outlets on my balcony don&rsquo;t work) I was ready to cut the bag and spill the beans. This weekend was a pleasant fall day, with the leaves falling (on my fabric/jacket) and a gentle breeze touched my skin and tried to blow Rag Jacket V2 away.</p><p>Cutting the fabric and sewing it on the balcony was quite pleasant. There were a lot of challenges with the burlap and with sewing outside, but it was a very unique experience and I had a lot of fun. I tried to not drop any chalk onto any passerbys heads and in between sessions it was always a Christmas morning present to step onto the balcony and see that Rag Jacket V2 was still there and had not become a bird.</p><p>A thread in the wind<figure><img src="thread.jpg" alt="thread" loading="lazy"/></p><h2 id="skill-improvements">Skill Improvements</h2><p>This time around I used a lot more techniques to improve Rag Jacket V2. I tried to back stitch (I forgot many times) and practiced the zigzag stitch as I have no Serger machine. The results do not really show in the final result of Rag Jacket V2 but I am glad I did them. I also think the zigzag stitch and other extra stitching I did on the burlap helped to preserve the integrity of the fabric as I tossed it to and fro.</p><p><figure><img src="zigzag.jpg" alt="zigzag" loading="lazy"/></p><h2 id="session-strategy">Session Strategy</h2><p>I am not sure how many hours Rag Jacket V2 took. I sewed almost all of it on the weekend with some very minor clean up details done on Monday.
If I had to estimate I would say 8 - 10 hours but even that might be too high.</p><p><figure><img src="burlap.jpg" alt="burlap" loading="lazy"/></p><p>I had much success in working on this project in short intervals. When I woke up, before I left to go do something else. The longest session I spend on this project was sewing the lining together (a full jacket with body and sleeves without a collar). This took me a little longer than 1 hour and I was able to do it because I attempted it after the majority of the work with burlap was done and it was so much easier that the time passed easily.
I probably spent around 30 sessions making this jacket with average session being 15 - 20 minutes. I think this method was much easier than me dedicating a full block of time to it.</p><p>brrrrring brinnnnnnnnnnnggg &ldquo;London is calling&rdquo; (perusing antique stores in between sessions)</p><p><figure><img src="phone.jpg" alt="phone" loading="lazy"/></p><h2 id="creatures-of-the-night-aka-sewing-benjamin-franklin-style">Creatures of the Night (AKA sewing Benjamin Franklin style)</h2><p>Unfortunately the moon shows up early to the party this time of year and I had to spend many a session sewing by a unreliable lightbulb on my machine and a wall light looking to take retirement early on my balcony. Sewing outside in the dark was rough and a unique challenge, but mistakes by night only show by day and the day was a long way away.</p><p>I wish I had nightvision googles&hellip;</p><p><figure><img src="darkness.jpg" alt="darkness" loading="lazy"/></p><h2 id="sealing-the-beast">Sealing the beast</h2><p>After sewing both parts of the burlap and lining jacket (without the collar) I needed to attach the lining to the burlap. I was extreme keen to do this as by stitching the lining to the burlap I would finally be able to seal this monster away: Prevent more fraying and undoing of the Jute knots. Overall it was quite easy. I simply pulled the lining through matched it up, pinned, and stitched.</p><p>One thing I will mention is I tried on the burlap jacket, pre lining, and while it looked ok, it also turned me into Bigfoot: covered in hair. I was looking forward to not having to dirty another shirt while I stitched my flannel to the enemy of my washer.</p><p>Under the cover of night I exorcise you!</p><p><figure><img src="lining.jpg" alt="lining" loading="lazy"/></p><h2 id="freestyling">Freestyling.</h2><p>For the first part (body and sleeves) of Rag Jacket V2 I followed the pattern but I quickly started freestyling based on my vision. After becoming Bigfoot I saw the Burlap portion was too short and so I lengthened the lining to extend the full length of the jacket. I also knew that it would be a bad idea to punch button holes into the burlap as it would create fraying so I lengthened the front width of the lining to allow for innovations in the attachment technology.
I also chose to use wool scraps for the collar and the pocket lining. I thought a charcoal wool collar would look cool and the vomit green (or in polite society:<em>Moss</em> coloured) wool could be cool for the pockets.</p><p>Wool collar made from scraps</p><p><figure><img src="wool-collar.jpg" alt="wool collar" loading="lazy"/></p><p>In the end this jacket is not made with high quality fabric but I am quite pleased, and proud, to say that it is all natural: 100% Jute, cotton, and wool fabric with 100% cotton interfacing and thread.</p><h2 id="mistakes">Mistakes</h2><p>I made a lot of mistakes on this jacket. I messed up the direction of the collar and interfacing and had to redo it. The pockets are not finished well and punching through all of the fabric to attach them was difficult. My stitching and freestyling were not that good. Still I think the jacket looks different and unique. I have a lot to learn and more ideas and improvements to my technique.</p><p>Rag Jacket V2 feels warm. I have worn it around town. Luckily I am not in Brazil, Columbia, or another coffee producing country or I could get grabbed, tossed in a truck and delivered to Starbucks as a medium roast. I am proud and pleased with the result. It was a difficult project and I do not think there are many people now or in the past that have made a burlap jacket for their second sewing project. I plan to continue my journey with Rag Jacket V3</p><p>edit&hellip; check next creation<a href="https://www.mtclinton.com/posts/learning-to-sew-part-3-polar/">Part 3</a></p><h2 id="the-result-again">The Result (Again)</h2><p><figure><img src="rag-jacket-v2-2.png" alt="rag jacket" loading="lazy"/></p>
]]></content:encoded></item><item><title>Setting Up a Postgres, Go Gin, and React project on Kubernetes</title><link>https://mtclinton.com/posts/setting-up-postgres-go-gin-react-kubernetes/</link><pubDate>Fri, 14 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/setting-up-postgres-go-gin-react-kubernetes/</guid><category>code</category><description>I spent past few days setting up a Kubernetes project Finance Dashboard and this post is the curtain fall of a useful side project. The core code lives inside a single file: finance-dashboard.yaml. Much of the documenation on how to set it up is provided in the README of Finance Dashboard. Instead I&rsquo;ll briefly mention some issues I encountered.</description><content:encoded>&lt;![CDATA[<p>I spent past few days setting up a Kubernetes project<a href="https://github.com/mtclinton/finance-dashboard">Finance Dashboard</a> and this post is the curtain fall of a useful side project. The core code lives inside a single file:<code>finance-dashboard.yaml</code>. Much of the documenation on how to set it up is provided in the README of Finance Dashboard. Instead I&rsquo;ll briefly mention some issues I encountered.</p><h2 id="finance-dashboard">Finance Dashboard</h2><p><figure><img src="demo.gif" alt="finance-dashboard" loading="lazy"/></p><h3 id="the-moving-parts">The moving parts</h3><ul><li>Backend (Go/Gin) + Postgres + Frontend (nginx serving a static React build)</li><li>One namespace:<code>finance</code></li><li>Frontend proxies to the backend via<code>/api</code></li></ul><h3 id="problems-i-hit-and-fixes-that-stuck">Problems I hit (and fixes that stuck)</h3><ul><li><p>DNS flakiness and upstream resolution</p><ul><li>Problem: nginx tried to resolve<code>finance-backend</code> before the Service had endpoints → 502s and crash loops.</li><li>Fix: Use a ConfigMap-mounted nginx config and avoid<code>nginx -t</code> at start. Added a tiny init wait where needed. Later I eliminated DNS altogether by co-locating containers.</li></ul></li><li><p>“Pod can’t reach Postgres” whack‑a‑mole</p><ul><li>Problem: One-directional connectivity, or<code>pg_isready</code> passing while the app still failed.</li><li>Fixes:<ul><li>Simplified to a<strong>single Pod</strong> (<code>finance-stack</code>) running Postgres + backend (+ frontend). Backend connects to Postgres via<code>127.0.0.1</code>, zero CNI/DNS drama.</li><li>Explicit<code>?sslmode=disable</code> in<code>DATABASE_URL</code> for local clusters.</li></ul></li></ul></li><li><p>Readiness/Liveness probes fighting real life</p><ul><li>Problem:<code>/health</code> required DB; probes flipped endpoints to “not ready,” then nginx upstream broke.</li><li>Fix:<strong>TCP readiness</strong> on port 8080 (backend is ready once it’s listening) and longer liveness delays. The app itself handles DB retries/logging.</li></ul></li><li><p>Frontend proxy rewriting</p><ul><li>Problem:<code>/api/*</code> requests were getting mangled (trailing slash on<code>proxy_pass</code>).</li><li>Fix:<code>proxy_pass http://finance-backend:8080;</code> (no slash), plus config delivered via ConfigMap:<ul><li><code>/</code> → static files</li><li><code>/api/*</code> → backend</li><li>(Optional)<code>/health</code> → backend<code>/health</code> for quick checks</li></ul></li></ul></li><li><p>Seeding and demo data</p><ul><li>Problem: Empty UI during demos, or duplicate categories after multiple runs.</li><li>Fixes:<ul><li>Categories are unique on<code>(name, type)</code> with a dedupe step.</li><li>Added a<code>-seed-demo</code> flag to load realistic transactions/budgets only if none exist.</li></ul></li></ul></li></ul><h3 id="the-final-pattern-i-used">The final pattern I used</h3><ul><li>One Deployment, three containers (Postgres, backend, frontend/nginx). One Service for the frontend (ClusterIP), one for the backend (ClusterIP).</li><li>Frontend proxies<code>/api</code> to<code>127.0.0.1:8080</code> when co-located, or to the backend Service if split out later.</li><li>Port-forward the frontend Service in dev (<code>kubectl port-forward -n finance svc/finance-frontend 8081:80</code>) and open<code>http://localhost:8081</code>.</li></ul><h3 id="the-payoff">The payoff</h3><p>Once I stopped pretending this needed to be “production distributed” for a local Minikube demo, everything became boring and reliable. Co-locating Postgres + backend + nginx in one Pod made the<code>finance-dashboard.yaml</code> simpler, removed all the networking guesswork, and let me focus on the UI and data instead of the cluster.</p><p>That’s the configuration I’ll keep for now. When I go to a real cluster, I can split Services/Deployments again, but now I know exactly which knobs matter. After this project my finances have never looked better. Thank you Finance Dashboard!</p>
]]></content:encoded></item><item><title>Learning to Sew Part 1</title><link>https://mtclinton.com/posts/learning-to-sew-part-1/</link><pubDate>Sun, 09 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/learning-to-sew-part-1/</guid><category>crafting</category><description>Learning how to sew by making a jacket</description><content:encoded>&lt;![CDATA[<p>After the sudden and tragic death of<a href="https://sehkelly.com">Paul Vincent</a> this summer and my brother making his own suit for a<a href="https://monroeclinton.com/making-my-own-suit/">1920s-inspired lawn party</a> I have been inspired to learn sewing to make my own clothes. After much delay, I have finally started this journey and this is the first in what is planned to be a long series of posts documenting my foray into the art.</p><p>Long ago, I heard a story about a pottery class where the teacher told the students they could craft as they like. The final grade was to be determined by the last piece they created at the end of the class. Some students made pots everyday while others decided to take more time in crafting each piece. By the end of the class, when students were evaluated by their last piece and the students who had crafted a pot everyday far surpassed those who spent much longer on each pot they had created.</p><p>The point of this story is to illustrate my approach to learning sewing. I believe that even if I were to acquire expensive wool right now, say Fox Brothers for example, and I was to meticulously measure, cut, and sew a piece with the idea that it was an expensive fabric I would still fail tremendously. Even with care and attention to detail, I would make many mistakes with no experience. To use another example, when learning to ride a bicycle, one will fall to the ground continually no matter what approach is used, even if they possess an extraordinary sense of balance.</p><p>Instead, I will attempt to make as many pieces as possible, focusing on quantity rather than quality. Initially, as in this post, I will use the cheapest fabric possible: muslin. As I make beginner mistakes and improve my skill to a small degree, I will advance to a cheap cotton fabric and, naturally, incrementally improve my personal skills as well as advance the quality (and cost) of the fabric.</p><p>In time I hope to be able to craft 100% 350-500 GSM wool fabrics into various styles of jackets and trousers for the winter and 100% 200-350 GSM linen for the summer. I have various other ideas and plans regarding this, but the above goal should be the main focus at this period.</p><h2 id="the-result---rag-jacket-v1">The Result - Rag Jacket V1:</h2><p><figure><img src="rag-jacket-v1.jpg" alt="rag jacket" loading="lazy"/></p><h2 id="step-1-find-an-old-lady">Step 1: Find an old lady</h2><p>As with any hobby in the modern age, when one ventures into the arena and turns to face the jeering crowd a mishmash of faces held in contorted expressions: pleading, yelling, bargaining with you to &ldquo;buy MY product&rdquo;, to &ldquo;get THIS sewing machine&rdquo;, or &ldquo;you MUST get this tool&rdquo;. All I felt was disgust. Instead, I went to the forest and whistled to the birds. They listened to my tune, and the wind blew them away.</p><p>One day, a little birdie came back and whispered in my ear. That is how I was introduced to a generous older lady who was happy to give me her sewing machine, for free, as she no longer used it.
Such an event was fortuitous, as now, not only have I made a friend but I also have a mentor to receive advice and tips on the errors I will make.
This lady also has many similar interests to mine, such as antiques and rugs. By meeting her (instead of ordering some new expensive machine online), I got many useful tips and recommendations for another hobby.</p><p><figure><img src="machine.jpg" alt="sewing maching" loading="lazy"/></p><h2 id="step-2-print-and-tape-pattern-together">Step 2: Print and tape pattern together</h2><p>Now that I have the machine, I needed the fabric, tools, a printer, and a pattern. I got the pattern from my brother: a classic jacket pattern made by a person called &ldquo;mascultory&rdquo; on Etsy. Frankly, I have no love for the pattern, but my goal for now is to learn the basics of sewing. I will change the pattern to a more personally pleasing style once my skills improve.</p><p>For the fabric and tools, I went to Michaels and bought the cheapest fabric: muslin (a very lightweight fabric). In the store, I had a mindset of buying the fewest tools necessary to make this first jacket. I am new to the hobby, and thought that with such little knowledge it is common for a person to be swindled into acquiring expensive junk. I bought a rotary cutter and small board so I could quickly cut fabric (and hopefully not my finger). Additionally, I bought a cheap variety pack of buttons and a box of pins.</p><p>After debugging and fixing the linux drivers for connecting to a printer you can now start your journey. I took a step and fell on my face: messing up the scaling of the pattern to the printer paper. But many sheets later I had a short story and now I was ready to tape it together. Think of the pattern creation as a very easy puzzle. You just align the letters on the corners of each page and tape them together.</p><p><figure><img src="pattern.jpg" alt="pattern" loading="lazy"/></p><h2 id="step-3-cut-the-fabric-and-not-your-finger-using-the-pattern--1-hour">Step 3: Cut the fabric (and not your finger) using the pattern ~ 1 hour</h2><p>I rolled my fabric onto the table, wetted my rotary blade with my tongue and started wheeling and dealing in a way to impress Papa John for a job. Here I made my first incredible mistake. I did not pin or use weight on the pattern while cutting so it moved around alot and with the tiny self healing board under the fabric it was hard to maintain a clean cut. I also did not properly read the instructions for placing patterns with &ldquo;FOLD&rdquo; marked on them against a folded portion of fabric. Overall, the cutting portion went quite poorly. I accidently cut some areas marked as seam allowance and there was loose threading everywhere.</p><p><figure><img src="cutting.jpg" alt="cutting" loading="lazy"/></p><h2 id="step-4-sew-front-and-back-together--15-hours">Step 4: Sew Front and Back together ~ 1.5 hours</h2><p>After the fabric was cut out, I moved on to sewing the body (front, sides, and back) of the jacket together. The pattern had multiple details for adding pockets to the bottom front of the jacket and upper left front of the jacket. I decide to skip these as I knew the Rag Jacket would live up to its name by the end of the night. I did cut out and dart the middle front portion and after some time had 3 main pieces (back, right and left front). Then I made another mistake&hellip;</p><p><figure><img src="pinning.jpg" alt="pinning" loading="lazy"/></p><p>When attempting to attach the fronts to the back I first sewed the connection at the top of the shoulders. I connected the Rag Jacket into 1 piece now and then upon looking at it, realized that I had attached them the wrong way. The lesson being: pin it all together to make sure its right before sewing. I brought out the pocket knife and seam ripper to start again&hellip;</p><p><figure><img src="mistake.jpg" alt="mistake" loading="lazy"/></p><p>Now correctly oriented, I decided to slip it on and take a look. It looked ridiculous&hellip;</p><p><figure><img src="body.jpg" alt="body" loading="lazy"/></p><h2 id="step-5-sew-collar--20-minutes">Step 5: Sew Collar ~ 20 minutes</h2><p>At this point in the instructions I got to the collar. Here I realized that I had not cut the fabric correctly (using the FOLD method) and so, sighing, rolled out the fabric for another try. This time I pinned the pattern to the fabric and was more careful where the self healing board was placed. The cuts were much better than last time, but the pieces were also small (compared to body pieces).</p><p>I attached the collar to the body and did a laughable job. I need to review the pattern instructions more carefully for Rag Jacket V2 as my attachment of this collar makes me shudder.</p><p><figure><img src="collar.jpg" alt="collar" loading="lazy"/></p><h2 id="step-6-sew-sleeves--25-minutes">Step 6: Sew Sleeves ~ 25 minutes</h2><p>With the end in sight I progressed to the sleeves, a much easier task than the other steps. Sewing them together is mostly a series of straight lines. The most important thing to remember is to have to a mirror of sleeves rather than twins. Something to bring up now is that with the fabric I am using here the front and back facing of the fabric is meaningless. For most fabrics there is a &ldquo;good&rdquo; side to present and a &ldquo;bad&rdquo; side to hide which would make the orientation of all these pieces more important.</p><p><figure><img src="sleeve.jpg" alt="sleeve" loading="lazy"/></p><p>I forsaw the attachment of the sleeve to the body to go horribly wrong so I tried on the 3 pieces to imagine the Rag Jacket as it could be instead of the monster I knew it would become.</p><p><figure><img src="before-shoulder-attach.jpg" alt="before-shoulder-attach" loading="lazy"/></p><h2 id="step-7-attach-sleeves--30-minutes">Step 7: Attach Sleeves ~ 30 minutes</h2><p>It took me several minutes of pulling the sleeve inside out and then rightside and pinning it to body before I understood how to even sew the sleeve to the body while hiding the stitch. I aligned the top of the sleeve to the top of the shoulder, pinned, and left the rest to fate.</p><p>There was a large amount of extra fabric from the sleeve near the top of the shoulder that I have heard you are supposed to hand sew and then when you release the handstitch, after machine stitching, the fabric will have room to breath and be clean.</p><p>But I had no individual needle, just my machine, so I threw caution to the wind and pressed my foot to the pedal. Here is the hilarious result:</p><p><figure><img src="shoulder2.jpg" alt="shoulder2" loading="lazy"/></p><h2 id="step-8-buttons-and-other-details--1-hour">Step 8: Buttons and other details ~ 1 hour</h2><p>After trying on the Rag Jacket and laughing at myself, I decided to try to clean it up and get some experience adding buttons. After perusing the sewing marchine manual, reading and rereading the tiny text and strange diagrams, I tried many times to sew a buttonhole on some scrap fabric. Eventually I had a ghost of a buttonhole and decide it was time to try on the real thing. Unfortunately, I seriously underestimated the size of the buttonhole and while at first I had some satisfication that I created something that resembled a buttonhole, I quickly realized it was quite small. The Rag Jacket was looking to be a tight jacket with shoulder fluff all held together by a tiny button.</p><p><figure><img src="buttonhole.jpg" alt="buttonhole" loading="lazy"/></p><p>As I searched for the smallest button, I was unsure how to connect the button to the jacket as I had no individual needle and no idea how to use the machine to programmatically sew the tiniest of buttons to my Rag Jacket. Instead I positioned the jacket and button under the sewing machine&rsquo;s needle and turned the wheel by hand. As a result the button is there but barely. I sewed some of the edges of the jacket to hide the frays and decided to call it a day.</p><p><figure><img src="button.jpg" alt="button" loading="lazy"/></p><h2 id="lessons">Lessons</h2><ul><li>Always use pins or clips. For the pattern cutting or sewing pieces together</li><li>Cut the fabric on an even surface and try using shears rather than the rotary cutter</li><li>Get and use an iron to press fabric together</li><li>Make larger buttonholes</li><li>Get an individual needle to handstitch sleeve to body</li></ul><p>Overall the result of Rag Jacket V1 is bad. It looks ridiculous but I learned a lot. I hope to improve and release Rag Jacket V2 soon&hellip;.</p><p>edit&hellip; check it out<a href="https://www.mtclinton.com/posts/learning-to-sew-part-2-burlap/">Part 2</a></p><h2 id="the-result-again">The Result (Again)</h2><p><figure><img src="rag-jacket-v1.jpg" alt="rag jacket" loading="lazy"/></p>
]]></content:encoded></item><item><title>Updating a Rust Project to Latest Dependencies</title><link>https://mtclinton.com/posts/updating-rust-dependencies/</link><pubDate>Wed, 05 Nov 2025 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/updating-rust-dependencies/</guid><category>code</category><description>I recently updated an older Rust project (termdex, a terminal-based Pokédex) to use the latest package versions. Here&rsquo;s what I ran into and how I fixed it.
The Starting Point The project was using older versions of most dependencies:</description><content:encoded>&lt;![CDATA[<p>I recently updated an older Rust project (<a href="https://github.com/mtclinton/termdex">termdex</a>, a terminal-based Pokédex) to use the latest package versions. Here&rsquo;s what I ran into and how I fixed it.</p><h2 id="the-starting-point">The Starting Point</h2><p>The project was using older versions of most dependencies:</p><ul><li><code>ratatui</code> 0.26 (still named<code>tui</code> in Cargo.toml)</li><li><code>diesel</code> 2.0.0</li><li><code>crossterm</code> 0.26</li><li><code>reqwest</code> 0.11</li><li>And several others</li></ul><p>The goal was to get everything up to the latest stable versions while keeping the project functional.</p><h2 id="major-updates">Major Updates</h2><h3 id="ratatui-migration">Ratatui Migration</h3><p>The biggest change was moving from<code>ratatui</code> 0.27 to 0.29. The library had several API changes:</p><ul><li><strong>Frame generics</strong>:<code>Frame&lt;B&gt;</code> became just<code>Frame</code> (no generic parameter)</li><li><strong>Area method</strong>:<code>f.size()</code> →<code>f.area()</code></li><li><strong>Cursor positioning</strong>:<code>f.set_cursor()</code> →<code>f.set_cursor_position()</code> (takes a tuple now)</li><li><strong>Text API</strong>:<code>Spans</code> was replaced with<code>Line</code>. Code like<code>Text::from(Spans::from(...))</code> became<code>Text::from(vec![Line::from(...)])</code></li><li><strong>Wrap API</strong>:<code>Wrap { trim: true }</code> works, but<code>Wrap::trim()</code> doesn&rsquo;t exist in 0.29</li></ul><h3 id="diesel-macros">Diesel Macros</h3><p>Diesel 2.1 deprecated the old<code>#[table_name = "..."]</code> syntax. I updated all models to use the new format:</p><figure class="code-terminal" data-lang="rust"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">rust</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="c1">// Old</span></span></span><span class="line"><span class="cl"><span class="cp">#[table_name =</span><span class="s">"pokemon"</span><span class="cp">]</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">pub</span><span class="w"/><span class="k">struct</span><span class="nc">NewPokemon</span><span class="w"/><span class="p">{</span><span class="w"/><span class="o">..</span><span class="p">.</span><span class="w"/><span class="p">}</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="w"/></span></span><span class="line"><span class="cl"><span class="c1">// New</span></span></span><span class="line"><span class="cl"><span class="cp">#[diesel(table_name = pokemon)]</span><span class="w"/></span></span><span class="line"><span class="cl"><span class="k">pub</span><span class="w"/><span class="k">struct</span><span class="nc">NewPokemon</span><span class="w"/><span class="p">{</span><span class="w"/><span class="o">..</span><span class="p">.</span><span class="w"/><span class="p">}</span></span></span></code></pre></div></div></figure><h3 id="version-conflicts">Version Conflicts</h3><p>The trickiest part was resolving version conflicts between dependencies:</p><ul><li><code>tui-input</code> 0.8 used<code>crossterm</code> 0.27, but<code>ratatui</code> 0.29 needs<code>crossterm</code> 0.28</li><li>Solution: Updated<code>tui-input</code> to 0.14, which supports<code>crossterm</code> 0.28</li><li><code>ansi-to-tui</code> had similar issues—upgraded from 3.0 to 7.0 to match<code>ratatui</code> 0.29</li></ul><h3 id="docker-updates">Docker Updates</h3><p>The Dockerfiles needed Rust 1.86 to compile the latest<code>diesel_cli</code> (2.3.3). Updated both Dockerfiles from<code>rust:1.82</code> to<code>rust:1.86</code>.</p><h2 id="common-issues">Common Issues</h2><ol><li><strong>Borrow checker</strong>: Had to clone<code>Text</code> objects before passing them to widgets when they&rsquo;re used later</li><li><strong>Unused variables</strong>: Some loops had<code>index</code> that wasn&rsquo;t used, but in one case it was actually needed for array indexing</li><li><strong>Deprecated methods</strong>: Various method renames and API changes that required grep searches through the codebase</li></ol><h2 id="the-process">The Process</h2><p>I used Cursor&rsquo;s AI assistant to help with this. The workflow was:</p><ol><li>Update Cargo.toml with target versions</li><li>Run<code>cargo build</code> to see errors</li><li>Fix compilation errors one by one</li><li>Repeat until it builds</li></ol><p>The AI was helpful for finding all the places that needed changes (like searching for<code>f.size()</code> or<code>#[table_name</code>), but you still need to understand the codebase structure to make the right fixes.</p><h2 id="final-result">Final Result</h2><p><figure><img src="termdex.gif" alt="termdex" loading="lazy"/></p><p>After updating:</p><ul><li><code>ratatui</code>: 0.27 → 0.29</li><li><code>crossterm</code>: 0.27 → 0.28</li><li><code>diesel</code>: 2.0.0 → 2.1</li><li><code>reqwest</code>: 0.11 → 0.12</li><li><code>tui-input</code>: 0.8 → 0.14</li><li><code>ansi-to-tui</code>: 3.0 → 7.0</li></ul><p>Everything compiles and works. The warnings about unused imports and results are still there, but those are non-blocking.</p><h2 id="takeaways">Takeaways</h2><ol><li><strong>Read the error messages carefully</strong>—they often point to exactly what needs changing</li><li><strong>Update in stages</strong>—don&rsquo;t try to update everything at once</li><li><strong>Version conflicts are common</strong>—dependencies often have their own version requirements</li><li><strong>Keep Dockerfiles in sync</strong>—Rust version requirements can break builds</li></ol><p>The whole process took a couple of hours, mostly spent fixing API changes and resolving version conflicts. The code is now on modern, maintained versions of all dependencies.</p>
]]></content:encoded></item><item><title>Building a simple python epoll server</title><link>https://mtclinton.com/posts/simple-python-epoll-server/</link><pubDate>Sat, 08 Jan 2022 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/posts/simple-python-epoll-server/</guid><category>code</category><description>Echo client url using python http epoll server</description><content:encoded>&lt;![CDATA[<p>How can you make your python server fast? One method is through using the Linux system call epoll. Epoll is an I/O event notification system that monitors file descriptors of I/O events.</p><p>In your first foray into writing python http servers you will likely encounter or write a simple program as seen below:</p><h2 id="simple-socket-server-for-one-client">Simple socket server for one client</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">socket</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">HOST</span><span class="o">=</span><span class="s2">"127.0.0.1"</span><span class="c1"># Standard loopback interface address (localhost)</span></span></span><span class="line"><span class="cl"><span class="n">PORT</span><span class="o">=</span><span class="mi">9999</span><span class="c1"># Port to listen on</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span><span class="n">PORT</span><span class="p">))</span></span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">.</span><span class="n">listen</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="p">,</span><span class="n">addr</span><span class="o">=</span><span class="n">s</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="k">with</span><span class="n">conn</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Connected by</span><span class="si">{</span><span class="n">addr</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">while</span><span class="kc">True</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">data</span><span class="o">=</span><span class="n">conn</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="ow">not</span><span class="n">data</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">break</span></span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="o">.</span><span class="n">sendall</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></span></span></code></pre></div></div></figure><p>After understanding the basics of creating, listening, accepting and writing to a python socket the most obvious question will be how do I serve multiple clients?</p><p>One answer to this is epoll. Before we get to that though, we must examine why the above code can only serve one client. The reason is that the code is blocking and only accepting one connection.</p><p>By blocking we mean that for the lines conn, addr = s.accept and data = conn.recv(1024) the program will not continue until the completion of each event. Likewise, the program is only accepting one connection until it completes and exits.
Even if the code is put into an infinite loop the server will still only be able to accept one connection or client at a time.</p><p>When we are planning how to create a useful server and thinking how to counter the issues mentioned above we may think of multiple points that must be addressed in creating a multi-client server:</p><ul><li>Socket accept should be able to accept multiple clients instead of waiting for one</li><li>Handling the connection can cause server to slow down or even block</li><li>Receiving from the client can cause server to slow down or even block</li></ul><p>Ideally when we consider these problems we would want accepting clients, handling clients, receiving data and writing data to clients to be done fast or concurrently or both.</p><p>Such a solution may be provided through threads, but in this post we will examine using epoll. As mentioned in the introduction epoll is I/O event notification system that monitors file descriptors.
That means that we can use file descriptors to represent accept and handling clients with epoll monitoring them.</p><p>To begin writing this epoll http server we must change all sockets involved in the server to be non-blocking since if the socket is blocking it may wait and slow the entire server.</p><h2 id="set-socket-to-non-blocking">Set socket to non-blocking</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">socket</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">HOST</span><span class="o">=</span><span class="s2">"127.0.0.1"</span><span class="c1"># Standard loopback interface address (localhost)</span></span></span><span class="line"><span class="cl"><span class="n">PORT</span><span class="o">=</span><span class="mi">9999</span><span class="c1"># Port to listen on</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span><span class="n">PORT</span><span class="p">))</span></span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">.</span><span class="n">listen</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">s</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></span></span></code></pre></div></div></figure><p>To use epoll and python we must make use of the select module whose documentation can be read<a href="https://docs.python.org/3/library/select.html">here</a>.</p><p>You can create an epoll instance by using select.epoll() and register your server socket to the instance.
Next you create an infinite loop while getting a list of events through calling poll() on your instance.
Then you iterate through your list of events testing and appropriately applying logic based on if the event
is your server socket or if it is a read or write event.</p><h2 id="simple-epoll-server-instance">Simple epoll server instance</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">socket</span><span class="o">,</span><span class="nn">select</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">EOL1</span><span class="o">=</span><span class="sa">b</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">EOL2</span><span class="o">=</span><span class="sa">b</span><span class="s1">'</span><span class="se">\n\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">=</span><span class="sa">b</span><span class="s1">'HTTP/1.0 200 OK</span><span class="se">\r\n</span><span class="s1">Date: Mon, 1 Jan 1996 01:01:01 GMT</span><span class="se">\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">+=</span><span class="sa">b</span><span class="s1">'Content-Type: text/plain</span><span class="se">\r\n</span><span class="s1">Content-Length: 13</span><span class="se">\r\n\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">+=</span><span class="sa">b</span><span class="s1">'Hello, client'</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">HOST</span><span class="o">=</span><span class="s2">"127.0.0.1"</span><span class="c1"># Standard loopback interface address (localhost)</span></span></span><span class="line"><span class="cl"><span class="n">PORT</span><span class="o">=</span><span class="mi">9999</span><span class="c1"># Port to listen on</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="n">HOST</span><span class="p">,</span><span class="n">PORT</span><span class="p">))</span></span></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">=</span><span class="n">select</span><span class="o">.</span><span class="n">epoll</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">s</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">connections</span><span class="o">=</span><span class="p">{};</span><span class="n">requests</span><span class="o">=</span><span class="p">{};</span><span class="n">responses</span><span class="o">=</span><span class="p">{}</span></span></span><span class="line"><span class="cl"><span class="k">while</span><span class="kc">True</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">events</span><span class="o">=</span><span class="n">epoll</span><span class="o">.</span><span class="n">poll</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="n">fileno</span><span class="o">==</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">():</span></span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="p">,</span><span class="n">addr</span><span class="o">=</span><span class="n">sock</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">conn</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">conn</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">connections</span><span class="p">[</span><span class="n">conn</span><span class="o">.</span><span class="n">fileno</span><span class="p">()]</span><span class="o">=</span><span class="n">conn</span></span></span><span class="line"><span class="cl"><span class="n">requests</span><span class="p">[</span><span class="n">conn</span><span class="o">.</span><span class="n">fileno</span><span class="p">()]</span><span class="o">=</span><span class="sa">b</span><span class="s1">''</span></span></span><span class="line"><span class="cl"><span class="n">responses</span><span class="p">[</span><span class="n">conn</span><span class="o">.</span><span class="n">fileno</span><span class="p">()]</span><span class="o">=</span><span class="n">response</span></span></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">+=</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="n">EOL1</span><span class="ow">in</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="ow">or</span><span class="n">EOL2</span><span class="ow">in</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]:</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">modify</span><span class="p">(</span><span class="n">fileno</span><span class="p">,</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLOUT</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s1">'Client sent: '</span><span class="o">+</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">()[:</span><span class="o">-</span><span class="mi">2</span><span class="p">])</span></span></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLOUT</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">byteswritten</span><span class="o">=</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span></span></span><span class="line"><span class="cl"><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">=</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">][</span><span class="n">byteswritten</span><span class="p">:]</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="nb">len</span><span class="p">(</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">modify</span><span class="p">(</span><span class="n">fileno</span><span class="p">,</span><span class="mi">0</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLHUP</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">fileno</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="k">del</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">finally</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">sock</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span></span></span><span class="line"><span class="cl"><span class="n">epoll</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">sock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></span></span></code></pre></div></div></figure><p>This code is from<a href="http://scotdoyle.com/python-epoll-howto.html">Scott Doyle&rsquo;s site</a> which is one of the best sites for learning how to use epoll in linux. It has many wonderful examples of different implementations.</p><p>In the above code we see the basic setup of the socket and epoll. In the try block the connections, requests, and responses
dictionaries are created to track the use of the client socket, the sending of response data, and the accumulation of a request.
The reason these should be tracked is for the connection when it is ended the socket should be unregistered from the epoll instance.
For a request, the entire request may not all be sent at once but in parts that will be appended until an end of line (EOL) is reached.
For the response, all response data may not be written to a socket at once but sent in parts and as such must be tracked as a dictionary value.</p><p>To turn this into code we can use for a server library we need to create classes. First we will create a server class that will
set up the server socket and register that socket to an epoll instance.</p><h2 id="creating-a-server-class">Creating a server class</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">socket</span></span></span><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">e3.loop</span><span class="k">as</span><span class="nn">loop</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">class</span><span class="nc">Server</span><span class="p">():</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">=</span><span class="n">loop</span><span class="o">.</span><span class="n">Loop</span><span class="o">.</span><span class="n">instance</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">=</span><span class="kc">None</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">listen</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">port</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="k">assert</span><span class="ow">not</span><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">=</span><span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">setsockopt</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SOL_SOCKET</span><span class="p">,</span><span class="n">socket</span><span class="o">.</span><span class="n">SO_REUSEADDR</span><span class="p">,</span><span class="mi">1</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="kc">False</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">bind</span><span class="p">((</span><span class="s2">""</span><span class="p">,</span><span class="n">port</span><span class="p">))</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">128</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">register_handler</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">add_handler</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span><span class="bp">self</span><span class="o">.</span><span class="n">accept_connection</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">accept_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="n">connection</span><span class="p">,</span><span class="n">address</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_socket</span><span class="o">.</span><span class="n">accept</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">connection</span><span class="o">.</span><span class="n">setblocking</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">handle_connection</span><span class="p">(</span><span class="n">connection</span><span class="p">)</span></span></span></code></pre></div></div></figure><p>The e3.loop import is because this library is named e3 with a file called loop.py in it that contains
the logic for the epoll instance. When a server class is initialized it will create an epoll instance
by calling loop.Loop.instance(). Then by using its listen method the server&rsquo;s socket will be set up
and start listening. It will also register its socket file descriptor to the epoll instance.</p><p>The accept_connection method is one of the first main issues we encounter when writing an epoll server.
When nothing was abstracted the epoll instance could easily register the server socket file descriptor.
Only when the server class calls the listen method is the server socket
created and registered to the epoll instance. How should epoll track the file descriptor and be able to
call the accept method on the file descriptor to accept connections from clients?</p><p>The answer is by registering the server socket file descriptor to the epoll instance when the server
first starts listening and passing a callback to the epoll instance with that descriptor to be called when
an event occurs on the server socket. In addition, when this is first done in the server listen method we will
also change the epoll server_fd variable to be that of the server socket file descriptor so that when the
infinite loop is iterating over events it will be able to tell if the server socket has been called.</p><p>When an event has a file descriptor that is the same as the server socket the epoll instance will call the callback that
accepts the connection, sets the connection socket to be non-blocking, registers the connection socket to the
epoll instance and creates a value in the connections and requests dictionaries.</p><p>To understand what the epoll instance is doing see below:</p><h2 id="the-e3-epoll-instance">The e3 epoll instance</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">socket</span><span class="o">,</span><span class="nn">select</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">EOL1</span><span class="o">=</span><span class="sa">b</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">EOL2</span><span class="o">=</span><span class="sa">b</span><span class="s1">'</span><span class="se">\n\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">class</span><span class="nc">Loop</span><span class="p">():</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">=</span><span class="n">select</span><span class="o">.</span><span class="n">epoll</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="o">=</span><span class="p">{}</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="o">=</span><span class="p">{}</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="o">=</span><span class="p">{}</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">server_fd</span><span class="o">=</span><span class="o">-</span><span class="mi">1</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_handlers</span><span class="o">=</span><span class="p">{}</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="nd">@classmethod</span></span></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">instance</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="ow">not</span><span class="nb">hasattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span><span class="s2">"_instance"</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="bp">cls</span><span class="o">.</span><span class="n">_instance</span><span class="o">=</span><span class="bp">cls</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="k">return</span><span class="bp">cls</span><span class="o">.</span><span class="n">_instance</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">register_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">fd</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">fd</span><span class="p">,</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="o">|</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLET</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">server_fd</span><span class="o">=</span><span class="n">fd</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">add_handler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">fd</span><span class="p">,</span><span class="n">handler</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_handlers</span><span class="p">[</span><span class="n">fd</span><span class="p">]</span><span class="o">=</span><span class="n">handler</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">handle_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">connection</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">connection</span><span class="o">.</span><span class="n">fileno</span><span class="p">(),</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="o">|</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLET</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">connection</span><span class="o">.</span><span class="n">fileno</span><span class="p">()]</span><span class="o">=</span><span class="n">connection</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">connection</span><span class="o">.</span><span class="n">fileno</span><span class="p">()]</span><span class="o">=</span><span class="sa">b</span><span class="s1">''</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="k">while</span><span class="kc">True</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">events</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">poll</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">for</span><span class="n">fileno</span><span class="p">,</span><span class="n">event</span><span class="ow">in</span><span class="n">events</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="n">fileno</span><span class="o">==</span><span class="bp">self</span><span class="o">.</span><span class="n">server_fd</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">accept_connection</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_handlers</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span></span></span><span class="line"><span class="cl"><span class="n">accept_connection</span><span class="p">()</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLIN</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">while</span><span class="kc">True</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">+=</span><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1024</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="k">except</span><span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">pass</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="n">EOL1</span><span class="ow">in</span><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="ow">or</span><span class="n">EOL2</span><span class="ow">in</span><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]:</span></span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">modify</span><span class="p">(</span><span class="n">fileno</span><span class="p">,</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLOUT</span><span class="o">|</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLET</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">headercontent</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">requests</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">()[:]</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\r\n</span><span class="s2">"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span></span></span><span class="line"><span class="cl"><span class="n">url</span><span class="o">=</span><span class="n">headercontent</span><span class="o">.</span><span class="n">split</span><span class="p">()[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">:]</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">==</span><span class="mi">0</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="n">url</span><span class="o">=</span><span class="s2">"Hello add characters to your url to see the echo"</span></span></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">=</span><span class="s1">'HTTP/1.0 200 OK</span><span class="se">\r\n</span><span class="s1">Date: Mon, 1 Jan 1996 01:01:01 GMT</span><span class="se">\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">+=</span><span class="s1">'Content-Type: text/plain</span><span class="se">\r\n</span><span class="s1">Content-Length: '</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">url</span><span class="p">))</span><span class="o">+</span><span class="s1">'</span><span class="se">\r\n\r\n</span><span class="s1">'</span></span></span><span class="line"><span class="cl"><span class="n">response</span><span class="o">+=</span><span class="n">url</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">=</span><span class="n">response</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLOUT</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">while</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">byteswritten</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">][</span><span class="n">byteswritten</span><span class="p">:]</span></span></span><span class="line"><span class="cl"><span class="k">except</span><span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="k">pass</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">responses</span><span class="p">[</span><span class="n">fileno</span><span class="p">])</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">modify</span><span class="p">(</span><span class="n">fileno</span><span class="p">,</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLET</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">elif</span><span class="n">event</span><span class="o">&amp;</span><span class="n">select</span><span class="o">.</span><span class="n">EPOLLHUP</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">fileno</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="k">del</span><span class="bp">self</span><span class="o">.</span><span class="n">connections</span><span class="p">[</span><span class="n">fileno</span><span class="p">]</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span><span class="n">fd</span><span class="p">):</span></span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">"stopped epoll"</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">unregister</span><span class="p">(</span><span class="n">fd</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="bp">self</span><span class="o">.</span><span class="n">_epoll</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></span></span></code></pre></div></div></figure><p>Outside of the use of a callback for accepting client connections this epoll instance operates similar as the first
epoll example in that once events are created for the poll() method they are iterated and tested for being the server
file descriptor or read or write events. If a read event is called the instance reads from the socket until an end of line (EOL) is
encountered. It parses the request and creates a response with the client url request. It then creates a write event, that
when encountered by the epoll instance, will write to the client socket , in other words, echoing the request.</p><p>This can be tested out using this code:</p><h2 id="creating-a-server-class-1">Creating a server class</h2><figure class="code-terminal" data-lang="python"><div class="code-terminal-header"><span class="code-terminal-dots" aria-hidden="true"><span class="code-terminal-dot code-terminal-dot--red"/><span class="code-terminal-dot code-terminal-dot--amber"/><span class="code-terminal-dot code-terminal-dot--green"/></span><span class="code-terminal-lang">python</span><button type="button" class="code-terminal-copy" data-copy-code= aria-label="Copy code to clipboard"><span class="code-terminal-copy-icon" aria-hidden="true">⧉</span><span class="code-terminal-copy-label">COPY</span></button></div><div class="code-terminal-body"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span><span class="nn">e3</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">def</span><span class="nf">main</span><span class="p">():</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="n">http_server</span><span class="o">=</span><span class="n">e3</span><span class="o">.</span><span class="n">server</span><span class="o">.</span><span class="n">Server</span><span class="p">()</span></span></span><span class="line"><span class="cl"><span class="n">http_server</span><span class="o">.</span><span class="n">listen</span><span class="p">(</span><span class="mi">8889</span><span class="p">)</span></span></span><span class="line"><span class="cl"><span class="n">e3</span><span class="o">.</span><span class="n">loop</span><span class="o">.</span><span class="n">Loop</span><span class="o">.</span><span class="n">instance</span><span class="p">()</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></span></span><span class="line"><span class="cl"/></span><span class="line"><span class="cl"><span class="k">if</span><span class="vm">__name__</span><span class="o">==</span><span class="s2">"__main__"</span><span class="p">:</span></span></span><span class="line"><span class="cl"><span class="n">main</span><span class="p">()</span></span></span></code></pre></div></div></figure><p>Here is what it looks like in the browser:</p><h2 id="e3-server-returning-client-url-as-html">e3 server returning client url as html</h2><p><figure><img src="e3.gif" alt="e3" loading="lazy"/></p>
]]></content:encoded></item><item><title>About</title><link>https://mtclinton.com/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><dc:creator>Max Clinton</dc:creator><guid isPermaLink="true">https://mtclinton.com/about/</guid><description>I like to make things and occasionally write about what I have built.
Look at my stuff on GitHub.</description><content:encoded>&lt;![CDATA[<p>I like to make things and occasionally write about what I have built.</p><p>Look at my stuff on<a href="https://github.com/mtclinton">GitHub</a>.</p>
]]></content:encoded></item></channel></rss>