Friday Links: Claude for VS Code, PHP2Shell, and coding portfolios

Hey there.

Quick update: This week, I finished the first draft of Street-Smart Coding in the Age of AI and already reached out to some of my loyal beta readers. You can preorder your ebook copy starting at just $1.

In case you missed last email, Street-Smart Coding in the Age of AI is book #3 in my Street-Smart Coding collection. It’s a short and actionable guide to help you leverage AI without becoming dependent on it. The first draft sits around 5K words. You can finish it over coffee.


Here are 4 links I thought were worth sharing this week:

#1. If you use Claude Code for VS Code, be aware it was recently compromised (5min).

#2. PHP2Shell vulnerability has taught us it’s time to start paying 40 years of technical debt (3min).

#3. If you still use Postman, be aware it was at some point installing Claude plugins and startup hooks. Here are the findings on the official GitHub repo (3min). I just uninstalled it.

#4. I’ve never had a portfolio. I joke that my blog is my portfolio. But if you have one, here’s how to rethink your portfolio in the age of AI (6min).


And in case you missed it, last week, to celebrate Halloween, I shared 4 posts to scare the coder inside you (1min) and, more recently, I wrote about C# new keyword and data annotations (2min).


(Bzzz…Radio voice) This email was brought to you by… Preorder your copy of Street-Smart Coding in the Age of AI. A short and actionable guide to leverage AI without losing your skills.

See you next time,

Cesar

The Missing Ingredient to Beat AI Slop

AI content is too perfect… and soulless.

Em dashes were a clear giveaway of AI-generated content.
But you can instruct your LLM of choice not to use them and still sound robotic.
It’s. Not. That. It’s. This. Beep… Beep…

Maybe typos and imperfect sentences are a sign of human-written content.
To show there was a human behind my words, I stopped using AI to proof-read my writing.
You can instruct your LLM to add typos too.

Apart from personal stories and an interesting life, brevity is maybe the true sign of a human-written content.

I stopped writing 1,000-word SEO-optimized posts long time ago.
These days, anything longer than a tweet counts towards publishing.
100-200 words is my sweet spot.
AI can always add more fluff… and more fluff.

The bottleneck isn’t hitting a word count, but well-thought ideas that don’t need an AI-summary.

Nobody has ever complained about good ideas being concise.

Just like nobody has complained about 10 Surprisingly Simple Ideas That Changed My Life And Could Change Yours Too being too short.

The Fastest Salary Negotiation I've Had (You Might Have One Too)

I made a list of contributions and achievements in the past year.
I did a quick market research. OK, by research, I mean I asked Gemini.
I came up with a range and an anchor point.
I reached out to an ex-coworker to ask how he asked for a raise.
I reread the chapters on negotiation from Choose Yourself Guide to Wealth.
I wrote a script and had a “what would you do in my shoes?” line ready as fallback.

I texted my “boss” asking for a time slot to discuss a raise.
I was expecting to jump into a call to present my case and “negotiate.”
Instead he asked if we could do it via direct messages.

I texted something like, “It’s been a while, blah, blah, blah… My current rate is $X and I have in mind something between $Y and $Z.”

He replied, “let me check and get back to you.”

Radio silence!

In a 1-on-1 negotiation, you get an immediate answer.
Either “sorry, we can’t do that” or “here’s what I can do for you.”
But this time, a loop was opened in my mind.

The next day, about the same time, I got a text, “Good news! Blah, blah, blah… We are supporting your request to increase your rate to $Y, effective $insertDate. Blah, blah, blah…“

The fastest, easiest, and most awkward salary or rate negotiation I ever had.

Lesson: Always go prepared. Always have a salary range and anchor point in mind. “Ask and you shall receive,” Jesus said. And maybe that could be as fast and easy as some messages via Discord or Slack.

If you’re starting out or already ahead in your coding journey, check out Career Lessons From the Trenches, my free 7-day email course where I distill 10+ years of career lessons into 7 short emails–to help you navigate your coding career.

TIL: The new Keyword Doesn't Hide Data Annotations

In another episode of I thought I knew enough about C#…

Today I wanted to “overwrite” the validations of a property from a parent DTO on its child DTO. Let’s say I had a Movie and Clip and needed shorter names for clips.

Just take a look at the attributes on Movie and ShortClip.

using System.ComponentModel.DataAnnotations;

namespace TestProject1;

[TestClass]
public class NewKeywordTests
{
    public abstract class Movie
    {
        [Required]
        [MinLength(52)]  // <--
        public string? Name { get; set; }
    }

    public class ShortClip : Movie
    {
        [MaxLength(20)]  // <-- Different annotations
        public new string? Name { get; set; }
        //     ^^^
    }

    [TestMethod]
    public void NewDoesNotHideValidationAttributes()
    {
        var myClip = new ShortClip
        {
            Name = "AShortName"
            //     ^^^^^
            // It has less than 20 chars,
            // so it must be valid, right?
        };

        var context = new ValidationContext(myClip);
        var validationResults = new List<ValidationResult>();

        bool isValid = Validator.TryValidateObject(
            myClip,
            context,
            validationResults,
            validateAllProperties: true
        );

        Assert.IsTrue(isValid);
        //     ^^^^^
        // Booom!!!
    }
}

Whaaat?! It didn’t work. The new keyword in the child class hides the property, but not the attributes. Sad trombone!

Sneaking into TryValidateObject() source code, it uses TypeDescriptor.GetProperties() to list the properties to validate, which returns a “merged” list of attributes. [Source].

var descriptor = TypeDescriptor.GetProperties(myClip.GetType());
var attributes = x[0].Attributes;
//  ^^^^^
// Among other attributes:
// RequiredAttribute
// MinAttribute
// MaxAttribute

When I asked Gemini for help, it suggested using virtual and override. And guess what? That doesn’t work either.

On my original code, I ended pulling down the property I wanted to have different annotations to the child classes on the hierarchy.

That’s why you shouldn’t blindly trust AI and build code reading and troubleshooting skills. I cover those skills and more in Street-Smart Coding—A roadmap with 30 lessons to help you code like a pro.

A Parenting and Book Writing Lesson Learned At a Bookstore

Do you have a book for parents raising two teenager girls?, a guy said.

He was in the next aisle at a bookstore. I was looking for some Christmas presents. I had on my hands Clear Thinking and The Cat Who Saved Books. I was looking for a third book to take advantage of the month’s promotion. The cheapest of the three was free.

The guy kept walking the aisles. An employee started to recommend titles: Think and Grow Rich, The 5:00 Club… Then his daughter said, “I’ve seen this book…I don’t know the title, but its cover is a little brain made of 1-dollar bills…“

“The Psychology of Money,” I said laughing. That moment I knew she was my kind of reading mate. And I knew his after was doing something good: surrounding them with books.

Then I saw it: sometimes a good book covers does all the heavy work for your book. Design your cover so a 13-year-old girl, probably not interested in your subject, could remember your book.

Like it or not, a book is judged by its cover. Just like you and me are judged by the way we look.