<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Blog</title>
    <link>https://blog.zhade.dev/</link>
    <description>Recent content on Blog</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Fri, 13 Feb 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://blog.zhade.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>In Defense of Friction</title>
      <link>https://blog.zhade.dev/posts/2026-02-13-in-defense-of-friction/</link>
      <pubDate>Fri, 13 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2026-02-13-in-defense-of-friction/</guid>
      <description></description>
    </item>
    <item>
      <title>Lessons from a Month of Vibe Coding with Copilot CLI</title>
      <link>https://blog.zhade.dev/posts/2026-01-11-vibe-coding/</link>
      <pubDate>Sun, 11 Jan 2026 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2026-01-11-vibe-coding/</guid>
      <description>&lt;p&gt;One of the greatest perks to working at GitHub is unlimited access to Copilot tokens, allowing me to vibe code as much as I want:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;./images/unlimited-copilot-tokens.png&#34; alt=&#34;Unlimited Copilot tokens&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;With my unlimited AI, I spent most of my holiday break vibe coding up small utilities and games that I’d wanted to work on before but never had the time to finish.&lt;/p&gt;&#xA;&lt;p&gt;Here are a few lessons that a holiday season with irresponsible access to premium models taught me about vibe coding with &lt;a href=&#34;https://github.com/features/copilot/cli&#34;&gt;Copilot CLI&lt;/a&gt;:&lt;/p&gt;</description>
    </item>
    <item>
      <title>How GitHub&#39;s Agentic Security Principles Make Our AI Agents as Secure as Possible</title>
      <link>https://blog.zhade.dev/posts/2025-11-25-agentic-security-principles/</link>
      <pubDate>Tue, 25 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-11-25-agentic-security-principles/</guid>
      <description></description>
    </item>
    <item>
      <title>Self Advocacy at a Remote-First Company: How to Careermax</title>
      <link>https://blog.zhade.dev/posts/2025-11-07-self-advocacy/</link>
      <pubDate>Fri, 07 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-11-07-self-advocacy/</guid>
      <description>&lt;p&gt;Over the past couple of years at GitHub, I’ve learned that nothing in corporate is handed to you; you should always be your own biggest advocate. Promotions, good projects, and visibility are only unlocked when you have eyes on you. As they say, only the squeaky wheel gets grease.&lt;/p&gt;&#xA;&lt;p&gt;Getting visibility is never easy, but it can be even more difficult at a remote-first company where it’s harder to physically network. However, by being tactical and intentional, you can still maximize your impact and visibility. Here are the five things I focus on to make that happen at GitHub.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Reversible are Embeddings: Embedding Inversions and How to Protect your Data</title>
      <link>https://blog.zhade.dev/posts/2025-10-28-embeddings-inversion/</link>
      <pubDate>Mon, 27 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-10-28-embeddings-inversion/</guid>
      <description>&lt;p&gt;I was recently asked to determine the sensitivity of embeddings generated from proprietary code. While it seemed natural to think that embeddings were one-way functions that could not be reversed, research revealed that substantial semantic leakage was possible—even if direct reconstruction was not.&lt;/p&gt;&#xA;&lt;p&gt;Embeddings turn a &lt;strong&gt;token&lt;/strong&gt;—a word, subword, or symbol— into a vector that encodes its semantic meaning. However, these vectors are not unique; multiple tokens can map to the same vector, and as such are a &lt;a href=&#34;https://en.wikipedia.org/wiki/Lossy_compression&#34;&gt;lossy function&lt;/a&gt;. Embeddings generated from longer sequences, like sentences or paragraphs, lose even more data, as the  &lt;a href=&#34;https://blog.ml6.eu/the-art-of-pooling-embeddings-c56575114cf8&#34;&gt;sequence embedding techniques&lt;/a&gt; compress more information into the same vector space, leading to even more collisions, like squishing a bunch of different photos into a single blurry thumbnail.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Prompt Injection is a Weakness, not a Vulnerability</title>
      <link>https://blog.zhade.dev/posts/2025-05-15-prompt-injection-weakness/</link>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-05-15-prompt-injection-weakness/</guid>
      <description>&lt;p&gt;Prompt injection is the most widely discussed emergent threat for Large Language Models (LLMs). But how should organizations approach tracking and prioritizing it?&lt;/p&gt;&#xA;&lt;p&gt;In my opinion, instead of being a vulnerability in and of itself, prompt injection is a weakness that leads to other, more potent vulnerabilities. While it is true that prompt injection is undesirable, it doesn’t necessarily lead to any business value compromises and is also (at the time of writing) unsolvable. As such, it is better to treat it as a necessary side effect of using LLMs, architect around it, and not track it as a distinct vulnerability.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Secure Generative UIs with Grammar Constrained Decoding</title>
      <link>https://blog.zhade.dev/posts/2025-04-29-secure-generative-uis/</link>
      <pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-04-29-secure-generative-uis/</guid>
      <description>&lt;p&gt;LLMs are very powerful for generating arbitrary text, but they really shine when you ask them to generate structured output. One such use case is generating rich UIs and text.&lt;/p&gt;&#xA;&lt;p&gt;It’s much easier to read the output of an LLM if it’s properly styled and interactive. Reading large blobs of text can get unwieldy, and adding styling and interactive elements dynamically makes the output much more user-friendly and personalizable. This is known as a &lt;a href=&#34;https://www.nngroup.com/articles/generative-ui&#34;&gt;Generative UI&lt;/a&gt;; a User Interface that is generated in real-time by a generative AI.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Writing in the Age of AI: My AI-enabled Process for Writing</title>
      <link>https://blog.zhade.dev/posts/2025-03-04-writing-in-the-age-of-ai/</link>
      <pubDate>Tue, 04 Mar 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-03-04-writing-in-the-age-of-ai/</guid>
      <description>&lt;p&gt;Is writing a dying art in the ChatGPT era? How I think about using AI in my writing and my AI-enabled process.&lt;/p&gt;&#xA;&lt;p&gt;LLMs have decimated the role of a professional writer. We’ve seen layoffs among &lt;a href=&#34;https://www.cnn.com/2024/01/09/tech/duolingo-layoffs-due-to-ai/index.html&#34;&gt;translators&lt;/a&gt;, &lt;a href=&#34;https://www.wypr.org/2024-05-30/wall-street-journal-layoffs-continue-despite-lucrative-ai-deal-and-record-profits&#34;&gt;journalists&lt;/a&gt;, paralegals; many job fields for which writing is the core responsibility have either been completely obviated or are on their way there in due course. Even as an engineer, I’ve been able to increase my writing efficiency almost to the order of &lt;a href=&#34;https://www.indeed.com/hire/c/info/full-time-equivalent&#34;&gt;0.5 FTE&lt;/a&gt;— reports and other prose that I might’ve previously needed another engineer to help with, I’m able to do alone in half the time and twice as well.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Path to SOC Analyst: Breaking into Cybersecurity</title>
      <link>https://blog.zhade.dev/posts/2025-02-23-path-to-soc-analyst/</link>
      <pubDate>Sun, 23 Feb 2025 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2025-02-23-path-to-soc-analyst/</guid>
      <description>&lt;p&gt;This was originally drafted as &lt;a href=&#34;https://docs.google.com/document/d/1cx9Ww_qdqwfbfb5wbGGrRwLt-wB738o-aE2jwaHlx6w/&#34;&gt;a Google doc&lt;/a&gt; for a friend.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;If you’re trying to break into cybersecurity with no previous cyber, engineering, or IT experience, the best way to break into the industry is as a SOC analyst.&lt;/p&gt;&#xA;&lt;p&gt;SOC Analysts are cybersecurity analysts responsible for monitoring corporate networks for potential threats and intrusions. While certainly not an introductory IT/ engineering role, it is the closest thing to an introductory role in security.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Being Intentional in 2024</title>
      <link>https://blog.zhade.dev/posts/2024-01-22-intentionality/</link>
      <pubDate>Mon, 22 Jan 2024 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2024-01-22-intentionality/</guid>
      <description>&lt;p&gt;I put on quite a bit of weight over COVID. Stuck in lockdown with little else to do, I quickly picked up a nasty habit of snacking. The cupboard and fridge were so accessible and readily stocked with all manner of tasty food. With nothing better to do, I would go grab a bite anytime I was hungry or bored or thirsty or anything. And of course, with all of this, I began to balloon in weight, despite wanting to remain healthy.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introduction to Natural Language Processing</title>
      <link>https://blog.zhade.dev/posts/2023-09-21-intro-natural-language-processing/</link>
      <pubDate>Thu, 21 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2023-09-21-intro-natural-language-processing/</guid>
      <description>&lt;p&gt;A quick intro to the basic terminology and concepts in Natural Language Processing.&lt;/p&gt;&#xA;&lt;h3 id=&#34;token&#34;&gt;Token&lt;/h3&gt;&#xA;&lt;p&gt;A &lt;strong&gt;token&lt;/strong&gt; is the smallest semantic subsection of a piece of text. For example, a word.&lt;/p&gt;&#xA;&lt;p&gt;This is the smallest subdivision of a text that can be assigned meaning (any smaller units than a word, like individual letters, have no inherent meaning to them)&lt;/p&gt;&#xA;&lt;h3 id=&#34;n--gram&#34;&gt;n- gram&lt;/h3&gt;&#xA;&lt;p&gt;An &lt;strong&gt;n- gram&lt;/strong&gt; is a collection of &lt;code&gt;n&lt;/code&gt; tokens. For example, if we’re using words as the gram and using the value 2 as &lt;code&gt;n&lt;/code&gt;, in the sentence:&lt;/p&gt;</description>
    </item>
    <item>
      <title>&#34;for … in&#34; vs &#34;for … of&#34; in JavaScript</title>
      <link>https://blog.zhade.dev/posts/2023-09-17-for-in-javascript/</link>
      <pubDate>Sun, 17 Sep 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2023-09-17-for-in-javascript/</guid>
      <description>&lt;p&gt;TIL that &lt;code&gt;for … in&lt;/code&gt; and &lt;code&gt;for … of&lt;/code&gt; have different behaviors in JavaScript.&lt;/p&gt;&#xA;&lt;p&gt;As a native Python developer, I had presumed that &lt;code&gt;for … in&lt;/code&gt; in JavaScript would have a similar behavior to the equivalent in Python. However, they have very different behaviors. See below:&lt;/p&gt;&#xA;&lt;h3 id=&#34;tldr&#34;&gt;TLDR&lt;/h3&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;JavaScript&lt;/th&gt;&#xA;          &lt;th&gt;Python&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;for (foo in [])&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;for i in range([])&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;for (foo of [])&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;&lt;code&gt;for i in []&lt;/code&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h3 id=&#34;details&#34;&gt;Details&lt;/h3&gt;&#xA;&lt;p&gt;&lt;code&gt;for … in&lt;/code&gt; iterates over the &lt;em&gt;keys&lt;/em&gt; of a particular object, whereas &lt;code&gt;for … of&lt;/code&gt; iterates over the &lt;em&gt;values&lt;/em&gt; of the object. It does this by using an &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols&#34;&gt;iteration protocol&lt;/a&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Introduction to Adversarial AI</title>
      <link>https://blog.zhade.dev/posts/2023-04-03-intro-adversarial-ai/</link>
      <pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2023-04-03-intro-adversarial-ai/</guid>
      <description>&lt;p&gt;The following is a transcription of a talk I&amp;rsquo;ve given internally at GitHub. The talk, and &lt;a href=&#34;https://zhade.dev/slides/presentations/adversarial-ai&#34;&gt;slides&lt;/a&gt;, are about the basics of adversarial AI, and how it can be used to attack machine learning models.&lt;/p&gt;&#xA;&lt;h2 id=&#34;slides&#34;&gt;Slides&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://zhade.dev/slides/presentations/adversarial-ai&#34;&gt;&lt;iframe src=&#34;https://zhade.dev/slides/presentations/adversarial-ai&#34; width=&#34;100%&#34;&gt;&lt;/iframe&gt;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;transcript&#34;&gt;Transcript&lt;/h2&gt;&#xA;&lt;h3 id=&#34;how-do-machine-learning-systems-work&#34;&gt;How do Machine Learning Systems work?&lt;/h3&gt;&#xA;&lt;p&gt;For the purposes of this talk/ blog post, we’re not going to go too in depth into the technical details of machine learning algorithms. However, from a security perspective, it is important to note the flow of data.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Implementing a Robust Digital Identity</title>
      <link>https://blog.zhade.dev/posts/2022-06-10-implementing-a-robust-digital-identity/</link>
      <pubDate>Fri, 10 Jun 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2022-06-10-implementing-a-robust-digital-identity/</guid>
      <description></description>
    </item>
    <item>
      <title>Setting Secure Hashing Parameters for Password Hashing</title>
      <link>https://blog.zhade.dev/posts/2022-05-28-setting-secure-hashing-params/</link>
      <pubDate>Sat, 28 May 2022 00:00:00 +0000</pubDate>
      <guid>https://blog.zhade.dev/posts/2022-05-28-setting-secure-hashing-params/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;TLDR: As of May 2022, I’d recommend using Argon2Id with the parameters recommended in &lt;a href=&#34;https://www.rfc-editor.org/rfc/rfc9106.html&#34;&gt;RFC 9106&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;When trying to select the right way to protect your user’s passwords and credentials, there’s two things we need to consider. Firstly, we need to choose the right algorithm, one that is cryptographically secure. Secondly, we need to se the right &lt;em&gt;parameters&lt;/em&gt; for the given algorithm to make it behave as securely as possible.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
