<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jean-Luc Martel</title>
    <description>The latest articles on DEV Community by Jean-Luc Martel (@jlmartel).</description>
    <link>https://dev.to/jlmartel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4061410%2Fc407a2f0-c9db-4796-bcf2-43f744536ee6.jpg</url>
      <title>DEV Community: Jean-Luc Martel</title>
      <link>https://dev.to/jlmartel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jlmartel"/>
    <language>en</language>
    <item>
      <title>Your AI Coding Agent Just Finished. Now Ask It to Attack Its Own Work.</title>
      <dc:creator>Jean-Luc Martel</dc:creator>
      <pubDate>Fri, 21 Aug 2026 01:39:27 +0000</pubDate>
      <link>https://dev.to/jlmartel/your-ai-coding-agent-just-finished-now-ask-it-to-attack-its-own-work-54g3</link>
      <guid>https://dev.to/jlmartel/your-ai-coding-agent-just-finished-now-ask-it-to-attack-its-own-work-54g3</guid>
      <description>&lt;p&gt;AI coding agents are remarkably good at getting from “here’s what I want” to “here’s a working implementation.”&lt;/p&gt;

&lt;p&gt;They are also remarkably good at being satisfied with what they just built.&lt;/p&gt;

&lt;p&gt;That second trait is a problem.&lt;/p&gt;

&lt;p&gt;One of the highest-leverage habits I’ve picked up when working with coding agents is surprisingly simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After the agent finishes a meaningful piece of work, ask it to perform an adversarial review of its own implementation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review your work and make sure everything looks good.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That tends to produce a polite little victory lap.&lt;/p&gt;

&lt;p&gt;Instead, change the objective.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Act as an adversarial reviewer. Assume this implementation contains subtle bugs, incorrect assumptions, security issues, race conditions, missing edge cases, or architectural problems. Your job is to find them. Do not defend the implementation. Try to break it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference can be dramatic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building and attacking are different tasks
&lt;/h2&gt;

&lt;p&gt;When an agent is implementing a feature, its working objective is roughly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find a plausible path to satisfying the requirements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once it has found that path, everything it sees is colored by the solution it just constructed.&lt;/p&gt;

&lt;p&gt;Humans do this too.&lt;/p&gt;

&lt;p&gt;You write a function, run the obvious tests, and your brain quietly becomes the function’s defense attorney.&lt;/p&gt;

&lt;p&gt;The code looks reasonable because you know what it was &lt;em&gt;supposed&lt;/em&gt; to do.&lt;/p&gt;

&lt;p&gt;An adversarial review gives the model a different role:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Assume the implementation is wrong. Find the evidence.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That changes what it searches for.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this satisfy the happy path?&lt;/li&gt;
&lt;li&gt;Does this compile?&lt;/li&gt;
&lt;li&gt;Did I implement the requested feature?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it starts asking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens with malformed input?&lt;/li&gt;
&lt;li&gt;What assumption did I make that the caller never promised?&lt;/li&gt;
&lt;li&gt;What happens under concurrency?&lt;/li&gt;
&lt;li&gt;Is this operation actually atomic?&lt;/li&gt;
&lt;li&gt;Can this fail halfway through?&lt;/li&gt;
&lt;li&gt;What happens when a dependency returns something unexpected?&lt;/li&gt;
&lt;li&gt;Did I introduce an authorization bypass?&lt;/li&gt;
&lt;li&gt;Did I preserve existing behavior?&lt;/li&gt;
&lt;li&gt;Is there a hidden performance cliff?&lt;/li&gt;
&lt;li&gt;Are the tests proving the behavior, or merely exercising the implementation?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same model. Same context. Very different search space.&lt;/p&gt;

&lt;h2&gt;
  
  
  The prompt I actually want
&lt;/h2&gt;

&lt;p&gt;Something like this works well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Perform an adversarial review of the implementation you just created.

Assume there are bugs.

Do not explain why the current implementation is good. Your job is to attack it.

Look specifically for:

- incorrect assumptions
- edge cases
- race conditions
- security vulnerabilities
- data corruption risks
- failure/retry problems
- backwards compatibility issues
- performance regressions
- missing validation
- incorrect error handling
- tests that pass without proving the intended behavior

For every issue you find:

1. Describe the failure mode.
2. Explain how it could occur in practice.
3. Rate its severity.
4. Point to the relevant code.
5. Propose a concrete fix.

Do not modify the code yet. First produce the review.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last instruction matters.&lt;/p&gt;

&lt;p&gt;I usually want the &lt;strong&gt;review before the repair&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you immediately ask the agent to “find and fix any problems,” it can silently patch things while skipping the explanation. Separating diagnosis from remediation makes the reasoning inspectable.&lt;/p&gt;

&lt;p&gt;It also lets you decide which findings are real.&lt;/p&gt;

&lt;p&gt;Because the agent can absolutely invent problems too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make it argue against itself
&lt;/h2&gt;

&lt;p&gt;For larger changes, I sometimes push this further and create two explicit roles.&lt;/p&gt;

&lt;p&gt;First:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are the implementation engineer. Complete the feature.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are now a senior engineer reviewing this change before production deployment.

You did not write this code.

Assume the implementation engineer was competent but may have made subtle mistakes.

Try to reject this change.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The phrase &lt;strong&gt;“You did not write this code”&lt;/strong&gt; is surprisingly useful.&lt;/p&gt;

&lt;p&gt;Obviously the model did write it. We are not performing metaphysical surgery on the transformer.&lt;/p&gt;

&lt;p&gt;But role framing affects the kind of analysis the model performs. Removing psychological ownership, even fictitiously, tends to produce a more skeptical review.&lt;/p&gt;

&lt;p&gt;For especially important code, you can go further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Imagine this change caused a production incident three months from now.

Work backwards and identify the most plausible ways this implementation could have caused it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you’re effectively asking for a miniature pre-mortem.&lt;/p&gt;

&lt;p&gt;That often surfaces issues a generic code review misses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ask for counterexamples, not opinions
&lt;/h2&gt;

&lt;p&gt;One of the easiest ways to make AI review more useful is to demand concrete failure cases.&lt;/p&gt;

&lt;p&gt;Bad:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is this implementation robust?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Better:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give me five concrete inputs, system states, or event sequences that could cause this implementation to behave incorrectly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even better:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For each suspected bug, construct the smallest reproducible scenario that would demonstrate it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This forces the critique toward falsifiable claims.&lt;/p&gt;

&lt;p&gt;For example, instead of:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There may be a race condition here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you want:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Request A reads balance=100. Request B reads balance=100. Both subtract 80. Both persist 20. The system has processed $160 of withdrawals from a $100 balance.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is something you can reason about.&lt;/p&gt;

&lt;p&gt;And test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn the findings into tests
&lt;/h2&gt;

&lt;p&gt;This is where the workflow becomes particularly powerful.&lt;/p&gt;

&lt;p&gt;After the adversarial review, ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For every credible issue you identified, write a regression test that fails against the current implementation.

Do not change the production code yet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the loop becomes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement → Attack → Reproduce → Repair → Verify&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is much stronger than:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implement → Looks good → Ship&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And it makes the agent prove its criticism.&lt;/p&gt;

&lt;p&gt;If the supposed bug cannot be reproduced, maybe the review was wrong.&lt;/p&gt;

&lt;p&gt;If the test fails, you now have both evidence and permanent coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different reviewers find different classes of bugs
&lt;/h2&gt;

&lt;p&gt;“Review this code” is extremely underspecified.&lt;/p&gt;

&lt;p&gt;I get better results by running multiple targeted reviews.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Security reviewer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this implementation as a hostile application security engineer.

Look for ways an attacker could abuse inputs, authentication, authorization, state transitions, serialization, file access, network calls, or resource consumption.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reliability reviewer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this as a distributed systems reliability engineer.

Focus on partial failure, retries, duplicate execution, idempotency, ordering, timeouts, race conditions, stale state, and recovery after crashes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  API reviewer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review this as the maintainer of clients that depend on this API.

Look for undocumented behavior changes, ambiguous contracts, backwards compatibility problems, surprising defaults, and error semantics.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance reviewer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Assume this works correctly at 100 requests per day but fails badly at 10 million.

Find the scaling problems.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These prompts constrain the search.&lt;/p&gt;

&lt;p&gt;And constrained searches are often much better than asking a model to vaguely “think harder.”&lt;/p&gt;

&lt;h2&gt;
  
  
  There is another benefit: specification discovery
&lt;/h2&gt;

&lt;p&gt;The adversarial pass does something beyond finding implementation bugs.&lt;/p&gt;

&lt;p&gt;It often discovers that your &lt;strong&gt;requirements were incomplete&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Suppose the agent asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What should happen if two users update the object simultaneously?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe you never specified that.&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Is deleting this resource supposed to cascade to associated records?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also unspecified.&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should this endpoint reveal whether an email address already exists?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Congratulations, your coding agent just wandered into a product/security decision disguised as an implementation detail.&lt;/p&gt;

&lt;p&gt;This is one of the more useful properties of adversarial review.&lt;/p&gt;

&lt;p&gt;It exposes the negative space around your specification.&lt;/p&gt;

&lt;p&gt;The original implementation task asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What did the user tell me to build?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The adversarial task asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What did the user forget to tell me?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That second question can be much more valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just ask it to “double-check”?
&lt;/h2&gt;

&lt;p&gt;Because “double-check” preserves the original frame.&lt;/p&gt;

&lt;p&gt;The model is still trying to validate the solution.&lt;/p&gt;

&lt;p&gt;Adversarial review changes the success criterion.&lt;/p&gt;

&lt;p&gt;Success is no longer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The implementation appears correct.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Success becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I found a credible way this could fail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That small prompt-engineering shift matters.&lt;/p&gt;

&lt;p&gt;It is basically the software equivalent of red teaming.&lt;/p&gt;

&lt;p&gt;You don't ask the red team to confirm that the defenses look sensible.&lt;/p&gt;

&lt;p&gt;You tell them to get in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't blindly accept the critique either
&lt;/h2&gt;

&lt;p&gt;There is an important caveat.&lt;/p&gt;

&lt;p&gt;AI-generated criticism is not automatically correct.&lt;/p&gt;

&lt;p&gt;A sufficiently determined model can find imaginary bugs with impressive confidence.&lt;/p&gt;

&lt;p&gt;So I treat adversarial findings as hypotheses.&lt;/p&gt;

&lt;p&gt;The hierarchy is roughly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Concrete failing test&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reproducible execution path&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clear reasoning from documented behavior&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Plausible concern&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Vibes wearing a security-engineer costume&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The farther down that list a finding sits, the less weight I give it.&lt;/p&gt;

&lt;p&gt;This is also why asking the agent to produce reproduction cases and tests is so useful.&lt;/p&gt;

&lt;p&gt;It converts prose into evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the agent inspect the diff, not just its memory
&lt;/h2&gt;

&lt;p&gt;If your tool supports it, another useful instruction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the actual git diff and all directly affected code.

Do not rely on your memory of what you intended to change.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Intent is dangerous during review.&lt;/p&gt;

&lt;p&gt;The implementation may not match the agent’s mental model of the implementation.&lt;/p&gt;

&lt;p&gt;The diff is reality.&lt;/p&gt;

&lt;p&gt;For significant changes, I also ask it to inspect neighboring code and call sites. Bugs frequently live at boundaries rather than inside the newly written function.&lt;/p&gt;

&lt;h2&gt;
  
  
  A workflow worth automating
&lt;/h2&gt;

&lt;p&gt;For meaningful changes, my preferred agent loop is increasingly something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Understand the task.
2. Inspect the existing code.
3. Propose an implementation plan.
4. Implement the change.
5. Run relevant tests.
6. Perform an adversarial review.
7. Produce concrete failure cases for credible findings.
8. Add regression tests.
9. Fix confirmed issues.
10. Run the full relevant test suite.
11. Review the final diff again.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can put this directly into an agent instruction file.&lt;/p&gt;

&lt;p&gt;The marginal cost is tiny.&lt;/p&gt;

&lt;p&gt;The value can be enormous.&lt;/p&gt;

&lt;h2&gt;
  
  
  The broader lesson
&lt;/h2&gt;

&lt;p&gt;The interesting thing here isn't really the prompt.&lt;/p&gt;

&lt;p&gt;It's that AI coding agents become more useful when we stop treating them as a single programmer with a single continuous train of thought.&lt;/p&gt;

&lt;p&gt;They can be the implementer.&lt;/p&gt;

&lt;p&gt;Then the reviewer.&lt;/p&gt;

&lt;p&gt;Then the attacker.&lt;/p&gt;

&lt;p&gt;Then the test engineer.&lt;/p&gt;

&lt;p&gt;Then the maintainer wondering what lunatic wrote this six months ago.&lt;/p&gt;

&lt;p&gt;Those roles optimize for different things.&lt;/p&gt;

&lt;p&gt;And one of the cheapest ways to improve AI-generated software is to deliberately make the model disagree with the version of itself that wrote the code.&lt;/p&gt;

&lt;p&gt;So the next time your coding agent announces:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Implementation complete. All tests pass.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't congratulate it yet.&lt;/p&gt;

&lt;p&gt;Tell it to try to destroy what it just built.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>testing</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>How to Let gzip Find the Signal in a Pile of Documents</title>
      <dc:creator>Jean-Luc Martel</dc:creator>
      <pubDate>Mon, 03 Aug 2026 23:19:53 +0000</pubDate>
      <link>https://dev.to/jlmartel/how-to-let-gzip-find-the-signal-in-a-pile-of-documents-2o9g</link>
      <guid>https://dev.to/jlmartel/how-to-let-gzip-find-the-signal-in-a-pile-of-documents-2o9g</guid>
      <description>&lt;p&gt;Suppose you have a directory full of text documents.&lt;/p&gt;

&lt;p&gt;Most are repetitive, padded with boilerplate, or otherwise low-signal. A few contain the useful material. You could read every file manually, feed them all into an embedding pipeline, or ask an LLM to rank them.&lt;/p&gt;

&lt;p&gt;Or you could ask &lt;strong&gt;gzip&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The basic idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Repetitive text compresses well. Varied text usually does not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That makes compression ratio a crude but surprisingly useful proxy for redundancy.&lt;/p&gt;

&lt;p&gt;It will not tell you which document is &lt;em&gt;best&lt;/em&gt;. But it can help you identify which documents contain less repetition and deserve a closer look.&lt;/p&gt;

&lt;h2&gt;
  
  
  The heuristic
&lt;/h2&gt;

&lt;p&gt;For each document:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Measure its original size.&lt;/li&gt;
&lt;li&gt;Compress it individually with &lt;code&gt;gzip&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Measure the compressed size.&lt;/li&gt;
&lt;li&gt;Calculate:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;compressed size / original size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lower ratio means the document compressed well, which usually indicates more repetition.&lt;/p&gt;

&lt;p&gt;A higher ratio means the document was harder to compress, which may indicate more varied or information-dense content.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lower ratio: more redundant&lt;/li&gt;
&lt;li&gt;higher ratio: less redundant&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Bash command
&lt;/h2&gt;

&lt;p&gt;Here is a small Bash pipeline that ranks &lt;code&gt;.txt&lt;/code&gt; files by compression ratio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ./documents &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'*.txt'&lt;/span&gt; &lt;span class="nt"&gt;-print0&lt;/span&gt; |
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; file&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;compressed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$raw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;gz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$compressed&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'
    raw &amp;gt; 0 {
      printf "%.3f\t%8d\t%8d\t%s\n", gz/raw, raw, gz, file
    }
  '&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-nr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.642      18432      11834  ./documents/research-notes.txt
0.417      30211      12600  ./documents/project-summary.txt
0.091      27102       2467  ./documents/standard-contract.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The columns are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ratio    original bytes    compressed bytes    filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the output is sorted in descending order, the least compressible files appear first.&lt;/p&gt;

&lt;p&gt;Those are the files I would inspect first when looking for the possible “gems.”&lt;/p&gt;

&lt;p&gt;To find the most repetitive documents instead, reverse the sort:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why &lt;code&gt;gzip -n&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;-n&lt;/code&gt; flag prevents &lt;code&gt;gzip&lt;/code&gt; from storing the original filename and timestamp in its output.&lt;/p&gt;

&lt;p&gt;That makes the compressed sizes more comparable across files and across runs.&lt;/p&gt;

&lt;p&gt;Without it, a small amount of unrelated metadata can leak into the measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is actually measuring
&lt;/h2&gt;

&lt;p&gt;This technique does not measure truth, relevance, writing quality, or semantic importance.&lt;/p&gt;

&lt;p&gt;It measures compressibility.&lt;/p&gt;

&lt;p&gt;Those things sometimes correlate, but they are not the same.&lt;/p&gt;

&lt;p&gt;A document full of repeated boilerplate will usually compress extremely well. A document with more distinct vocabulary, sentence structure, numbers, and ideas may compress less efficiently.&lt;/p&gt;

&lt;p&gt;That makes the ratio useful as a first-pass ranking signal.&lt;/p&gt;

&lt;p&gt;It is closer to a metal detector than a treasure map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Important caveats
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Small files produce noisy ratios
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;gzip&lt;/code&gt; adds headers and other fixed overhead. For tiny files, that overhead can dominate the result.&lt;/p&gt;

&lt;p&gt;You may want to ignore documents below a minimum size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ./documents &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'*.txt'&lt;/span&gt; &lt;span class="nt"&gt;-size&lt;/span&gt; +1k &lt;span class="nt"&gt;-print0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Already-compressed formats will mislead you
&lt;/h3&gt;

&lt;p&gt;Running this directly against PDF, DOCX, ZIP, JPG, or other compressed formats mostly measures the compression characteristics of the container format.&lt;/p&gt;

&lt;p&gt;Extract the text first.&lt;/p&gt;

&lt;p&gt;For example, with PDFs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pdftotext input.pdf output.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incompressible does not mean valuable
&lt;/h3&gt;

&lt;p&gt;Encrypted data, random identifiers, hashes, minified code, and corrupted text are all difficult to compress.&lt;/p&gt;

&lt;p&gt;They may score highly while containing little useful information.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repetition is not always fluff
&lt;/h3&gt;

&lt;p&gt;Contracts, API documentation, technical specifications, and scientific papers may repeat terminology because precision requires it.&lt;/p&gt;

&lt;p&gt;A lower ratio can indicate redundancy, but it can also indicate consistency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Language and formatting matter
&lt;/h3&gt;

&lt;p&gt;Compression ratios can be affected by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;document length&lt;/li&gt;
&lt;li&gt;whitespace&lt;/li&gt;
&lt;li&gt;markup&lt;/li&gt;
&lt;li&gt;tables&lt;/li&gt;
&lt;li&gt;repeated headings&lt;/li&gt;
&lt;li&gt;source language&lt;/li&gt;
&lt;li&gt;character encoding&lt;/li&gt;
&lt;li&gt;templated metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a fairer comparison, normalize the documents first.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s1"&gt;'[:space:]'&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt; &amp;lt; input.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could also strip HTML, remove headers and footers, or convert everything to lowercase before compression.&lt;/p&gt;

&lt;p&gt;Just remember that normalization changes what you are measuring.&lt;/p&gt;

&lt;h2&gt;
  
  
  A slightly more useful version
&lt;/h2&gt;

&lt;p&gt;For larger collections, I would filter out tiny files and print the percentage saved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find ./documents &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s1"&gt;'*.txt'&lt;/span&gt; &lt;span class="nt"&gt;-size&lt;/span&gt; +1k &lt;span class="nt"&gt;-print0&lt;/span&gt; |
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nv"&gt;IFS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; file&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;compressed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$raw&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;gz&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$compressed&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s1"&gt;'
    raw &amp;gt; 0 {
      ratio = gz / raw
      saved = 100 * (1 - ratio)

      printf "%6.2f%% saved\t%8d bytes\t%s\n",
             saved, raw, file
    }
  '&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This sorts the files with the lowest percentage saved first, meaning the least compressible documents rise to the top.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this could be useful
&lt;/h2&gt;

&lt;p&gt;This trick can be handy for quickly triaging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scraped web pages&lt;/li&gt;
&lt;li&gt;exported support tickets&lt;/li&gt;
&lt;li&gt;meeting transcripts&lt;/li&gt;
&lt;li&gt;research notes&lt;/li&gt;
&lt;li&gt;log samples&lt;/li&gt;
&lt;li&gt;generated reports&lt;/li&gt;
&lt;li&gt;document archives&lt;/li&gt;
&lt;li&gt;large sets of Markdown files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is especially useful when you want a fast local heuristic without setting up a database, embedding model, or external API.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compression as a feature
&lt;/h2&gt;

&lt;p&gt;The broader idea is more interesting than the Bash command.&lt;/p&gt;

&lt;p&gt;Compression ratio can be treated as a lightweight feature in a ranking system.&lt;/p&gt;

&lt;p&gt;You could combine it with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;document length&lt;/li&gt;
&lt;li&gt;vocabulary diversity&lt;/li&gt;
&lt;li&gt;duplicate paragraph counts&lt;/li&gt;
&lt;li&gt;keyword density&lt;/li&gt;
&lt;li&gt;entropy&lt;/li&gt;
&lt;li&gt;embedding similarity&lt;/li&gt;
&lt;li&gt;recency&lt;/li&gt;
&lt;li&gt;source reputation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compression alone is crude.&lt;/p&gt;

&lt;p&gt;Compression plus a few other signals could become a genuinely useful document-triage tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;There are sophisticated ways to rank a pile of documents.&lt;/p&gt;

&lt;p&gt;Sometimes, though, a 40-year-old compression algorithm is enough to tell you which files keep repeating themselves.&lt;/p&gt;

&lt;p&gt;And that is often a very good place to start.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>automation</category>
      <category>bash</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
