<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://jeromegill.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://jeromegill.com/" rel="alternate" type="text/html" /><updated>2026-10-20T09:31:49+00:00</updated><id>https://jeromegill.com/feed.xml</id><title type="html">Jerome Gill</title><subtitle>Jerome Gill is a software engineer in Tenerife, writing about software, AI-assisted development and side projects.</subtitle><author><name>Jerome Gill</name></author><entry><title type="html">Crossing The Antimeridian with PostGIS</title><link href="https://jeromegill.com/blog/antimeridian/" rel="alternate" type="text/html" title="Crossing The Antimeridian with PostGIS" /><published>2026-09-04T00:00:00+00:00</published><updated>2026-09-04T00:00:00+00:00</updated><id>https://jeromegill.com/blog/antimeridian</id><content type="html" xml:base="https://jeromegill.com/blog/antimeridian/"><![CDATA[<p>Normally when you want to do geospatial queries, you define a bounding box and ask your database to return geometries that have some relationship to the box.</p>

<p>The function for this is <a href="https://postgis.net/docs/ST_MakeEnvelope.html"><code class="language-plaintext highlighter-rouge">ST_MakeEnvelope</code></a></p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ST_MakeEnvelope</span><span class="p">(</span><span class="mi">177</span><span class="p">,</span> <span class="o">-</span><span class="mi">20</span><span class="p">,</span> <span class="mi">178</span><span class="p">,</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="mi">4326</span><span class="p">)</span>
<span class="c1">-- POLYGON((177 -20, 177 -16, 178 -16, 178 -20, 177 -20))</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">ST_MakeEnvelope</code> takes 4 arguments <code class="language-plaintext highlighter-rouge">(float xmin, float ymin, float xmax, float ymax)</code> and returns a polygon with 4 points, once in each corner of a rectangle.</p>

<p><code class="language-plaintext highlighter-rouge">xmin</code> and <code class="language-plaintext highlighter-rouge">ymin</code> are taken together to be the <em>“bottom left”</em> of the bounding box. <code class="language-plaintext highlighter-rouge">xmax</code> and <code class="language-plaintext highlighter-rouge">ymax</code> are taken to be the <em>“top right”</em>.</p>

<p>The Polygon format contains no indication about which point represents “bottom left” or “top right”. It simply stores an unordered collection of points. These can range from a simple rectangle to something incredibly complex with many, many points (think borders of a European country).</p>

<p>The function itself is agnostic as to what <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code> are, but generally we consider them as longitude and latitude.</p>

<p>When doing so, we have 180 degrees of longitude <code class="language-plaintext highlighter-rouge">y</code>, ranging from -90 to 90 and 360 degrees of latitude, <code class="language-plaintext highlighter-rouge">x</code>. 0 longitude is taken to be the equator. 0 latitude is the meridian line, which runs through Greenwich, London. For… err… historical reasons.</p>

<p><a href="https://gisgeography.com/latitude-longitude-coordinates/">gisgeography</a> has a great diagram of the basics of what these numbers mean.</p>

<p>They each behave slightly differently, arithmetically, when we cross their extremes.</p>

<h2 id="across-the-poles">Across the poles</h2>

<p>For longitude, if we take a value of, say 85 degrees north, and move 10 degrees further north, we take 5 degrees to cross the north pole, then find ourselves back where we started, a further 5 degrees from the north pole with a longitude of 85 once again.</p>

<p>But of course, we aren’t actually where we started. We crossed the north pole. And in that exact moment our latitude flipped 180 degrees.</p>

<h2 id="and-around-the-world">And around the world</h2>

<p>Circumnavigating the world at the equator means we have to implement wraparound logic somewhere.</p>

<p>We have two standard choices for where we do this, the meridian or, more commonly, the anti meridian.</p>

<p>If we take an x value of 0 to be the meridian line, to perform the wrap logic at the anti meridian we take a 360 degree scale from -180 to 180. Moving 10 degrees east from a position of 175 latitude, you cross the antimeridian and your latitude is now -175.</p>

<p>The alternative is to use a scale of 0 to 360 which gives us the wraparound logic at the meridian. Moving 10 degrees east at 355 degrees gives you a new latitude of 5.</p>

<h2 id="choosing-where-the-world-ends">Choosing where the world ends</h2>

<p>You choose which scale to use based on how people are likely to use your application. You want to calculate as few bounding boxes that cross your chosen wraparound location as possible. We do this to avoid unnecessary calculation of an accepted workaround.</p>

<p>Remember that the Polygon consists of unordered points. We can calculate (and therefore draw) the shape of it by drawing a line from the smallest to largest values for [x,y].</p>

<p>If we draw a line from the smallest value of <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code> to the largest value of <code class="language-plaintext highlighter-rouge">x</code> and smallest value of <code class="language-plaintext highlighter-rouge">y</code> we get a line along the bottom of our rectangle. Repeat this idea and we get the bounds.</p>

<p>Implementing this in code presents some problems because of a subtle difference in behaviour between <code class="language-plaintext highlighter-rouge">ST_MakeEnvelope</code> and the <a href="https://postgis.net/workshops/postgis-intro/geometries.html#polygons"><code class="language-plaintext highlighter-rouge">POLYGON</code></a> data format it returns.</p>

<p>Say you want Fiji. It sits at about 177 degrees east on one side of that line and about 178 degrees <em>west</em> on the other, so your minimum longitude is 177 and your maximum is -178.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>?bbox=177.0,-20.0,-178.0,-16.0
</code></pre></div></div>

<p>If you’re paying attention, you’ll notice the max is smaller than the min.</p>

<p>This results in a polygon as follows…</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ST_MakeEnvelope</span><span class="p">(</span><span class="mi">177</span><span class="p">,</span> <span class="o">-</span><span class="mi">20</span><span class="p">,</span> <span class="o">-</span><span class="mi">178</span><span class="p">,</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="mi">4326</span><span class="p">)</span>
<span class="c1">-- POLYGON((177 -20, 177 -16, -178 -16, -178 -20, 177 -20))</span>
</code></pre></div></div>

<p>RFC 7946 <a href="https://datatracker.ietf.org/doc/html/rfc7946#section-5">§5.2</a> says a box crossing the antimeridian has a northeast longitude lower than its southwest one, and gives Fiji as the worked example.</p>

<p>To use it, we must interpret those points back into a shape. And if you interpret that Polygon as a rectangle whose bounds run between the smallest X value, to the largest, you get a rectangle with y bounds that you expect, but x bounds that run from -178 all the way to 177. That’s 355 degrees of the planet instead of the 5 you asked for.</p>

<h2 id="so-what-do-we-do">So what do we do?</h2>

<p>Since a single polygon can only ever be read smallest to largest, the answer is to use two of them, each with its top right corner larger than its bottom left:</p>

<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">ST_MakeEnvelope</span><span class="p">(</span><span class="mi">177</span><span class="p">,</span>  <span class="o">-</span><span class="mi">20</span><span class="p">,</span>  <span class="mi">180</span><span class="p">,</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="mi">4326</span><span class="p">)</span>  <span class="c1">-- west of the line</span>
<span class="n">ST_MakeEnvelope</span><span class="p">(</span><span class="o">-</span><span class="mi">180</span><span class="p">,</span> <span class="o">-</span><span class="mi">20</span><span class="p">,</span> <span class="o">-</span><span class="mi">178</span><span class="p">,</span> <span class="o">-</span><span class="mi">16</span><span class="p">,</span> <span class="mi">4326</span><span class="p">)</span>  <span class="c1">-- east of it</span>
</code></pre></div></div>

<p>Both are ordinary boxes. Together they cover the 5 degrees you meant.</p>

<p>This struck me as bizarrely hacky for what I presume must be a very common problem.</p>

<p>I’m sure this is the most basic thing in the world to anyone who has worked with 2d maps more than I have, but I found it interesting.</p>

<h3 id="heres-how-i-solved-it-with-typeorm">Here’s how I solved it with <a href="https://typeorm.io/">TypeOrm</a>.</h3>

<p>First we split our min and max longitude if it crosses the antimeridian at 180 into two min and maxs with extremes of 180 and -180</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">splitAntimeridian</span><span class="p">({</span> <span class="nx">minLon</span><span class="p">,</span> <span class="nx">maxLon</span> <span class="p">}):</span> <span class="p">[</span><span class="kr">number</span><span class="p">,</span> <span class="kr">number</span><span class="p">][]</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nx">maxLon</span> <span class="o">&lt;</span> <span class="nx">minLon</span>
    <span class="p">?</span> <span class="p">[</span>
        <span class="p">[</span><span class="nx">minLon</span><span class="p">,</span> <span class="mi">180</span><span class="p">],</span>
        <span class="p">[</span><span class="o">-</span><span class="mi">180</span><span class="p">,</span> <span class="nx">maxLon</span><span class="p">],</span>
      <span class="p">]</span>
    <span class="p">:</span> <span class="p">[[</span><span class="nx">minLon</span><span class="p">,</span> <span class="nx">maxLon</span><span class="p">]];</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Then OR the two <code class="language-plaintext highlighter-rouge">ST_Intersects</code> calls together, inside a bracketed group:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">query</span><span class="p">.</span><span class="nf">andWhere</span><span class="p">(</span>
  <span class="k">new</span> <span class="nc">Brackets</span><span class="p">((</span><span class="nx">qb</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nf">splitAntimeridian</span><span class="p">(</span><span class="nx">bbox</span><span class="p">).</span><span class="nf">forEach</span><span class="p">(([</span><span class="nx">west</span><span class="p">,</span> <span class="nx">east</span><span class="p">],</span> <span class="nx">i</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="nx">qb</span><span class="p">.</span><span class="nf">orWhere</span><span class="p">(</span>
        <span class="s2">`ST_Intersects(geometry,
        ST_MakeEnvelope(:west</span><span class="p">${</span><span class="nx">i</span><span class="p">}</span><span class="s2">, :minLat, :east</span><span class="p">${</span><span class="nx">i</span><span class="p">}</span><span class="s2">, :maxLat, 4326))`</span><span class="p">,</span>
        <span class="p">{</span> <span class="p">[</span><span class="s2">`west</span><span class="p">${</span><span class="nx">i</span><span class="p">}</span><span class="s2">`</span><span class="p">]:</span> <span class="nx">west</span><span class="p">,</span> <span class="p">[</span><span class="s2">`east</span><span class="p">${</span><span class="nx">i</span><span class="p">}</span><span class="s2">`</span><span class="p">]:</span> <span class="nx">east</span><span class="p">,</span> <span class="nx">minLat</span><span class="p">,</span> <span class="nx">maxLat</span> <span class="p">},</span>
      <span class="p">);</span>
    <span class="p">});</span>
  <span class="p">}),</span>
<span class="p">);</span>
</code></pre></div></div>

<p>Now <code class="language-plaintext highlighter-rouge">ST_Intersects</code> calculates whether geometries of interest are found within 2 bounding boxes instead of 1, on either side of the antimeridian.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Normally when you want to do geospatial queries, you define a bounding box and ask your database to return geometries that have some relationship to the box.]]></summary></entry><entry><title type="html">Maintaining a reading list with claude</title><link href="https://jeromegill.com/blog/reading-list/" rel="alternate" type="text/html" title="Maintaining a reading list with claude" /><published>2026-07-31T00:00:00+00:00</published><updated>2026-07-31T00:00:00+00:00</updated><id>https://jeromegill.com/blog/reading-list</id><content type="html" xml:base="https://jeromegill.com/blog/reading-list/"><![CDATA[<p>I made a micro-app for tracking links Claude tells me to read.</p>

<p><a href="https://github.com/JeromeGill/reading-list">JeromeGill/reading-list</a></p>

<p><img src="https://raw.githubusercontent.com/JeromeGill/reading-list/main/docs/screenshot.png" alt="Reading List app screenshot" /></p>

<p>When working in unfamiliar tech I got into the habit of getting claude to find links to justify basically every decision I wasn’t sure about.</p>

<p>I started keeping a <code class="language-plaintext highlighter-rouge">.md</code> file of links managed by a skill that would add things to it as it finds things. But it got annoying to keep on top of. I’d forget to mark things as read, and generally it was annoying.</p>

<p>So I vibed up a little app to manage it for me.
The backend is a Claude Code skill that appends links to a YAML file. The frontend is a small Mac app made with tauri that reads that file and shows you what’s unread.</p>

<p>Claude never touches the read list. It only adds to the top of unread, and never adds the same link twice.</p>

<p>Each link gets one line on what it answers, not what it is. “When CommandBus and CommandHandler earn their keep versus a plain service” is useful later. “The NestJS CQRS docs” is not. You forget the conversation. The line has to work without it.</p>

<p>Click a link to open it. Click × to mark it read.</p>

<p>Nothing leaves your machine. The file is <code class="language-plaintext highlighter-rouge">~/.claude/reading-list.yaml</code>, plain text, on your Mac.</p>

<p>I’ve used it a lot while planning features, especially learning new tech. I have had to do a lot of that lately, now that I’m in a role where I have much less say over tech choices.</p>

<p>It should be pretty helpful though. You could use it to learn basically anything Claude can point you at.</p>

<p>Install is three steps, about five minutes. Get the app from <a href="https://github.com/JeromeGill/reading-list/releases">Releases</a>, or build it yourself from the <a href="https://github.com/JeromeGill/reading-list">repo</a> then in Claude Code:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/plugin marketplace add JeromeGill/reading-list
/plugin install reading-list@jeromegill-plugins
/reload-plugins
</code></pre></div></div>

<p>Then tell Claude to actually use it — add a line to <code class="language-plaintext highlighter-rouge">~/.claude/CLAUDE.md</code> saying so, because Claude only uses a skill when it decides it’s relevant, and left alone that’s inconsistent.</p>

<p>Skill and README are both on GitHub:</p>

<ul>
  <li><a href="https://github.com/JeromeGill/reading-list/blob/main/skills/reading-list/SKILL.md">Skill</a></li>
  <li><a href="https://github.com/JeromeGill/reading-list/blob/main/README.md">README</a></li>
</ul>

<p>Maybe it’s useful for someone else too.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[I made a micro-app for tracking links Claude tells me to read.]]></summary></entry><entry><title type="html">Revoking GH CLI oauth token</title><link href="https://jeromegill.com/blog/gh-token/" rel="alternate" type="text/html" title="Revoking GH CLI oauth token" /><published>2026-07-23T00:00:00+00:00</published><updated>2026-07-23T00:00:00+00:00</updated><id>https://jeromegill.com/blog/gh-token</id><content type="html" xml:base="https://jeromegill.com/blog/gh-token/"><![CDATA[<h1 id="revoking-a-gh-cli-token-properly">Revoking a <code class="language-plaintext highlighter-rouge">gh</code> CLI Token (Properly)</h1>

<p>If a GitHub CLI token leaks <code class="language-plaintext highlighter-rouge">gh auth logout</code> is not enough to revoke the token. It only deletes the token from your local credential store, at least on osx. The token itself stays valid on GitHub’s servers.</p>

<h2 id="why-gh-auth-logout-doesnt-work">Why <code class="language-plaintext highlighter-rouge">gh auth logout</code> doesn’t work</h2>

<p><code class="language-plaintext highlighter-rouge">gh cli</code> authenticates as an OAuth app, not a classic personal access token. That means the token won’t show up under <strong>Settings → Developer settings → Personal access tokens</strong>, and there’s no per-token revoke button anywhere.</p>

<h2 id="verify-it">Verify it</h2>

<p>Test the old token directly against the API:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-sI</span> <span class="nt">-H</span> <span class="s2">"Authorization: token OLD_TOKEN_HERE"</span> https://api.github.com/user
</code></pre></div></div>

<p>Run <code class="language-plaintext highlighter-rouge">gh auth logout</code>, then run this. It still returns <code class="language-plaintext highlighter-rouge">200 OK</code> — the token is still live, you just can’t use it from that machine anymore.</p>

<h2 id="the-actual-fix">The actual fix</h2>

<ol>
  <li>Go to <a href="https://github.com/settings/applications">github.com/settings/applications</a>.</li>
  <li>Find <strong>GitHub CLI</strong> (check both the “Authorized OAuth Apps” and “Authorized GitHub Apps” tabs — it can appear under either).</li>
  <li>
    <p>Click it, then <strong>Revoke access</strong>.
This invalidates every token that app has issued, on every machine.</p>
  </li>
  <li>Re-authenticate with:
    <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gh auth login
</code></pre></div>    </div>
  </li>
</ol>

<p>This generates a fresh token, replacing the one you just killed.</p>

<p>Github should make it very clear in the UI all valid tokens and when they were most recently used. But it doesn’t. Hopefully this helps someone.
Run the curl command again — it now returns <code class="language-plaintext highlighter-rouge">401 Unauthorized</code>.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Revoking a gh CLI Token (Properly) If a GitHub CLI token leaks gh auth logout is not enough to revoke the token. It only deletes the token from your local credential store, at least on osx. The token itself stays valid on GitHub’s servers. Why gh auth logout doesn’t work gh cli authenticates as an OAuth app, not a classic personal access token. That means the token won’t show up under Settings → Developer settings → Personal access tokens, and there’s no per-token revoke button anywhere.]]></summary></entry><entry><title type="html">More vibe porting</title><link href="https://jeromegill.com/blog/more-vibe-porting/" rel="alternate" type="text/html" title="More vibe porting" /><published>2026-07-11T00:00:00+00:00</published><updated>2026-07-11T00:00:00+00:00</updated><id>https://jeromegill.com/blog/more-vibe-porting</id><content type="html" xml:base="https://jeromegill.com/blog/more-vibe-porting/"><![CDATA[<p>Another vibe ported project caught my eye. PGRust.</p>

<p>Someone has ported <a href="https://github.com/malisper/pgrust">postgres into rust</a>.
This seems to be a two person project of over 7k commits. I don’t know enough rust to really comment on the code quality, but they claim good scores on certain metrics.</p>

<p>But what for?</p>

<p>Postgres is such a core technology that I really struggle to believe a vibe coded port will gain much traction. I think <a href="https://github.com/malisper/pgrust/issues/24">this</a> issue speaks for all of us.</p>

<p>Maybe it’s a cultural thing as a european but I find myself really turned off by the waste of producing stuff like this. Like, hand written passion projects were one thing, but these days anyone with a credit card and something to prove can create a port of a major open source project. But it doesn’t just cost money. It’s carbon, heat, water.</p>

<p>No one is going to use this over postgres. It’s just burning tokens for the sake of it existing. If the core maintainers want to port parts of postgres into rust, they will.</p>

<p>It isn’t proving anything. We all know it’s possible to create test passing code with llms.</p>

<p>I guess I just find my own reaction to it interesting. Just a few months ago I found the idea that we could more or less automate shifts into more appropriate languages for old projects exciting and potentially really valuable. Maybe I am already over it.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Another vibe ported project caught my eye. PGRust.]]></summary></entry><entry><title type="html">Extending .gitignore for a set of non-versioned ignores</title><link href="https://jeromegill.com/blog/localgitignore/" rel="alternate" type="text/html" title="Extending .gitignore for a set of non-versioned ignores" /><published>2026-05-28T00:00:00+00:00</published><updated>2026-05-28T00:00:00+00:00</updated><id>https://jeromegill.com/blog/localgitignore</id><content type="html" xml:base="https://jeromegill.com/blog/localgitignore/"><![CDATA[<p>There are occasions when I want files in a repo that should not be versioned but I don’t want to pollute a versioned gitignore with.</p>

<p>an example is a <code class="language-plaintext highlighter-rouge">notes</code> text file I often keep in a repo which is just random bullshit that probably belongs in tasks or documenting properly but I haven’t gotten around to yet.</p>

<p>Other examples are artifacts from agentic experiments that don’t need to be shared or remembered but I don’t want to delete yet.</p>

<p>For this, I’ve found the git excludesFile feature a really neat way to manage it.</p>

<p>Basically excludesFile is a set of files that git treats like <code class="language-plaintext highlighter-rouge">.gitignore</code> that we all know and love.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global core.excludesFile .gitignore.local
</code></pre></div></div>

<p>This command sets globally that any .gitignore.local file should be treated as a second .gitignore file.</p>

<p>It gets a bit clunky to describe but if you add .gitignore.local to .gitignore in any directory, you can then have a second set of unversioned ignores.</p>

<pre><code class="language-.gitignore">node_modules
.gitignore.local
</code></pre>

<pre><code class="language-.gitignore.local">notes.txt
</code></pre>

<p>It’s pretty handy for kind of a niche use case. But I’ve found it helpful.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[There are occasions when I want files in a repo that should not be versioned but I don’t want to pollute a versioned gitignore with.]]></summary></entry><entry><title type="html">Rock Climbing Vocab Flashcards</title><link href="https://jeromegill.com/blog/climbing-vocab-flashcards/" rel="alternate" type="text/html" title="Rock Climbing Vocab Flashcards" /><published>2026-05-20T00:00:00+00:00</published><updated>2026-05-20T00:00:00+00:00</updated><id>https://jeromegill.com/blog/climbing-vocab-flashcards</id><content type="html" xml:base="https://jeromegill.com/blog/climbing-vocab-flashcards/"><![CDATA[<h1 id="climbing-vocabulary--spanish--english">Climbing Vocabulary — Spanish ⇄ English</h1>

<p>A reference for climbers in Spanish-speaking areas (Spain-flavoured, because that’s where I live). Regional variants are noted where they matter (e.g. Latin America).</p>

<p>I know some of these translations are wrong and need work.</p>

<p>Want to improve the translations? See them <a href="https://docs.google.com/spreadsheets/d/1ukb1HkO_HRjNMfjzjvnnuc3JYf4JgTXvVu2JPJ1ObrM/edit?usp=sharing">here</a> and leave a comment. Please include what country you’re commenting from to help with regional differences</p>

<hr />

<h2 id="a-few-notes-on-usage">A Few Notes on Usage</h2>

<ul>
  <li><strong>“Seguro”</strong> is overloaded. It means “safe”, “I’m anchored”, or “off belay” depending on context. Always confirm visually before taking someone off belay.</li>
  <li><strong>“Cuerda”</strong> can mean “slack!” (give me rope) or “rope!” (warning, rope coming down). Tone and context decide.</li>
  <li><strong>“Cuerda doble”</strong> in Spanish refers to a <em>half rope</em> (used as a pair on multi-pitch). Don’t confuse with “two ropes” in general English.</li>
  <li><strong>“Friend”</strong> is universal — Spanish climbers use the English word, often pronounced “frien”. The plural is <em>friends</em> (sometimes <em>friendes</em>).</li>
  <li>Latin American countries sometimes use slight variants: e.g. <em>cuerda</em> can be <em>soga</em> in some regions, <em>pies de gato</em> may be <em>gatos</em> or <em>zapatos de escalar</em>, <em>magnesio</em> is <em>carbonato</em> or <em>tiza</em> in parts of Latin America.</li>
  <li>Encouragement in Spain leans loud and informal. <em>¡Vamos!</em>, <em>¡Venga!</em>, and <em>¡Tira!</em> are universal — don’t worry about being too polite at the crag.</li>
</ul>

<p>¡Buena escalada!</p>

<h2 id="rock-features-características-de-la-roca">Rock Features (Características de la Roca)</h2>

<h3 id="holds-presas--agarres">Holds (Presas / Agarres)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>presa / agarre</td>
      <td>hold</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>regleta</td>
      <td>crimp</td>
      <td>small edge for fingertips</td>
    </tr>
    <tr>
      <td>regletilla / microregleta</td>
      <td>micro-crimp</td>
      <td>tiny crimp</td>
    </tr>
    <tr>
      <td>canto</td>
      <td>edge</td>
      <td>flat edge</td>
    </tr>
    <tr>
      <td>romo / bola</td>
      <td>sloper</td>
      <td>rounded, friction-dependent</td>
    </tr>
    <tr>
      <td>pinza</td>
      <td>pinch</td>
      <td> </td>
    </tr>
    <tr>
      <td>bidedo</td>
      <td>two-finger pocket</td>
      <td>“two-finger”</td>
    </tr>
    <tr>
      <td>monodedo</td>
      <td>mono / one-finger pocket</td>
      <td> </td>
    </tr>
    <tr>
      <td>tridedo</td>
      <td>three-finger pocket</td>
      <td> </td>
    </tr>
    <tr>
      <td>hueco / agujero</td>
      <td>pocket / hueco</td>
      <td> </td>
    </tr>
    <tr>
      <td>bidón / cubo</td>
      <td>jug / bucket</td>
      <td>big, comfy hold</td>
    </tr>
    <tr>
      <td>presa cubo</td>
      <td>jug</td>
      <td> </td>
    </tr>
    <tr>
      <td>escama</td>
      <td>flake</td>
      <td> </td>
    </tr>
    <tr>
      <td>lateral / presa lateral</td>
      <td>sidepull</td>
      <td> </td>
    </tr>
    <tr>
      <td>invertido / presa invertida</td>
      <td>undercling</td>
      <td> </td>
    </tr>
    <tr>
      <td>gastón</td>
      <td>gaston</td>
      <td>thumb-down sidepull</td>
    </tr>
    <tr>
      <td>chuleta / bolo</td>
      <td>knob / chickenhead</td>
      <td>protruding feature</td>
    </tr>
    <tr>
      <td>presa de pie</td>
      <td>foothold</td>
      <td> </td>
    </tr>
    <tr>
      <td>repié / pie</td>
      <td>foothold</td>
      <td>small foothold</td>
    </tr>
  </tbody>
</table>

<h3 id="wall-features-características-de-la-pared">Wall Features (Características de la Pared)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>pared / muro</td>
      <td>wall / face</td>
      <td> </td>
    </tr>
    <tr>
      <td>placa</td>
      <td>slab</td>
      <td>less-than-vertical</td>
    </tr>
    <tr>
      <td>vertical</td>
      <td>vertical</td>
      <td> </td>
    </tr>
    <tr>
      <td>desplome</td>
      <td>overhanging wall</td>
      <td> </td>
    </tr>
    <tr>
      <td>extraplomo</td>
      <td>steep overhang</td>
      <td> </td>
    </tr>
    <tr>
      <td>techo</td>
      <td>roof</td>
      <td>horizontal</td>
    </tr>
    <tr>
      <td>panza / barriga</td>
      <td>bulge</td>
      <td> </td>
    </tr>
    <tr>
      <td>diedro</td>
      <td>dihedral / corner</td>
      <td>open-book</td>
    </tr>
    <tr>
      <td>arista</td>
      <td>arête</td>
      <td>outside corner</td>
    </tr>
    <tr>
      <td>fisura</td>
      <td>crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de dedos</td>
      <td>finger crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de manos</td>
      <td>hand crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de puños</td>
      <td>fist crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura ancha</td>
      <td>off-width</td>
      <td> </td>
    </tr>
    <tr>
      <td>chimenea</td>
      <td>chimney</td>
      <td> </td>
    </tr>
    <tr>
      <td>veta / hendidura</td>
      <td>seam</td>
      <td>very thin crack</td>
    </tr>
    <tr>
      <td>repisa</td>
      <td>ledge</td>
      <td> </td>
    </tr>
    <tr>
      <td>reposadero</td>
      <td>rest ledge</td>
      <td>good resting spot</td>
    </tr>
    <tr>
      <td>estalactita</td>
      <td>tufa / stalactite</td>
      <td>classic limestone feature</td>
    </tr>
    <tr>
      <td>columna</td>
      <td>column / pillar / tufa</td>
      <td> </td>
    </tr>
    <tr>
      <td>pilar</td>
      <td>pillar</td>
      <td> </td>
    </tr>
    <tr>
      <td>bloque</td>
      <td>boulder</td>
      <td>also generic block</td>
    </tr>
    <tr>
      <td>acantilado</td>
      <td>cliff / sea cliff</td>
      <td> </td>
    </tr>
    <tr>
      <td>sector</td>
      <td>sector / area of crag</td>
      <td> </td>
    </tr>
    <tr>
      <td>escuela</td>
      <td>crag</td>
      <td>“climbing school” — single-pitch sport crag</td>
    </tr>
    <tr>
      <td>zona de escalada</td>
      <td>climbing area</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="techniques-técnicas">Techniques (Técnicas)</h2>

<h3 id="foot-techniques-técnicas-de-pie">Foot Techniques (Técnicas de Pie)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cantear</td>
      <td>to edge</td>
      <td>use the edge of the shoe</td>
    </tr>
    <tr>
      <td>adherencia</td>
      <td>smearing</td>
      <td>friction on the shoe sole</td>
    </tr>
    <tr>
      <td>talonamiento / gancho de talón</td>
      <td>heel hook</td>
      <td> </td>
    </tr>
    <tr>
      <td>punteo / gancho de puntera</td>
      <td>toe hook</td>
      <td> </td>
    </tr>
    <tr>
      <td>rodilla baja / egipcio</td>
      <td>drop knee / Egyptian</td>
      <td> </td>
    </tr>
    <tr>
      <td>bandera</td>
      <td>flag</td>
      <td>counter-balancing leg</td>
    </tr>
    <tr>
      <td>bandera interior</td>
      <td>inside flag</td>
      <td> </td>
    </tr>
    <tr>
      <td>bandera exterior</td>
      <td>outside flag</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de pie</td>
      <td>foot jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>rodillazo / kneebar</td>
      <td>knee bar</td>
      <td> </td>
    </tr>
    <tr>
      <td>oposición / puente</td>
      <td>stemming / bridging</td>
      <td> </td>
    </tr>
    <tr>
      <td>sacar pies</td>
      <td>to move the feet up</td>
      <td>literally “take feet out”</td>
    </tr>
  </tbody>
</table>

<h3 id="hand--body-techniques-técnicas-de-mano-y-cuerpo">Hand / Body Techniques (Técnicas de Mano y Cuerpo)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>bloqueo / bloquear</td>
      <td>lock-off</td>
      <td> </td>
    </tr>
    <tr>
      <td>cruce / cruzar</td>
      <td>cross-through</td>
      <td> </td>
    </tr>
    <tr>
      <td>lance / lance dinámico</td>
      <td>dyno</td>
      <td>dynamic move</td>
    </tr>
    <tr>
      <td>dyno</td>
      <td>dyno</td>
      <td>also used as-is</td>
    </tr>
    <tr>
      <td>punto muerto</td>
      <td>deadpoint</td>
      <td>controlled dynamic</td>
    </tr>
    <tr>
      <td>igualar / juntar</td>
      <td>to match</td>
      <td>hands or feet</td>
    </tr>
    <tr>
      <td>rebote / repique</td>
      <td>bump</td>
      <td>move from hold to hold quickly</td>
    </tr>
    <tr>
      <td>mantle / manteo</td>
      <td>mantle</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotrar / empotre</td>
      <td>jam / jamming</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de mano</td>
      <td>hand jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de dedo</td>
      <td>finger jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>bicicleta</td>
      <td>layback (sometimes)</td>
      <td>also “scissor / bicycle” pedal move</td>
    </tr>
    <tr>
      <td>oposición de fuerza</td>
      <td>layback</td>
      <td>classic layback in a corner</td>
    </tr>
    <tr>
      <td>chimenear</td>
      <td>chimneying</td>
      <td> </td>
    </tr>
    <tr>
      <td>figura cuatro</td>
      <td>figure four</td>
      <td> </td>
    </tr>
    <tr>
      <td>figura ocho</td>
      <td>figure eight</td>
      <td> </td>
    </tr>
    <tr>
      <td>campus</td>
      <td>campus</td>
      <td>climbing without feet</td>
    </tr>
    <tr>
      <td>escalar a campus</td>
      <td>to campus</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en bloque / búlder</td>
      <td>bouldering</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="style--tactics-estilo-y-táctica">Style / Tactics (Estilo y Táctica)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>encadenar</td>
      <td>to send</td>
      <td>climb clean</td>
    </tr>
    <tr>
      <td>encadene</td>
      <td>a send / a redpoint</td>
      <td> </td>
    </tr>
    <tr>
      <td>a vista</td>
      <td>onsight</td>
      <td>first try, no info</td>
    </tr>
    <tr>
      <td>flash</td>
      <td>flash</td>
      <td>first try, with info</td>
    </tr>
    <tr>
      <td>ensayar</td>
      <td>to work / rehearse</td>
      <td> </td>
    </tr>
    <tr>
      <td>pegada / intento</td>
      <td>attempt / try / go</td>
      <td> </td>
    </tr>
    <tr>
      <td>proyecto / “el proyecto”</td>
      <td>project</td>
      <td> </td>
    </tr>
    <tr>
      <td>beta / secuencia</td>
      <td>beta / sequence</td>
      <td> </td>
    </tr>
    <tr>
      <td>paso clave / crux</td>
      <td>crux</td>
      <td>hardest move</td>
    </tr>
    <tr>
      <td>bombear / hinchar</td>
      <td>to pump out</td>
      <td> </td>
    </tr>
    <tr>
      <td>estar hinchado</td>
      <td>to be pumped</td>
      <td> </td>
    </tr>
    <tr>
      <td>congestión / hinchazón</td>
      <td>the pump</td>
      <td> </td>
    </tr>
    <tr>
      <td>colgar de la cuerda</td>
      <td>hangdog</td>
      <td>resting on the rope</td>
    </tr>
    <tr>
      <td>caer / volar</td>
      <td>to fall / take a whipper</td>
      <td> </td>
    </tr>
    <tr>
      <td>vuelo</td>
      <td>a fall (esp. a big one)</td>
      <td>“whipper”</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="equipment-material">Equipment (Material)</h2>

<h3 id="soft-goods-material-blando">Soft Goods (Material Blando)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>arnés</td>
      <td>harness</td>
      <td> </td>
    </tr>
    <tr>
      <td>anillo central / anillo de aseguramiento</td>
      <td>belay loop</td>
      <td> </td>
    </tr>
    <tr>
      <td>perneras</td>
      <td>leg loops</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda</td>
      <td>rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda simple</td>
      <td>single rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda doble</td>
      <td>half rope</td>
      <td>⚠️ “doble” in Spanish = half rope</td>
    </tr>
    <tr>
      <td>cuerda gemela</td>
      <td>twin rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda dinámica</td>
      <td>dynamic rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda estática</td>
      <td>static rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cinta / cinta exprés / exprés</td>
      <td>quickdraw</td>
      <td> </td>
    </tr>
    <tr>
      <td>cintas</td>
      <td>quickdraws (pl.) / slings</td>
      <td>context-dependent</td>
    </tr>
    <tr>
      <td>anillo de cinta</td>
      <td>sling / runner</td>
      <td> </td>
    </tr>
    <tr>
      <td>dyneema</td>
      <td>dyneema</td>
      <td> </td>
    </tr>
    <tr>
      <td>cinta tubular</td>
      <td>webbing / tubular tape</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordino</td>
      <td>cord / accessory cord</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordelette</td>
      <td>cordelette</td>
      <td>also borrowed as-is</td>
    </tr>
    <tr>
      <td>pies de gato</td>
      <td>climbing shoes</td>
      <td> </td>
    </tr>
    <tr>
      <td>magnesio</td>
      <td>chalk</td>
      <td> </td>
    </tr>
    <tr>
      <td>bolsa de magnesio</td>
      <td>chalk bag</td>
      <td> </td>
    </tr>
    <tr>
      <td>pof</td>
      <td>“pof” / pof bag</td>
      <td>pine resin (Fontainebleau-style, controversial)</td>
    </tr>
    <tr>
      <td>cepillo</td>
      <td>brush</td>
      <td>for cleaning holds</td>
    </tr>
    <tr>
      <td>colchoneta / crash pad</td>
      <td>crash pad</td>
      <td>bouldering</td>
    </tr>
    <tr>
      <td>casco</td>
      <td>helmet</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="hardware-material-metálico">Hardware (Material Metálico)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>mosquetón</td>
      <td>carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>mosquetón de seguridad</td>
      <td>locking carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>mosquetón HMS / pera</td>
      <td>HMS / pear-shaped carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta recta</td>
      <td>straight gate</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta curva</td>
      <td>bent gate</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta de alambre</td>
      <td>wiregate</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurador / aparato</td>
      <td>belay device</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>reverso / tubo</td>
      <td>tube-style belay device (ATC)</td>
      <td> </td>
    </tr>
    <tr>
      <td>GriGri</td>
      <td>GriGri</td>
      <td> </td>
    </tr>
    <tr>
      <td>autoblocante</td>
      <td>assisted-braking device</td>
      <td> </td>
    </tr>
    <tr>
      <td>ocho (de rapel)</td>
      <td>figure-8 descender</td>
      <td> </td>
    </tr>
    <tr>
      <td>maillón</td>
      <td>maillon / quicklink</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapa / plaqueta</td>
      <td>bolt hanger</td>
      <td>the visible plate</td>
    </tr>
    <tr>
      <td>parabolt</td>
      <td>expansion bolt</td>
      <td> </td>
    </tr>
    <tr>
      <td>químico / anclaje químico</td>
      <td>glue-in bolt</td>
      <td> </td>
    </tr>
    <tr>
      <td>anclaje</td>
      <td>anchor point / bolt</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>reunión</td>
      <td>belay / anchor (the station)</td>
      <td> </td>
    </tr>
    <tr>
      <td>descuelgue / cadenas</td>
      <td>lower-off / chains</td>
      <td>top of sport route</td>
    </tr>
    <tr>
      <td>clavo / pitón</td>
      <td>piton</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="trad-gear-material-de-empotradores">Trad Gear (Material de Empotradores)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>empotrador</td>
      <td>nut / passive pro (generic)</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotrador de cable / fisurero</td>
      <td>wired nut / stopper</td>
      <td> </td>
    </tr>
    <tr>
      <td>hexagonal / hexcentric</td>
      <td>hex</td>
      <td> </td>
    </tr>
    <tr>
      <td>tricam</td>
      <td>tricam</td>
      <td> </td>
    </tr>
    <tr>
      <td>friend / leva</td>
      <td>cam / camming device</td>
      <td>“friend” is universal</td>
    </tr>
    <tr>
      <td>friend dudoso</td>
      <td>marginal cam placement</td>
      <td>“dodgy friend”</td>
    </tr>
    <tr>
      <td>micro-friend</td>
      <td>micro cam</td>
      <td> </td>
    </tr>
    <tr>
      <td>ball nut</td>
      <td>ball nut</td>
      <td> </td>
    </tr>
    <tr>
      <td>offset</td>
      <td>offset (nut or cam)</td>
      <td> </td>
    </tr>
    <tr>
      <td>extractor / llave</td>
      <td>nut tool / nut key</td>
      <td> </td>
    </tr>
    <tr>
      <td>juego (de friends / de empotradores)</td>
      <td>rack</td>
      <td>“set”</td>
    </tr>
    <tr>
      <td>equipo</td>
      <td>full rack / setup</td>
      <td>broader</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="useful-phrases-frases-útiles">Useful Phrases (Frases Útiles)</h2>

<h3 id="belay-commands-voces-de-aseguramiento">Belay Commands (Voces de Aseguramiento)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>¿Aseguras? / ¿Listo?</td>
      <td>On belay? / Ready?</td>
      <td> </td>
    </tr>
    <tr>
      <td>Asegurando / Te aseguro</td>
      <td>Belaying / Belay on</td>
      <td> </td>
    </tr>
    <tr>
      <td>Escalando / Voy</td>
      <td>Climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>Cuando quieras / Adelante</td>
      <td>Climb on / Go ahead</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Cuerda!</td>
      <td>Slack! / Rope!</td>
      <td>“give me slack” — context</td>
    </tr>
    <tr>
      <td>Dame cuerda</td>
      <td>Give me slack</td>
      <td> </td>
    </tr>
    <tr>
      <td>Recoge</td>
      <td>Take in / up rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>Tensa</td>
      <td>Take! / Tension!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Tenso / Tengo</td>
      <td>I’ve got you (tight)</td>
      <td> </td>
    </tr>
    <tr>
      <td>¿Me tienes?</td>
      <td>Got me?</td>
      <td> </td>
    </tr>
    <tr>
      <td>Te tengo</td>
      <td>I’ve got you</td>
      <td> </td>
    </tr>
    <tr>
      <td>Bájame</td>
      <td>Lower me</td>
      <td> </td>
    </tr>
    <tr>
      <td>Voy a chapar</td>
      <td>Clipping</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Chapado!</td>
      <td>Clipped!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Caigo / ¡Voy!</td>
      <td>Falling!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Libre / Estoy seguro</td>
      <td>Off belay / I’m safe</td>
      <td>“seguro” = safe/anchored</td>
    </tr>
    <tr>
      <td>Hasta mí</td>
      <td>That’s me (end of rope)</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Atento! / ¡Mira!</td>
      <td>Watch me!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Piedra!</td>
      <td>Rock!</td>
      <td>falling rock — warning</td>
    </tr>
    <tr>
      <td>¡Cuerda! (gritado desde arriba)</td>
      <td>Rope!</td>
      <td>warning when throwing rope</td>
    </tr>
  </tbody>
</table>

<h3 id="encouragement-ánimos">Encouragement (Ánimos)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>¡Vamos! / ¡Venga!</td>
      <td>Come on! / Let’s go!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tú puedes!</td>
      <td>You can do it!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tira!</td>
      <td>Pull!</td>
      <td>“go for it”</td>
    </tr>
    <tr>
      <td>¡Aguanta!</td>
      <td>Hold on!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Sigue! / ¡Arriba!</td>
      <td>Keep going! / Up!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Fuerza!</td>
      <td>Strength! / Power!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Empuja!</td>
      <td>Push!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Confía (en los pies)!</td>
      <td>Trust (your feet)!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Saca pies!</td>
      <td>Move your feet up!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Respira!</td>
      <td>Breathe!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Bien! / ¡Eso es!</td>
      <td>Good! / That’s it!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡A muerte!</td>
      <td>Full effort!</td>
      <td>“to the death”</td>
    </tr>
    <tr>
      <td>¡Vamos campeón / campeona!</td>
      <td>Let’s go champ!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tira con huevos!</td>
      <td>Pull hard!</td>
      <td>vulgar but very common in Spain</td>
    </tr>
    <tr>
      <td>¡Crúzate!</td>
      <td>Cross!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Bloquea!</td>
      <td>Lock it off!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Salta!</td>
      <td>Jump / dyno!</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="knots-nudos">Knots (Nudos)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>nudo</td>
      <td>knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de ocho / ocho</td>
      <td>figure-eight</td>
      <td> </td>
    </tr>
    <tr>
      <td>ocho doble / ocho de seguimiento</td>
      <td>figure-eight follow-through</td>
      <td>the tie-in knot</td>
    </tr>
    <tr>
      <td>nudo de nueve</td>
      <td>figure-nine</td>
      <td> </td>
    </tr>
    <tr>
      <td>as de guía</td>
      <td>bowline</td>
      <td> </td>
    </tr>
    <tr>
      <td>ballestrinque / nudo dinámico</td>
      <td>clove hitch</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo italiano / dinámico</td>
      <td>Munter hitch / Italian hitch</td>
      <td>UIAA hitch</td>
    </tr>
    <tr>
      <td>nudo prusik</td>
      <td>prusik knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>machard / prusik francés</td>
      <td>French prusik / autoblock</td>
      <td> </td>
    </tr>
    <tr>
      <td>klemheist</td>
      <td>klemheist</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de cinta</td>
      <td>water knot / tape knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>pescador doble</td>
      <td>double fisherman’s</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo simple</td>
      <td>overhand knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de tope / nudo de seguridad</td>
      <td>stopper knot / backup knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>gaza / lazada</td>
      <td>loop / bight</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="grades-grados">Grades (Grados)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>grado</td>
      <td>grade</td>
      <td> </td>
    </tr>
    <tr>
      <td>vía</td>
      <td>route</td>
      <td> </td>
    </tr>
    <tr>
      <td>largo</td>
      <td>pitch</td>
      <td>also length</td>
    </tr>
    <tr>
      <td>vía de varios largos</td>
      <td>multi-pitch route</td>
      <td> </td>
    </tr>
    <tr>
      <td>bloque / búlder</td>
      <td>boulder problem</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada deportiva</td>
      <td>sport climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada clásica / tradicional / trad</td>
      <td>trad climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada artificial</td>
      <td>aid climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en hielo</td>
      <td>ice climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en placa</td>
      <td>slab climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en desplome</td>
      <td>overhang climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>primera repetición</td>
      <td>first repeat</td>
      <td> </td>
    </tr>
    <tr>
      <td>primera ascensión</td>
      <td>first ascent (FA)</td>
      <td> </td>
    </tr>
    <tr>
      <td>equipador</td>
      <td>route setter / bolter</td>
      <td>the person who bolted it</td>
    </tr>
  </tbody>
</table>

<h3 id="rope-management--roles-manejo-de-cuerda-y-roles">Rope Management &amp; Roles (Manejo de Cuerda y Roles)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>escalador / escaladora</td>
      <td>climber</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurador / aseguradora</td>
      <td>belayer</td>
      <td> </td>
    </tr>
    <tr>
      <td>primero / ir de primero</td>
      <td>leader / to lead</td>
      <td>“go first”</td>
    </tr>
    <tr>
      <td>segundo / ir de segundo</td>
      <td>second / follow</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordada</td>
      <td>rope team / partnership</td>
      <td> </td>
    </tr>
    <tr>
      <td>compañero de cordada</td>
      <td>climbing partner</td>
      <td> </td>
    </tr>
    <tr>
      <td>encordarse</td>
      <td>to tie in</td>
      <td> </td>
    </tr>
    <tr>
      <td>encordado</td>
      <td>tied in</td>
      <td> </td>
    </tr>
    <tr>
      <td>atarse a la cuerda</td>
      <td>to tie into the rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>puntos de encordamiento</td>
      <td>tie-in points</td>
      <td> </td>
    </tr>
    <tr>
      <td>en polea / top rope</td>
      <td>top rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>polea</td>
      <td>top rope (the setup)</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapar</td>
      <td>to clip</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapada en Z</td>
      <td>Z-clip</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapada al revés / back-clip</td>
      <td>back-clip</td>
      <td>dangerous!</td>
    </tr>
    <tr>
      <td>rozamiento</td>
      <td>rope drag</td>
      <td> </td>
    </tr>
    <tr>
      <td>estirar / extender la cuerda</td>
      <td>to flake the rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>recoger la cuerda</td>
      <td>to coil the rope / pull rope in</td>
      <td> </td>
    </tr>
    <tr>
      <td>plegado en mariposa</td>
      <td>butterfly coil</td>
      <td> </td>
    </tr>
    <tr>
      <td>montar reunión</td>
      <td>to build the anchor</td>
      <td> </td>
    </tr>
    <tr>
      <td>limpiar (la vía)</td>
      <td>to clean the route</td>
      <td>retrieve gear at the top</td>
    </tr>
    <tr>
      <td>recoger</td>
      <td>to clean / strip</td>
      <td>also “take in rope” — context</td>
    </tr>
    <tr>
      <td>pasar la cuerda (por la cadena)</td>
      <td>to thread the rope</td>
      <td>through the chains</td>
    </tr>
    <tr>
      <td>rapelar / hacer rápel</td>
      <td>to rappel / abseil</td>
      <td> </td>
    </tr>
    <tr>
      <td>rápel</td>
      <td>rappel / abseil</td>
      <td> </td>
    </tr>
    <tr>
      <td>descender / bajar</td>
      <td>to lower / descend</td>
      <td> </td>
    </tr>
    <tr>
      <td>descenso</td>
      <td>the descent</td>
      <td> </td>
    </tr>
    <tr>
      <td>parar una caída</td>
      <td>to catch a fall</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurar suave</td>
      <td>to give a soft catch</td>
      <td> </td>
    </tr>
    <tr>
      <td>factor de caída</td>
      <td>fall factor</td>
      <td> </td>
    </tr>
    <tr>
      <td>segurísimo / chapas nuevas</td>
      <td>well-bolted / new bolts</td>
      <td>bomber bolts</td>
    </tr>
    <tr>
      <td>equipamiento dudoso</td>
      <td>sketchy gear / runout</td>
      <td> </td>
    </tr>
    <tr>
      <td>corrido / muy corrido</td>
      <td>runout</td>
      <td>long distance between bolts</td>
    </tr>
    <tr>
      <td>abandonar / bajarse</td>
      <td>to bail</td>
      <td>retreat</td>
    </tr>
  </tbody>
</table>

<hr />]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Climbing Vocabulary — Spanish ⇄ English]]></summary></entry><entry><title type="html">Rock Climbing vocab in Spanish</title><link href="https://jeromegill.com/blog/climbing-vocab-mistral/" rel="alternate" type="text/html" title="Rock Climbing vocab in Spanish" /><published>2026-05-18T00:00:00+00:00</published><updated>2026-05-18T00:00:00+00:00</updated><id>https://jeromegill.com/blog/climbing-vocab-mistral</id><content type="html" xml:base="https://jeromegill.com/blog/climbing-vocab-mistral/"><![CDATA[<p>I live in spain, and often forget very specific and coloquial words for things when climbing with spanish friends. This can range from annoying, when I don’t understand beta or move sequences people are describing to me, to problematic when there is a situation that needs solving.</p>

<p>I’ve been using Anki to improve my spanish lately, and it’s going well. A friend mentioned about building his own deck of construction related vocab, so I thought it would be good for me to solidify some of the niche vocab I use in climbing.</p>

<p>I couldn’t find anything particularly complete online so had a go with mistral’s lechat research mode.</p>

<p>The following prompt complied this list from about 15 sources which is much more complete than anything I found on google.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Provide a complete list of climbing vocabulary in spanish with english translations in markdown format

Include;

rock features (crimp, jug, corner/dihedral, arete, etc)
techniques (flag, drop knee, cross through etc)
equipment (sport and trad, crabiner, quickdraw do not worry about alpine or ice etc)
Useful phrases (knots, grades, encouramgent, rope management, etc)
</code></pre></div></div>

<p>I think generally research tasks by LLMs are worth publishing so they can get indexed by search engines, if they are accurate and useful. The problem is that these produced by mistral aren’t great. There’s a bunch of things here, techniques especially, climbers would never say.</p>

<p>Unfortunately. Mistral continues to disappoint as someone who would value decoupling from US based tech where possible, given the current situation.</p>

<p>I decided to run the same prompt again using claude. The results were a big step up.</p>

<p>I’m going to manually clean up the list and get some friends to contribute translations. Once I’ve done that, next step is to get it into an anki format. Then I’ll make a little climbing vocab app.</p>

<h1 id="mistral">Mistral</h1>

<h2 id="-rock-features">🧗 Rock Features</h2>

<p>Rock features are the physical characteristics of the climbing surface that climbers interact with. Understanding these terms in Spanish is fundamental for route description, beta sharing, and climbing communication.</p>

<table>
  <thead>
    <tr>
      <th>English</th>
      <th>Spanish</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Crimp</td>
      <td>Regleta</td>
      <td>Small edge for fingertips.</td>
    </tr>
    <tr>
      <td>Jug</td>
      <td>Cazo / Presa grande</td>
      <td>Large, deep hold.</td>
    </tr>
    <tr>
      <td>Corner/Dihedral</td>
      <td>Diedro</td>
      <td>Inside corner where two rock planes meet.</td>
    </tr>
    <tr>
      <td>Arete</td>
      <td>Arista / Canto</td>
      <td>Edge or corner of a rock face.</td>
    </tr>
    <tr>
      <td>Edge</td>
      <td>Canto</td>
      <td>Narrow, flat hold.</td>
    </tr>
    <tr>
      <td>Sloper</td>
      <td>Romo / Placa lisa</td>
      <td>Rounded, sloping hold.</td>
    </tr>
    <tr>
      <td>Pinch</td>
      <td>Pinza</td>
      <td>Hold squeezed between thumb and fingers.</td>
    </tr>
    <tr>
      <td>Undercling</td>
      <td>Invertido</td>
      <td>Hold gripped from underneath.</td>
    </tr>
    <tr>
      <td>Chimney</td>
      <td>Chimenea</td>
      <td>Vertical passage in the rock.</td>
    </tr>
    <tr>
      <td>Slab</td>
      <td>Placa</td>
      <td>Less-than-vertical wall.</td>
    </tr>
    <tr>
      <td>Overhang</td>
      <td>Desplome</td>
      <td>Rock jutting out beyond vertical.</td>
    </tr>
    <tr>
      <td>Roof</td>
      <td>Techo</td>
      <td>Horizontal or near-horizontal overhang.</td>
    </tr>
    <tr>
      <td>Crack</td>
      <td>Fisura</td>
      <td>Fissure in the rock.</td>
    </tr>
    <tr>
      <td>Pocket</td>
      <td>Monodedo / Bidedo</td>
      <td>Small hole (1 or 2 fingers).</td>
    </tr>
    <tr>
      <td>Prow</td>
      <td>Proa</td>
      <td>Pointed or protruding rock feature.</td>
    </tr>
    <tr>
      <td>Ledge</td>
      <td>Repisa</td>
      <td>Flat or horizontal section of rock.</td>
    </tr>
    <tr>
      <td>Traverse</td>
      <td>Travesía</td>
      <td>Horizontal movement across a face.</td>
    </tr>
    <tr>
      <td>Highball</td>
      <td>Tsunami</td>
      <td>Tall boulder problem.</td>
    </tr>
    <tr>
      <td>Lowball</td>
      <td>Chincheta</td>
      <td>Short boulder problem.</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-climbing-techniques">🤸 Climbing Techniques</h2>

<p>Climbing techniques describe the methods and movements climbers use to ascend rock faces. Mastery of these terms in Spanish facilitates clear communication about climbing style and strategy.</p>

<table>
  <thead>
    <tr>
      <th>English</th>
      <th>Spanish</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Flagging</td>
      <td>Bandera / Bailarina</td>
      <td>Leg extended for balance.</td>
    </tr>
    <tr>
      <td>Drop Knee</td>
      <td>Rodilla caída / Bicicleta</td>
      <td>Dropping knee to twist hips closer.</td>
    </tr>
    <tr>
      <td>Cross Over</td>
      <td>Cruzar / Paso cruzado</td>
      <td>Arm crosses over to reach a hold.</td>
    </tr>
    <tr>
      <td>Deadpoint</td>
      <td>Punto muerto</td>
      <td>Dynamic move to grab a hold at apex.</td>
    </tr>
    <tr>
      <td>Dyno</td>
      <td>Dinámico</td>
      <td>Jumping for an out-of-reach hold.</td>
    </tr>
    <tr>
      <td>Heel Hook</td>
      <td>Gancho de talón</td>
      <td>Hooking heel onto a hold.</td>
    </tr>
    <tr>
      <td>Toe Hook</td>
      <td>Gancho de punta</td>
      <td>Hooking toes onto a hold.</td>
    </tr>
    <tr>
      <td>Back-step</td>
      <td>Paso atrás</td>
      <td>Using outside edge of foot on a hold.</td>
    </tr>
    <tr>
      <td>Campusing</td>
      <td>Campusing</td>
      <td>Climbing without using feet.</td>
    </tr>
    <tr>
      <td>Chimneying</td>
      <td>Chimenea</td>
      <td>Climbing a vertical crack.</td>
    </tr>
    <tr>
      <td>Stemming</td>
      <td>Stemming</td>
      <td>Pushing against opposite walls.</td>
    </tr>
    <tr>
      <td>Bridging</td>
      <td>Puente</td>
      <td>Using arms/legs to bridge between holds.</td>
    </tr>
    <tr>
      <td>Figure-Four</td>
      <td>Figura cuatro</td>
      <td>Leg hooked over opposite arm.</td>
    </tr>
    <tr>
      <td>Figure-Nine</td>
      <td>Figura nueve</td>
      <td>Same-side leg used.</td>
    </tr>
    <tr>
      <td>Finger Jam</td>
      <td>Bloqueo de dedos</td>
      <td>Jamming fingers into a crack.</td>
    </tr>
    <tr>
      <td>Fist Jam</td>
      <td>Bloqueo de puño</td>
      <td>Jamming hand into a crack.</td>
    </tr>
    <tr>
      <td>Foot Jam</td>
      <td>Bloqueo de pie</td>
      <td>Twisting foot into a wide crack.</td>
    </tr>
    <tr>
      <td>Hand Jam</td>
      <td>Bloqueo de mano</td>
      <td>Jamming hand into a crack.</td>
    </tr>
    <tr>
      <td>Knee Bar</td>
      <td>Barra de rodilla</td>
      <td>Wedging knee against a hold.</td>
    </tr>
    <tr>
      <td>Chest Jam</td>
      <td>Bloqueo de pecho</td>
      <td>Jamming torso into a wide crack.</td>
    </tr>
    <tr>
      <td>Arm Bar</td>
      <td>Barra de brazo</td>
      <td>Locking arm into a crack.</td>
    </tr>
    <tr>
      <td>Egyptian Bridging</td>
      <td>Puente egipcio</td>
      <td>One leg in front, one behind.</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-equipment">🎒 Equipment</h2>

<p>Equipment terminology is crucial for climbers to communicate about gear, safety, and climbing setup, especially in sport and trad climbing contexts.</p>

<table>
  <thead>
    <tr>
      <th>English</th>
      <th>Spanish</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Carabiner</td>
      <td>Mosquetón</td>
      <td>Metal loop with a gate.</td>
    </tr>
    <tr>
      <td>Quickdraw</td>
      <td>Cinta exprés</td>
      <td>Pre-attached sling + carabiner.</td>
    </tr>
    <tr>
      <td>Climbing Shoes</td>
      <td>Pies de gato / Zarpas</td>
      <td>Specialized rubber-soled shoes.</td>
    </tr>
    <tr>
      <td>Harness</td>
      <td>Arnés</td>
      <td>Waist/leg straps for securing to a rope.</td>
    </tr>
    <tr>
      <td>Helmet</td>
      <td>Casco</td>
      <td>Protective headgear.</td>
    </tr>
    <tr>
      <td>Rope</td>
      <td>Cuerda</td>
      <td>Static or dynamic rope.</td>
    </tr>
    <tr>
      <td>Belay Device</td>
      <td>Asegurador</td>
      <td>Device to control rope during belaying.</td>
    </tr>
    <tr>
      <td>Cams</td>
      <td>Friends / Empotradores</td>
      <td>Spring-loaded devices for trad climbing.</td>
    </tr>
    <tr>
      <td>Nuts</td>
      <td>Nuts / Chocks</td>
      <td>Passive protection for cracks.</td>
    </tr>
    <tr>
      <td>Slings</td>
      <td>Cintas</td>
      <td>Nylon/Dyneema loops for extending gear.</td>
    </tr>
    <tr>
      <td>Tricams</td>
      <td>Tricams</td>
      <td>Hybrid cam/nut devices.</td>
    </tr>
    <tr>
      <td>Ball Nuts</td>
      <td>Ball Nuts</td>
      <td>For thin cracks.</td>
    </tr>
    <tr>
      <td>Big Bros</td>
      <td>Big Bros</td>
      <td>Expandable tubes for wide cracks.</td>
    </tr>
    <tr>
      <td>Nut Tool</td>
      <td>Herramienta para nuts</td>
      <td>Tool to remove stuck gear.</td>
    </tr>
    <tr>
      <td>Cordelette</td>
      <td>Cordelette</td>
      <td>Long sling for equalizing anchors.</td>
    </tr>
    <tr>
      <td>Prusik Cord</td>
      <td>Cordino / Cuerda Prusik</td>
      <td>Cord for ascending or backup knots.</td>
    </tr>
    <tr>
      <td>Hexes</td>
      <td>Hexes</td>
      <td>Large passive protection.</td>
    </tr>
    <tr>
      <td>Bolting Equipment</td>
      <td>Equipo de anclaje</td>
      <td>Gear for placing permanent bolts.</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="-useful-phrases">💬 Useful Phrases</h2>

<p>Effective communication on the crag requires knowledge of common climbing phrases, including commands, encouragement, and technical terms related to knots and grades.</p>

<table>
  <thead>
    <tr>
      <th>English</th>
      <th>Spanish</th>
      <th>Context</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>Commands</strong></td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Give me rope!</td>
      <td>¡Dame cuerda!</td>
      <td>Asking for slack.</td>
    </tr>
    <tr>
      <td>Take in!</td>
      <td>¡Píllame! / ¡Recoge!</td>
      <td>Asking belayer to take in slack.</td>
    </tr>
    <tr>
      <td>I’m climbing.</td>
      <td>¡Voy!</td>
      <td>Starting or continuing a climb.</td>
    </tr>
    <tr>
      <td>Climb when ready.</td>
      <td>Escalada, vamos.</td>
      <td>Belayer’s signal to start.</td>
    </tr>
    <tr>
      <td>Below! / Down!</td>
      <td>¡Abajo!</td>
      <td>Warning for falling objects.</td>
    </tr>
    <tr>
      <td>Lower me.</td>
      <td>¡Bájame!</td>
      <td>Request to be lowered.</td>
    </tr>
    <tr>
      <td>I’m off! (falling)</td>
      <td>¡Me caigo! / ¡Vuelo!</td>
      <td>Warning that you’re falling.</td>
    </tr>
    <tr>
      <td><strong>Encouragement</strong></td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Good luck!</td>
      <td>¡Buena suerte!</td>
      <td>General encouragement.</td>
    </tr>
    <tr>
      <td>You’ve got this!</td>
      <td>¡Tú puedes! / ¡Vas bien!</td>
      <td>Motivational phrase.</td>
    </tr>
    <tr>
      <td>Almost there!</td>
      <td>¡Casi! / ¡Ya falta poco!</td>
      <td>Near the top or crux.</td>
    </tr>
    <tr>
      <td><strong>Knots</strong></td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Figure-eight knot</td>
      <td>Nudo de ocho</td>
      <td>Tie-in knot for harness.</td>
    </tr>
    <tr>
      <td>Double figure-eight</td>
      <td>Ocho doble</td>
      <td>Secure tie-in knot.</td>
    </tr>
    <tr>
      <td>Overhand knot</td>
      <td>Nudo llano / Nudo simple</td>
      <td>Basic knot.</td>
    </tr>
    <tr>
      <td>Prusik knot</td>
      <td>Nudo Prusik</td>
      <td>Friction hitch for ascending.</td>
    </tr>
    <tr>
      <td><strong>Grades</strong></td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Grade 4 (easy)</td>
      <td>Grado 4 (fácil)</td>
      <td>Beginner route.</td>
    </tr>
    <tr>
      <td>Grade 6a (harder)</td>
      <td>Grado 6a</td>
      <td>Intermediate route.</td>
    </tr>
    <tr>
      <td>Grade 9a (very hard)</td>
      <td>Grado 9a</td>
      <td>Advanced route.</td>
    </tr>
    <tr>
      <td>V4 (bouldering)</td>
      <td>V4 / Problema V4</td>
      <td>Bouldering grade.</td>
    </tr>
    <tr>
      <td><strong>Other</strong></td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>What’s the grade?</td>
      <td>¿Qué grado tiene?</td>
      <td>Asking about route difficulty.</td>
    </tr>
    <tr>
      <td>Do you have a quickdraw?</td>
      <td>¿Tienes una cinta exprés?</td>
      <td>Asking for gear.</td>
    </tr>
    <tr>
      <td>I need help with belay.</td>
      <td>Necesito ayuda para asegurar.</td>
      <td>Requesting assistance.</td>
    </tr>
    <tr>
      <td>Let’s go climbing!</td>
      <td>¡Vamos a escalar!</td>
      <td>Invitation to climb.</td>
    </tr>
    <tr>
      <td>Bolt</td>
      <td>Chapa</td>
      <td>Permanent anchor point.</td>
    </tr>
    <tr>
      <td>To clip a bolt</td>
      <td>Chapear</td>
      <td>Clipping the rope into a bolt.</td>
    </tr>
    <tr>
      <td>Hang on the rope</td>
      <td>Colgarse</td>
      <td>Resting on the rope.</td>
    </tr>
    <tr>
      <td>Try hard!</td>
      <td>¡A muerte! / ¡Dale con todo!</td>
      <td>Encouragement to push limits.</td>
    </tr>
    <tr>
      <td>I’m tired.</td>
      <td>Estoy cansado/a.</td>
      <td>Need a break.</td>
    </tr>
    <tr>
      <td>I made it!</td>
      <td>¡Lo logré! / ¡Encadené!</td>
      <td>Completed the route.</td>
    </tr>
  </tbody>
</table>

<h1 id="claude">Claude</h1>

<h2 id="rock-features-características-de-la-roca">Rock Features (Características de la Roca)</h2>

<h3 id="holds-presas--agarres">Holds (Presas / Agarres)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>presa / agarre</td>
      <td>hold</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>regleta</td>
      <td>crimp</td>
      <td>small edge for fingertips</td>
    </tr>
    <tr>
      <td>regletilla / microregleta</td>
      <td>micro-crimp</td>
      <td>tiny crimp</td>
    </tr>
    <tr>
      <td>canto</td>
      <td>edge</td>
      <td>flat edge</td>
    </tr>
    <tr>
      <td>romo / bola</td>
      <td>sloper</td>
      <td>rounded, friction-dependent</td>
    </tr>
    <tr>
      <td>pinza</td>
      <td>pinch</td>
      <td> </td>
    </tr>
    <tr>
      <td>bidedo</td>
      <td>two-finger pocket</td>
      <td>“two-finger”</td>
    </tr>
    <tr>
      <td>monodedo</td>
      <td>mono / one-finger pocket</td>
      <td> </td>
    </tr>
    <tr>
      <td>tridedo</td>
      <td>three-finger pocket</td>
      <td> </td>
    </tr>
    <tr>
      <td>hueco / agujero</td>
      <td>pocket / hueco</td>
      <td> </td>
    </tr>
    <tr>
      <td>bidón / cubo</td>
      <td>jug / bucket</td>
      <td>big, comfy hold</td>
    </tr>
    <tr>
      <td>presa cubo</td>
      <td>jug</td>
      <td> </td>
    </tr>
    <tr>
      <td>escama</td>
      <td>flake</td>
      <td> </td>
    </tr>
    <tr>
      <td>lateral / presa lateral</td>
      <td>sidepull</td>
      <td> </td>
    </tr>
    <tr>
      <td>invertido / presa invertida</td>
      <td>undercling</td>
      <td> </td>
    </tr>
    <tr>
      <td>gastón</td>
      <td>gaston</td>
      <td>thumb-down sidepull</td>
    </tr>
    <tr>
      <td>chuleta / bolo</td>
      <td>knob / chickenhead</td>
      <td>protruding feature</td>
    </tr>
    <tr>
      <td>presa de pie</td>
      <td>foothold</td>
      <td> </td>
    </tr>
    <tr>
      <td>repié / pie</td>
      <td>foothold</td>
      <td>small foothold</td>
    </tr>
  </tbody>
</table>

<h3 id="wall-features-características-de-la-pared">Wall Features (Características de la Pared)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>pared / muro</td>
      <td>wall / face</td>
      <td> </td>
    </tr>
    <tr>
      <td>placa</td>
      <td>slab</td>
      <td>less-than-vertical</td>
    </tr>
    <tr>
      <td>vertical</td>
      <td>vertical</td>
      <td> </td>
    </tr>
    <tr>
      <td>desplome</td>
      <td>overhanging wall</td>
      <td> </td>
    </tr>
    <tr>
      <td>extraplomo</td>
      <td>steep overhang</td>
      <td> </td>
    </tr>
    <tr>
      <td>techo</td>
      <td>roof</td>
      <td>horizontal</td>
    </tr>
    <tr>
      <td>panza / barriga</td>
      <td>bulge</td>
      <td> </td>
    </tr>
    <tr>
      <td>diedro</td>
      <td>dihedral / corner</td>
      <td>open-book</td>
    </tr>
    <tr>
      <td>arista</td>
      <td>arête</td>
      <td>outside corner</td>
    </tr>
    <tr>
      <td>fisura</td>
      <td>crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de dedos</td>
      <td>finger crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de manos</td>
      <td>hand crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura de puños</td>
      <td>fist crack</td>
      <td> </td>
    </tr>
    <tr>
      <td>fisura ancha</td>
      <td>off-width</td>
      <td> </td>
    </tr>
    <tr>
      <td>chimenea</td>
      <td>chimney</td>
      <td> </td>
    </tr>
    <tr>
      <td>veta / hendidura</td>
      <td>seam</td>
      <td>very thin crack</td>
    </tr>
    <tr>
      <td>repisa</td>
      <td>ledge</td>
      <td> </td>
    </tr>
    <tr>
      <td>reposadero</td>
      <td>rest ledge</td>
      <td>good resting spot</td>
    </tr>
    <tr>
      <td>estalactita</td>
      <td>tufa / stalactite</td>
      <td>classic limestone feature</td>
    </tr>
    <tr>
      <td>columna</td>
      <td>column / pillar / tufa</td>
      <td> </td>
    </tr>
    <tr>
      <td>pilar</td>
      <td>pillar</td>
      <td> </td>
    </tr>
    <tr>
      <td>bloque</td>
      <td>boulder</td>
      <td>also generic block</td>
    </tr>
    <tr>
      <td>acantilado</td>
      <td>cliff / sea cliff</td>
      <td> </td>
    </tr>
    <tr>
      <td>sector</td>
      <td>sector / area of crag</td>
      <td> </td>
    </tr>
    <tr>
      <td>escuela</td>
      <td>crag</td>
      <td>“climbing school” — single-pitch sport crag</td>
    </tr>
    <tr>
      <td>zona de escalada</td>
      <td>climbing area</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="techniques-técnicas">Techniques (Técnicas)</h2>

<h3 id="foot-techniques-técnicas-de-pie">Foot Techniques (Técnicas de Pie)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>cantear</td>
      <td>to edge</td>
      <td>use the edge of the shoe</td>
    </tr>
    <tr>
      <td>adherencia</td>
      <td>smearing</td>
      <td>friction on the shoe sole</td>
    </tr>
    <tr>
      <td>talonamiento / gancho de talón</td>
      <td>heel hook</td>
      <td> </td>
    </tr>
    <tr>
      <td>punteo / gancho de puntera</td>
      <td>toe hook</td>
      <td> </td>
    </tr>
    <tr>
      <td>rodilla baja / egipcio</td>
      <td>drop knee / Egyptian</td>
      <td> </td>
    </tr>
    <tr>
      <td>bandera</td>
      <td>flag</td>
      <td>counter-balancing leg</td>
    </tr>
    <tr>
      <td>bandera interior</td>
      <td>inside flag</td>
      <td> </td>
    </tr>
    <tr>
      <td>bandera exterior</td>
      <td>outside flag</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de pie</td>
      <td>foot jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>rodillazo / kneebar</td>
      <td>knee bar</td>
      <td> </td>
    </tr>
    <tr>
      <td>oposición / puente</td>
      <td>stemming / bridging</td>
      <td> </td>
    </tr>
    <tr>
      <td>sacar pies</td>
      <td>to move the feet up</td>
      <td>literally “take feet out”</td>
    </tr>
  </tbody>
</table>

<h3 id="hand--body-techniques-técnicas-de-mano-y-cuerpo">Hand / Body Techniques (Técnicas de Mano y Cuerpo)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>bloqueo / bloquear</td>
      <td>lock-off</td>
      <td> </td>
    </tr>
    <tr>
      <td>cruce / cruzar</td>
      <td>cross-through</td>
      <td> </td>
    </tr>
    <tr>
      <td>lance / lance dinámico</td>
      <td>dyno</td>
      <td>dynamic move</td>
    </tr>
    <tr>
      <td>dyno</td>
      <td>dyno</td>
      <td>also used as-is</td>
    </tr>
    <tr>
      <td>punto muerto</td>
      <td>deadpoint</td>
      <td>controlled dynamic</td>
    </tr>
    <tr>
      <td>igualar / juntar</td>
      <td>to match</td>
      <td>hands or feet</td>
    </tr>
    <tr>
      <td>rebote / repique</td>
      <td>bump</td>
      <td>move from hold to hold quickly</td>
    </tr>
    <tr>
      <td>mantle / manteo</td>
      <td>mantle</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotrar / empotre</td>
      <td>jam / jamming</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de mano</td>
      <td>hand jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotre de dedo</td>
      <td>finger jam</td>
      <td> </td>
    </tr>
    <tr>
      <td>bicicleta</td>
      <td>layback (sometimes)</td>
      <td>also “scissor / bicycle” pedal move</td>
    </tr>
    <tr>
      <td>oposición de fuerza</td>
      <td>layback</td>
      <td>classic layback in a corner</td>
    </tr>
    <tr>
      <td>chimenear</td>
      <td>chimneying</td>
      <td> </td>
    </tr>
    <tr>
      <td>figura cuatro</td>
      <td>figure four</td>
      <td> </td>
    </tr>
    <tr>
      <td>figura ocho</td>
      <td>figure eight</td>
      <td> </td>
    </tr>
    <tr>
      <td>campus</td>
      <td>campus</td>
      <td>climbing without feet</td>
    </tr>
    <tr>
      <td>escalar a campus</td>
      <td>to campus</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en bloque / búlder</td>
      <td>bouldering</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="style--tactics-estilo-y-táctica">Style / Tactics (Estilo y Táctica)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>encadenar</td>
      <td>to send</td>
      <td>climb clean</td>
    </tr>
    <tr>
      <td>encadene</td>
      <td>a send / a redpoint</td>
      <td> </td>
    </tr>
    <tr>
      <td>a vista</td>
      <td>onsight</td>
      <td>first try, no info</td>
    </tr>
    <tr>
      <td>flash</td>
      <td>flash</td>
      <td>first try, with info</td>
    </tr>
    <tr>
      <td>ensayar</td>
      <td>to work / rehearse</td>
      <td> </td>
    </tr>
    <tr>
      <td>pegada / intento</td>
      <td>attempt / try / go</td>
      <td> </td>
    </tr>
    <tr>
      <td>proyecto / “el proyecto”</td>
      <td>project</td>
      <td> </td>
    </tr>
    <tr>
      <td>beta / secuencia</td>
      <td>beta / sequence</td>
      <td> </td>
    </tr>
    <tr>
      <td>paso clave / crux</td>
      <td>crux</td>
      <td>hardest move</td>
    </tr>
    <tr>
      <td>bombear / hinchar</td>
      <td>to pump out</td>
      <td> </td>
    </tr>
    <tr>
      <td>estar hinchado</td>
      <td>to be pumped</td>
      <td> </td>
    </tr>
    <tr>
      <td>congestión / hinchazón</td>
      <td>the pump</td>
      <td> </td>
    </tr>
    <tr>
      <td>colgar de la cuerda</td>
      <td>hangdog</td>
      <td>resting on the rope</td>
    </tr>
    <tr>
      <td>caer / volar</td>
      <td>to fall / take a whipper</td>
      <td> </td>
    </tr>
    <tr>
      <td>vuelo</td>
      <td>a fall (esp. a big one)</td>
      <td>“whipper”</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="equipment-material">Equipment (Material)</h2>

<h3 id="soft-goods-material-blando">Soft Goods (Material Blando)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>arnés</td>
      <td>harness</td>
      <td> </td>
    </tr>
    <tr>
      <td>anillo central / anillo de aseguramiento</td>
      <td>belay loop</td>
      <td> </td>
    </tr>
    <tr>
      <td>perneras</td>
      <td>leg loops</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda</td>
      <td>rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda simple</td>
      <td>single rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda doble</td>
      <td>half rope</td>
      <td>⚠️ “doble” in Spanish = half rope</td>
    </tr>
    <tr>
      <td>cuerda gemela</td>
      <td>twin rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda dinámica</td>
      <td>dynamic rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cuerda estática</td>
      <td>static rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>cinta / cinta exprés / exprés</td>
      <td>quickdraw</td>
      <td> </td>
    </tr>
    <tr>
      <td>cintas</td>
      <td>quickdraws (pl.) / slings</td>
      <td>context-dependent</td>
    </tr>
    <tr>
      <td>anillo de cinta</td>
      <td>sling / runner</td>
      <td> </td>
    </tr>
    <tr>
      <td>dyneema</td>
      <td>dyneema</td>
      <td> </td>
    </tr>
    <tr>
      <td>cinta tubular</td>
      <td>webbing / tubular tape</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordino</td>
      <td>cord / accessory cord</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordelette</td>
      <td>cordelette</td>
      <td>also borrowed as-is</td>
    </tr>
    <tr>
      <td>pies de gato</td>
      <td>climbing shoes</td>
      <td> </td>
    </tr>
    <tr>
      <td>magnesio</td>
      <td>chalk</td>
      <td> </td>
    </tr>
    <tr>
      <td>bolsa de magnesio</td>
      <td>chalk bag</td>
      <td> </td>
    </tr>
    <tr>
      <td>pof</td>
      <td>“pof” / pof bag</td>
      <td>pine resin (Fontainebleau-style, controversial)</td>
    </tr>
    <tr>
      <td>cepillo</td>
      <td>brush</td>
      <td>for cleaning holds</td>
    </tr>
    <tr>
      <td>colchoneta / crash pad</td>
      <td>crash pad</td>
      <td>bouldering</td>
    </tr>
    <tr>
      <td>casco</td>
      <td>helmet</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="hardware-material-metálico">Hardware (Material Metálico)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>mosquetón</td>
      <td>carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>mosquetón de seguridad</td>
      <td>locking carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>mosquetón HMS / pera</td>
      <td>HMS / pear-shaped carabiner</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta recta</td>
      <td>straight gate</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta curva</td>
      <td>bent gate</td>
      <td> </td>
    </tr>
    <tr>
      <td>puerta de alambre</td>
      <td>wiregate</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurador / aparato</td>
      <td>belay device</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>reverso / tubo</td>
      <td>tube-style belay device (ATC)</td>
      <td> </td>
    </tr>
    <tr>
      <td>GriGri</td>
      <td>GriGri</td>
      <td> </td>
    </tr>
    <tr>
      <td>autoblocante</td>
      <td>assisted-braking device</td>
      <td> </td>
    </tr>
    <tr>
      <td>ocho (de rapel)</td>
      <td>figure-8 descender</td>
      <td> </td>
    </tr>
    <tr>
      <td>maillón</td>
      <td>maillon / quicklink</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapa / plaqueta</td>
      <td>bolt hanger</td>
      <td>the visible plate</td>
    </tr>
    <tr>
      <td>parabolt</td>
      <td>expansion bolt</td>
      <td> </td>
    </tr>
    <tr>
      <td>químico / anclaje químico</td>
      <td>glue-in bolt</td>
      <td> </td>
    </tr>
    <tr>
      <td>anclaje</td>
      <td>anchor point / bolt</td>
      <td>generic</td>
    </tr>
    <tr>
      <td>reunión</td>
      <td>belay / anchor (the station)</td>
      <td> </td>
    </tr>
    <tr>
      <td>descuelgue / cadenas</td>
      <td>lower-off / chains</td>
      <td>top of sport route</td>
    </tr>
    <tr>
      <td>clavo / pitón</td>
      <td>piton</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="trad-gear-material-de-empotradores">Trad Gear (Material de Empotradores)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>empotrador</td>
      <td>nut / passive pro (generic)</td>
      <td> </td>
    </tr>
    <tr>
      <td>empotrador de cable / fisurero</td>
      <td>wired nut / stopper</td>
      <td> </td>
    </tr>
    <tr>
      <td>hexagonal / hexcentric</td>
      <td>hex</td>
      <td> </td>
    </tr>
    <tr>
      <td>tricam</td>
      <td>tricam</td>
      <td> </td>
    </tr>
    <tr>
      <td>friend / leva</td>
      <td>cam / camming device</td>
      <td>“friend” is universal</td>
    </tr>
    <tr>
      <td>friend dudoso</td>
      <td>marginal cam placement</td>
      <td>“dodgy friend”</td>
    </tr>
    <tr>
      <td>micro-friend</td>
      <td>micro cam</td>
      <td> </td>
    </tr>
    <tr>
      <td>ball nut</td>
      <td>ball nut</td>
      <td> </td>
    </tr>
    <tr>
      <td>offset</td>
      <td>offset (nut or cam)</td>
      <td> </td>
    </tr>
    <tr>
      <td>extractor / llave</td>
      <td>nut tool / nut key</td>
      <td> </td>
    </tr>
    <tr>
      <td>juego (de friends / de empotradores)</td>
      <td>rack</td>
      <td>“set”</td>
    </tr>
    <tr>
      <td>equipo</td>
      <td>full rack / setup</td>
      <td>broader</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="useful-phrases-frases-útiles">Useful Phrases (Frases Útiles)</h2>

<h3 id="belay-commands-voces-de-aseguramiento">Belay Commands (Voces de Aseguramiento)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>¿Aseguras? / ¿Listo?</td>
      <td>On belay? / Ready?</td>
      <td> </td>
    </tr>
    <tr>
      <td>Asegurando / Te aseguro</td>
      <td>Belaying / Belay on</td>
      <td> </td>
    </tr>
    <tr>
      <td>Escalando / Voy</td>
      <td>Climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>Cuando quieras / Adelante</td>
      <td>Climb on / Go ahead</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Cuerda!</td>
      <td>Slack! / Rope!</td>
      <td>“give me slack” — context</td>
    </tr>
    <tr>
      <td>Dame cuerda</td>
      <td>Give me slack</td>
      <td> </td>
    </tr>
    <tr>
      <td>Recoge</td>
      <td>Take in / up rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>Tensa</td>
      <td>Take! / Tension!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Tenso / Tengo</td>
      <td>I’ve got you (tight)</td>
      <td> </td>
    </tr>
    <tr>
      <td>¿Me tienes?</td>
      <td>Got me?</td>
      <td> </td>
    </tr>
    <tr>
      <td>Te tengo</td>
      <td>I’ve got you</td>
      <td> </td>
    </tr>
    <tr>
      <td>Bájame</td>
      <td>Lower me</td>
      <td> </td>
    </tr>
    <tr>
      <td>Voy a chapar</td>
      <td>Clipping</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Chapado!</td>
      <td>Clipped!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Caigo / ¡Voy!</td>
      <td>Falling!</td>
      <td> </td>
    </tr>
    <tr>
      <td>Libre / Estoy seguro</td>
      <td>Off belay / I’m safe</td>
      <td>“seguro” = safe/anchored</td>
    </tr>
    <tr>
      <td>Hasta mí</td>
      <td>That’s me (end of rope)</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Atento! / ¡Mira!</td>
      <td>Watch me!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Piedra!</td>
      <td>Rock!</td>
      <td>falling rock — warning</td>
    </tr>
    <tr>
      <td>¡Cuerda! (gritado desde arriba)</td>
      <td>Rope!</td>
      <td>warning when throwing rope</td>
    </tr>
  </tbody>
</table>

<h3 id="encouragement-ánimos">Encouragement (Ánimos)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>¡Vamos! / ¡Venga!</td>
      <td>Come on! / Let’s go!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tú puedes!</td>
      <td>You can do it!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tira!</td>
      <td>Pull!</td>
      <td>“go for it”</td>
    </tr>
    <tr>
      <td>¡Aguanta!</td>
      <td>Hold on!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Sigue! / ¡Arriba!</td>
      <td>Keep going! / Up!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Fuerza!</td>
      <td>Strength! / Power!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Empuja!</td>
      <td>Push!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Confía (en los pies)!</td>
      <td>Trust (your feet)!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Saca pies!</td>
      <td>Move your feet up!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Respira!</td>
      <td>Breathe!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Bien! / ¡Eso es!</td>
      <td>Good! / That’s it!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡A muerte!</td>
      <td>Full effort!</td>
      <td>“to the death”</td>
    </tr>
    <tr>
      <td>¡Vamos campeón / campeona!</td>
      <td>Let’s go champ!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Tira con huevos!</td>
      <td>Pull hard!</td>
      <td>vulgar but very common in Spain</td>
    </tr>
    <tr>
      <td>¡Crúzate!</td>
      <td>Cross!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Bloquea!</td>
      <td>Lock it off!</td>
      <td> </td>
    </tr>
    <tr>
      <td>¡Salta!</td>
      <td>Jump / dyno!</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="knots-nudos">Knots (Nudos)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>nudo</td>
      <td>knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de ocho / ocho</td>
      <td>figure-eight</td>
      <td> </td>
    </tr>
    <tr>
      <td>ocho doble / ocho de seguimiento</td>
      <td>figure-eight follow-through</td>
      <td>the tie-in knot</td>
    </tr>
    <tr>
      <td>nudo de nueve</td>
      <td>figure-nine</td>
      <td> </td>
    </tr>
    <tr>
      <td>as de guía</td>
      <td>bowline</td>
      <td> </td>
    </tr>
    <tr>
      <td>ballestrinque / nudo dinámico</td>
      <td>clove hitch</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo italiano / dinámico</td>
      <td>Munter hitch / Italian hitch</td>
      <td>UIAA hitch</td>
    </tr>
    <tr>
      <td>nudo prusik</td>
      <td>prusik knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>machard / prusik francés</td>
      <td>French prusik / autoblock</td>
      <td> </td>
    </tr>
    <tr>
      <td>klemheist</td>
      <td>klemheist</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de cinta</td>
      <td>water knot / tape knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>pescador doble</td>
      <td>double fisherman’s</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo simple</td>
      <td>overhand knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>nudo de tope / nudo de seguridad</td>
      <td>stopper knot / backup knot</td>
      <td> </td>
    </tr>
    <tr>
      <td>gaza / lazada</td>
      <td>loop / bight</td>
      <td> </td>
    </tr>
  </tbody>
</table>

<h3 id="grades-grados">Grades (Grados)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>grado</td>
      <td>grade</td>
      <td> </td>
    </tr>
    <tr>
      <td>vía</td>
      <td>route</td>
      <td> </td>
    </tr>
    <tr>
      <td>largo</td>
      <td>pitch</td>
      <td>also length</td>
    </tr>
    <tr>
      <td>vía de varios largos</td>
      <td>multi-pitch route</td>
      <td> </td>
    </tr>
    <tr>
      <td>bloque / búlder</td>
      <td>boulder problem</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada deportiva</td>
      <td>sport climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada clásica / tradicional / trad</td>
      <td>trad climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada artificial</td>
      <td>aid climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en hielo</td>
      <td>ice climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en placa</td>
      <td>slab climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>escalada en desplome</td>
      <td>overhang climbing</td>
      <td> </td>
    </tr>
    <tr>
      <td>primera repetición</td>
      <td>first repeat</td>
      <td> </td>
    </tr>
    <tr>
      <td>primera ascensión</td>
      <td>first ascent (FA)</td>
      <td> </td>
    </tr>
    <tr>
      <td>equipador</td>
      <td>route setter / bolter</td>
      <td>the person who bolted it</td>
    </tr>
  </tbody>
</table>

<h3 id="rope-management--roles-manejo-de-cuerda-y-roles">Rope Management &amp; Roles (Manejo de Cuerda y Roles)</h3>

<table>
  <thead>
    <tr>
      <th>Spanish</th>
      <th>English</th>
      <th>Notes</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>escalador / escaladora</td>
      <td>climber</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurador / aseguradora</td>
      <td>belayer</td>
      <td> </td>
    </tr>
    <tr>
      <td>primero / ir de primero</td>
      <td>leader / to lead</td>
      <td>“go first”</td>
    </tr>
    <tr>
      <td>segundo / ir de segundo</td>
      <td>second / follow</td>
      <td> </td>
    </tr>
    <tr>
      <td>cordada</td>
      <td>rope team / partnership</td>
      <td> </td>
    </tr>
    <tr>
      <td>compañero de cordada</td>
      <td>climbing partner</td>
      <td> </td>
    </tr>
    <tr>
      <td>encordarse</td>
      <td>to tie in</td>
      <td> </td>
    </tr>
    <tr>
      <td>encordado</td>
      <td>tied in</td>
      <td> </td>
    </tr>
    <tr>
      <td>atarse a la cuerda</td>
      <td>to tie into the rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>puntos de encordamiento</td>
      <td>tie-in points</td>
      <td> </td>
    </tr>
    <tr>
      <td>en polea / top rope</td>
      <td>top rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>polea</td>
      <td>top rope (the setup)</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapar</td>
      <td>to clip</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapada en Z</td>
      <td>Z-clip</td>
      <td> </td>
    </tr>
    <tr>
      <td>chapada al revés / back-clip</td>
      <td>back-clip</td>
      <td>dangerous!</td>
    </tr>
    <tr>
      <td>rozamiento</td>
      <td>rope drag</td>
      <td> </td>
    </tr>
    <tr>
      <td>estirar / extender la cuerda</td>
      <td>to flake the rope</td>
      <td> </td>
    </tr>
    <tr>
      <td>recoger la cuerda</td>
      <td>to coil the rope / pull rope in</td>
      <td> </td>
    </tr>
    <tr>
      <td>plegado en mariposa</td>
      <td>butterfly coil</td>
      <td> </td>
    </tr>
    <tr>
      <td>montar reunión</td>
      <td>to build the anchor</td>
      <td> </td>
    </tr>
    <tr>
      <td>limpiar (la vía)</td>
      <td>to clean the route</td>
      <td>retrieve gear at the top</td>
    </tr>
    <tr>
      <td>recoger</td>
      <td>to clean / strip</td>
      <td>also “take in rope” — context</td>
    </tr>
    <tr>
      <td>pasar la cuerda (por la cadena)</td>
      <td>to thread the rope</td>
      <td>through the chains</td>
    </tr>
    <tr>
      <td>rapelar / hacer rápel</td>
      <td>to rappel / abseil</td>
      <td> </td>
    </tr>
    <tr>
      <td>rápel</td>
      <td>rappel / abseil</td>
      <td> </td>
    </tr>
    <tr>
      <td>descender / bajar</td>
      <td>to lower / descend</td>
      <td> </td>
    </tr>
    <tr>
      <td>descenso</td>
      <td>the descent</td>
      <td> </td>
    </tr>
    <tr>
      <td>parar una caída</td>
      <td>to catch a fall</td>
      <td> </td>
    </tr>
    <tr>
      <td>asegurar suave</td>
      <td>to give a soft catch</td>
      <td> </td>
    </tr>
    <tr>
      <td>factor de caída</td>
      <td>fall factor</td>
      <td> </td>
    </tr>
    <tr>
      <td>segurísimo / chapas nuevas</td>
      <td>well-bolted / new bolts</td>
      <td>bomber bolts</td>
    </tr>
    <tr>
      <td>equipamiento dudoso</td>
      <td>sketchy gear / runout</td>
      <td> </td>
    </tr>
    <tr>
      <td>corrido / muy corrido</td>
      <td>runout</td>
      <td>long distance between bolts</td>
    </tr>
    <tr>
      <td>abandonar / bajarse</td>
      <td>to bail</td>
      <td>retreat</td>
    </tr>
  </tbody>
</table>

<hr />

<h2 id="a-few-notes-on-usage">A Few Notes on Usage</h2>

<ul>
  <li><strong>“Seguro”</strong> is overloaded. It means “safe”, “I’m anchored”, or “off belay” depending on context. Always confirm visually before taking someone off belay.</li>
  <li><strong>“Cuerda”</strong> can mean “slack!” (give me rope) or “rope!” (warning, rope coming down). Tone and context decide.</li>
  <li><strong>“Cuerda doble”</strong> in Spanish refers to a <em>half rope</em> (used as a pair on multi-pitch). Don’t confuse with “two ropes” in general English.</li>
  <li><strong>“Friend”</strong> is universal — Spanish climbers use the English word, often pronounced “frien”. The plural is <em>friends</em> (sometimes <em>friendes</em>).</li>
  <li>Latin American countries sometimes use slight variants: e.g. <em>cuerda</em> can be <em>soga</em> in some regions, <em>pies de gato</em> may be <em>gatos</em> or <em>zapatos de escalar</em>, <em>magnesio</em> is <em>carbonato</em> or <em>tiza</em> in parts of Latin America.</li>
  <li>Encouragement in Spain leans loud and informal. <em>¡Vamos!</em>, <em>¡Venga!</em>, and <em>¡Tira!</em> are universal — don’t worry about being too polite at the crag.</li>
</ul>

<p>¡Buena escalada!</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[I live in spain, and often forget very specific and coloquial words for things when climbing with spanish friends. This can range from annoying, when I don’t understand beta or move sequences people are describing to me, to problematic when there is a situation that needs solving.]]></summary></entry><entry><title type="html">Using shared fixtures to cement integration testing</title><link href="https://jeromegill.com/blog/fixtures/" rel="alternate" type="text/html" title="Using shared fixtures to cement integration testing" /><published>2026-04-16T00:00:00+00:00</published><updated>2026-04-16T00:00:00+00:00</updated><id>https://jeromegill.com/blog/fixtures</id><content type="html" xml:base="https://jeromegill.com/blog/fixtures/"><![CDATA[<p>Integration testing should be the bedrock of testing strategy. They are far easier to write and maintain than end to end tests, and far less fragile than unit.</p>

<p>They are essentially testing the points of interaction of your application, without testing the implementation.</p>

<p>For a standard API, an intergration test makes a HTTP call and checks the response is what you expect.</p>

<p>You might mock service dependencies, or even the DB itself, but the general idea is that if you have an integration test for an API call you can rest assured that it basically works.</p>

<p>This means you can safely mock that call in other parts of the stack. So a client integration test can use a mocked response for a given API route, as long as that route is tested elsewhere.</p>

<h2 id="the-problem">The Problem</h2>

<p>The issue you have is basically that the details of the integration matter. You can’t just send any body to a integration tested route and expect it to work.</p>

<p>We need some guarentee that if I send <em>this</em> request I will get <em>this</em> response.</p>

<p>A backend integration test that mocks out the real response, or a frontend test that hardcodes an expected payload, introduces a fixture that can go stale. The backend changes its response shape. The backend test passes (because it was updated). The frontend test passes (because it tests against a now-stale hardcoded mock).</p>

<p>The root cause in both cases is the same: the fixture that defines “what the API returns” exists in multiple places, and those places are not guaranteed to agree with each other.</p>

<h2 id="fixtures-should-be-a-package">Fixtures should be a package.</h2>

<p>Specifically: a single package that exports a typed object for every API route. Each object has two fields:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">req</code> — the canonical example of what a valid request looks like (happy path)</li>
  <li><code class="language-plaintext highlighter-rouge">res</code> — the subset of the response that every caller can rely on</li>
</ul>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// packages/fixtures/src/auth/sign-up.fixture.ts</span>
<span class="k">export</span> <span class="kd">const</span> <span class="nx">signUpFixture</span> <span class="o">=</span> <span class="p">{</span>
  <span class="na">req</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">email</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hello@example.com</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">password</span><span class="p">:</span> <span class="dl">"</span><span class="s2">1234!</span><span class="dl">"</span><span class="p">,</span>
    <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Sign Up User</span><span class="dl">"</span><span class="p">,</span>
  <span class="p">},</span>
  <span class="na">res</span><span class="p">:</span> <span class="p">{</span>
    <span class="na">user</span><span class="p">:</span> <span class="p">{</span>
      <span class="na">email</span><span class="p">:</span> <span class="dl">"</span><span class="s2">hello@example.com</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">name</span><span class="p">:</span> <span class="dl">"</span><span class="s2">Sign Up User</span><span class="dl">"</span><span class="p">,</span>
      <span class="na">emailVerified</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
    <span class="p">},</span>
  <span class="p">},</span>
<span class="p">};</span>
</code></pre></div></div>

<p>The API integration test uses this fixture to verify the API produces the right output:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">app</span><span class="p">.</span><span class="nf">getHttpServer</span><span class="p">())</span>
  <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-up/email</span><span class="dl">"</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>

<span class="nf">expect</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">body</span><span class="p">).</span><span class="nf">toMatchObject</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">res</span><span class="p">);</span>
</code></pre></div></div>

<p>The client test uses the same fixture to verify the client handles the output correctly — or uses <code class="language-plaintext highlighter-rouge">signUpFixture.req</code> as the input for a form test, knowing it represents valid data.</p>

<p>Neither side defines the shape independently. Both sides import from the same place. If the API changes <code class="language-plaintext highlighter-rouge">emailVerified</code> to <code class="language-plaintext highlighter-rouge">email_verified</code>, the fixture is updated, the API test fails, and the client test fails — at the same time, before anything reaches production.</p>

<hr />

<h2 id="what-the-package-contains">What the Package Contains</h2>

<p>Each route gets a directory with relevant fixture files.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>packages/fixtures/src/
  auth/
    sign-up.fixture.ts    ← { req, res }
  health/
    check.fixture.ts
</code></pre></div></div>

<p>The fixture file is pure data — no framework dependencies, no special types. It is importable by both the Node.js backend (in integration tests) and the browser frontend (in component tests or mocks).</p>

<p>The fixture covers only the happy path. Error scenarios are tested by mutating the fixture <code class="language-plaintext highlighter-rouge">req</code> inline in the test itself:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// The fixture gives us a valid baseline. For an error scenario,</span>
<span class="c1">// change only the field that makes it invalid.</span>
<span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-in/email</span><span class="dl">"</span><span class="p">)</span>
  <span class="p">.</span><span class="nf">send</span><span class="p">({</span> <span class="p">...</span><span class="nx">signInFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">,</span> <span class="na">password</span><span class="p">:</span> <span class="dl">"</span><span class="s2">WrongPassword123!</span><span class="dl">"</span> <span class="p">})</span>
  <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">401</span><span class="p">);</span>
</code></pre></div></div>

<p>This keeps the fixture focused and avoids a proliferation of named variants like <code class="language-plaintext highlighter-rouge">signUpFixtureWithMissingName</code> or <code class="language-plaintext highlighter-rouge">signInFixtureInvalidPassword</code>. The fixture describes what a real interaction looks like. Tests describe what happens when things go wrong.</p>

<hr />

<h2 id="the-full-integration-spec">The Full Integration Spec</h2>

<p>With the fixture and manager in place, an integration spec reads at a high level of abstraction. The data is elsewhere; the test expresses intent:</p>

<div class="language-ts highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">Auth (integration)</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">POST /api/auth/sign-up/email</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nf">it</span><span class="p">(</span><span class="dl">"</span><span class="s2">registers a new user</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-up/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>

      <span class="nf">expect</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">body</span><span class="p">).</span><span class="nf">toMatchObject</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">res</span><span class="p">);</span>
    <span class="p">});</span>

    <span class="nf">it</span><span class="p">(</span><span class="dl">"</span><span class="s2">rejects a duplicate email with 422</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-up/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">);</span>
      <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-up/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">422</span><span class="p">);</span>
    <span class="p">});</span>
  <span class="p">});</span>

  <span class="nf">describe</span><span class="p">(</span><span class="dl">"</span><span class="s2">POST /api/auth/sign-in/email</span><span class="dl">"</span><span class="p">,</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
    <span class="nf">beforeEach</span><span class="p">(</span><span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-up/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signUpFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">);</span>
    <span class="p">});</span>

    <span class="nf">it</span><span class="p">(</span><span class="dl">"</span><span class="s2">returns a session token for valid credentials</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="kd">const</span> <span class="nx">res</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-in/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="nx">signInFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span>

      <span class="nf">expect</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">body</span><span class="p">).</span><span class="nf">toMatchObject</span><span class="p">(</span><span class="nx">signInFixture</span><span class="p">.</span><span class="nx">res</span><span class="p">);</span>
      <span class="nf">expect</span><span class="p">(</span><span class="k">typeof</span> <span class="nx">res</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">token</span><span class="p">).</span><span class="nf">toBe</span><span class="p">(</span><span class="dl">"</span><span class="s2">string</span><span class="dl">"</span><span class="p">);</span>
    <span class="p">});</span>

    <span class="nf">it</span><span class="p">(</span><span class="dl">"</span><span class="s2">rejects wrong password with 401</span><span class="dl">"</span><span class="p">,</span> <span class="k">async </span><span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span>
      <span class="k">await</span> <span class="nf">request</span><span class="p">(</span><span class="nx">server</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">post</span><span class="p">(</span><span class="dl">"</span><span class="s2">/api/auth/sign-in/email</span><span class="dl">"</span><span class="p">)</span>
        <span class="p">.</span><span class="nf">send</span><span class="p">({</span> <span class="p">...</span><span class="nx">signInFixture</span><span class="p">.</span><span class="nx">req</span><span class="p">,</span> <span class="na">password</span><span class="p">:</span> <span class="dl">"</span><span class="s2">WrongPassword123!</span><span class="dl">"</span> <span class="p">})</span>
        <span class="p">.</span><span class="nf">expect</span><span class="p">(</span><span class="mi">401</span><span class="p">);</span>
    <span class="p">});</span>
  <span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>

<p>Note what’s absent: no inline JSON objects, no hardcoded email strings, no guessing at what the API returns. The fixture is the contract; the test verifies it.</p>

<hr />

<h2 id="the-boundary-guarantee">The Boundary Guarantee</h2>

<p>The goal of this pattern is not just organisational. The goal is to make the integration boundary between client and API <strong>impossible to silently violate</strong>.</p>

<p>Consider what happens without shared fixtures:</p>

<ol>
  <li>Backend developer changes the sign-up response to include <code class="language-plaintext highlighter-rouge">{ user: { verified: false } }</code> instead of <code class="language-plaintext highlighter-rouge">{ user: { emailVerified: false } }</code>.</li>
  <li>Backend integration test is updated to match.</li>
  <li>Frontend developer has a separate mock that returns <code class="language-plaintext highlighter-rouge">{ user: { emailVerified: false } }</code>.</li>
  <li>Frontend tests pass.</li>
  <li>Production: the client checks <code class="language-plaintext highlighter-rouge">response.user.emailVerified</code>, gets <code class="language-plaintext highlighter-rouge">undefined</code>.</li>
</ol>

<p>With shared fixtures:</p>

<ol>
  <li>Backend developer changes the response.</li>
  <li>They update <code class="language-plaintext highlighter-rouge">signUpFixture.res</code> in <code class="language-plaintext highlighter-rouge">fixtures</code>.</li>
  <li>The backend integration test still passes — it asserts against the updated fixture.</li>
  <li>Every frontend test that imports <code class="language-plaintext highlighter-rouge">signUpFixture</code> now fails because it was relying on <code class="language-plaintext highlighter-rouge">emailVerified</code>.</li>
  <li>The developer is forced to confront the frontend impact before pushing.</li>
</ol>

<p>The fixture update is the forcing function. It happens in one place and propagates everywhere. The failing frontend tests will need to be dealt with before you have a passing build. A bit annoying, maybe, but much less fragile.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Integration testing should be the bedrock of testing strategy. They are far easier to write and maintain than end to end tests, and far less fragile than unit.]]></summary></entry><entry><title type="html">Vibe porting and where agentic coding is going</title><link href="https://jeromegill.com/blog/vibe-porting/" rel="alternate" type="text/html" title="Vibe porting and where agentic coding is going" /><published>2026-03-27T00:00:00+00:00</published><updated>2026-03-27T00:00:00+00:00</updated><id>https://jeromegill.com/blog/vibe-porting</id><content type="html" xml:base="https://jeromegill.com/blog/vibe-porting/"><![CDATA[<p>Ive seen a few writeups like this lately. “Vibe porting”.</p>

<p><a href="https://blog.cloudflare.com/vinext/">https://blog.cloudflare.com/vinext/</a></p>

<p>Essentially cloudflare ported <em>most</em> of nextjs in order to be easier to deploy on their infrastructure. And faster, allegedly.</p>

<p>This quote from a similar project sums up what is really interesting about this for me.</p>

<blockquote>
  <p>The implementation details didn’t interest me that much (I don’t work on frontend frameworks), but the methodology did. They took the existing Next.js spec and test suite, then pointed AI at it and had it implement code until every test passed.</p>

  <p>– <cite><a href="https://www.reco.ai/blog/we-rewrote-jsonata-with-ai">https://www.reco.ai/blog/we-rewrote-jsonata-with-ai</a></cite></p>
</blockquote>

<p>LLMs are starting to sit in this fuzzy plane where they let you know less about what it is your asking for because they interpret language into code. Sometimes quite well.</p>

<p>There is a narrative that if you aren’t generating vast amounts of code there is some kind of skill issue, when the reality, as ever, is that coding isn’t really the bottleneck. Specifying is.</p>

<p>It’s an xkcd meme, I think, but sufficiently detailed specification is code itself. In other words, code exists to tell a computer exactly what you want it to do.</p>

<p>These absurdly productive projects are built quickly because the hard work of specification has been done already, in the form of integration tests.</p>

<p>I find the framing “we rebuilt such and such in an afternoon” obnoxious, given the tests and specs took years of thought and design, but it does say something important about the way agentic coding is going.</p>

<p>Basically agents achieving rapid reproduction of existing codebases thanks to them having very thorough test suites and operating in a true TDD fashion.</p>

<p>Essentially, hardcore TDD, of the kind we all read about in books like “extreme programming”, puts specification front and center and gives agents a framework in which to iterate.</p>

<p>The way I see things going is a return to BDD. It seems to me that <a href="https://cucumber.io/">cucumber.io</a> was built for this moment, and way ahead of it’s time.</p>

<p>I’ll be experimenting with this over the next few weeks, and see if it’s possible to “one shot” something by defining behaviour well up front.</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Ive seen a few writeups like this lately. “Vibe porting”.]]></summary></entry><entry><title type="html">Sanchez and spanish “socialism”</title><link href="https://jeromegill.com/blog/sanchez/" rel="alternate" type="text/html" title="Sanchez and spanish “socialism”" /><published>2026-03-07T00:00:00+00:00</published><updated>2026-03-07T00:00:00+00:00</updated><id>https://jeromegill.com/blog/sanchez</id><content type="html" xml:base="https://jeromegill.com/blog/sanchez/"><![CDATA[<p>Within Spain, <strong>Sánchez</strong> isn’t considered a socialist at all.
People here see him very much like <strong>Blair</strong>—at the right and a “modernising” figure of a historically left-wing party (<strong>PSOE</strong>) that has long abandoned “socialist” policy in order to be a kind of liberal, centrist election winner (usually by coalition).</p>

<p>The Spanish left basically <strong>hate him</strong> for selling them out at every opportunity.</p>

<p>Ironically, with elections in <strong>2027</strong>, he’s outflanking both the left and the right here.</p>

<p>Much like <strong>Farage/Badenoch</strong> in the UK, the nationalism of <strong>Vox</strong> and the far right seems to evaporate when they have to choose between national interest and isolationism—or selling everyone out for whatever <strong>Trump</strong> feels like on any given Tuesday.
Unfortunately, a lot of their base see through it. But some don’t.</p>

<p>By telling <strong>Trump to fuck off</strong>, he’s basically shut down the main angle of attack from across the political spectrum next year.</p>

<ul>
  <li>The right wants <strong>isolationism</strong> (as <strong>Meloni</strong>, interestingly, is able to pull off in Italy).</li>
  <li>The left wants <strong>absolutely nothing to do with Trump</strong> and his weird wars.</li>
</ul>

<p>It’s a mystery to me why more <strong>European and even global leaders</strong> don’t take this stance.
<strong>Cowardice</strong> over reliance on <strong>US contracts for defence via NATO</strong>, I guess…</p>]]></content><author><name>Jerome Gill</name></author><summary type="html"><![CDATA[Within Spain, Sánchez isn’t considered a socialist at all. People here see him very much like Blair—at the right and a “modernising” figure of a historically left-wing party (PSOE) that has long abandoned “socialist” policy in order to be a kind of liberal, centrist election winner (usually by coalition).]]></summary></entry></feed>