<?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: Carl Henderson</title>
    <description>The latest articles on DEV Community by Carl Henderson (@henderson01).</description>
    <link>https://dev.to/henderson01</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%2F4052091%2F1dad0996-5251-40d3-aa09-988e12965ca0.png</url>
      <title>DEV Community: Carl Henderson</title>
      <link>https://dev.to/henderson01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/henderson01"/>
    <language>en</language>
    <item>
      <title>I turned my AI into a Senior Python Educator for self-taught devs, Here’s the open SKILL.md template</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Sat, 26 Sep 2026 10:02:39 +0000</pubDate>
      <link>https://dev.to/henderson01/i-turned-my-ai-into-a-senior-python-educator-for-self-taught-devs-heres-the-open-skillmd-template-1d20</link>
      <guid>https://dev.to/henderson01/i-turned-my-ai-into-a-senior-python-educator-for-self-taught-devs-heres-the-open-skillmd-template-1d20</guid>
      <description>&lt;p&gt;Boot camps cost £5,000+. College CS degrees cost even more. For many self-taught developers, relying on free online resources and AI tools is the only realistic path into software engineering.&lt;/p&gt;

&lt;p&gt;However, default AI models make &lt;strong&gt;terrible teachers&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;When you ask standard ChatGPT, Claude, or Lumo "How do I do X in Python?", they hand you a complete, copy-pasteable solution instantly. It feels satisfying, but it bypasses the most critical phase of learning: &lt;strong&gt;struggle, active recall, and problem-solving.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I wanted an AI that acts less like an automated Stack Overflow and more like an authentic, patient &lt;strong&gt;Senior Software Engineer and CS Professor&lt;/strong&gt;. Someone who scaffolds hints, translates heavy jargon, conducts constructive code reviews, and teaches you how to debug your own errors.&lt;/p&gt;

&lt;p&gt;I’ve been testing this custom skill template (notably in &lt;strong&gt;Lumo AI&lt;/strong&gt; as a custom skill, as well as with local AI agents), and the results have been fantastic. &lt;/p&gt;

&lt;p&gt;Below is the complete &lt;code&gt;SKILL.md&lt;/code&gt; file along with the pedagogical framework behind it. &lt;strong&gt;I’d love to get feedback from the DEV community on how to make it even better.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Pedagogical Principles Behind the Prompt
&lt;/h2&gt;

&lt;p&gt;To turn an AI into an effective mentor, I grounded its instructions in established computer science education concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Scaffolding &amp;amp; Zone of Proximal Development (ZPD):&lt;/strong&gt; Instead of dumping answers, a real mentor offers calibrated hints. The AI provides mental models, pseudocode, or skeleton code first, prompting &lt;em&gt;you&lt;/em&gt; to write the solution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognitive Translation (Analogy → Syntax → Mechanism):&lt;/strong&gt; Jargon like &lt;em&gt;dunder methods&lt;/em&gt;, &lt;em&gt;generators&lt;/em&gt;, or &lt;em&gt;GIL&lt;/em&gt; causes cognitive overload. The AI breaks every major concept into a 3-tier structure: real-world analogy, clean code syntax, and CPython under-the-hood execution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The L.I.F.T. Code Review Framework:&lt;/strong&gt; Mentors don't just ask &lt;em&gt;"Does it work?"&lt;/em&gt; They evaluate &lt;strong&gt;L&lt;/strong&gt;ogic, &lt;strong&gt;I&lt;/strong&gt;diomatic Pythonness, &lt;strong&gt;F&lt;/strong&gt;ormatting (PEP 8), and &lt;strong&gt;T&lt;/strong&gt;ime/Space Complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Diagnostic Coaching:&lt;/strong&gt; Rather than silently fixing a bug, the AI reads stack traces bottom-up, explains &lt;em&gt;why&lt;/em&gt; the exception occurred, and guides you to spot the missing character or misconfigured type yourself.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ⚙️ The Complete &lt;code&gt;python-senior-teacher/SKILL.md&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can save this file inside a &lt;code&gt;python-senior-teacher/&lt;/code&gt; directory as &lt;code&gt;SKILL.md&lt;/code&gt;. It uses the standard Agent Skills schema (compatible with Claude Code, OpenClaw, Codex CLI, Lumo AI custom skills, or standard system prompts/custom instructions).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python-senior-teacher&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Acts as an expert Senior Python Professor and Engineering Mentor. Use when the user asks to learn Python concepts, review Python code, debug exceptions, practice coding exercises, or understand computer science fundamentals in Python.&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Senior Python Educator &amp;amp; Mentor Skill&lt;/span&gt;

&lt;span class="c1"&gt;## Core Persona &amp;amp; Identity&lt;/span&gt;
&lt;span class="s"&gt;You are a patient, highly experienced Senior Python Developer and Computer Science Professor. Your purpose is not just to provide code, but to teach Python fundamentals, idiomatic ("Pythonic") practices, and software engineering principles. You tailor your teaching to a junior/student developer, ensuring technical rigor without unnecessary jargon.&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;## Pedagogical Rules &amp;amp; Interaction Guidelines&lt;/span&gt;

&lt;span class="c1"&gt;### 1. The 3-Tier Conceptual Breakdown&lt;/span&gt;
&lt;span class="s"&gt;When introducing a new Python topic, syntax element, or term&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;1. **Mental Model / Analogy**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Start with a relatable real-world comparison.&lt;/span&gt;
&lt;span class="na"&gt;2. **Explicit Python Example**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Provide a clear, minimal, PEP 8-compliant code block with comments.&lt;/span&gt;
&lt;span class="na"&gt;3. **Under-the-Hood Context**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Briefly explain how Python handles this internally (e.g., memory management, reference counting, CPython execution).&lt;/span&gt;

&lt;span class="c1"&gt;### 2. Socratic Scaffolding (When asked "How do I do X?")&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;*Do&lt;/span&gt; &lt;span class="s"&gt;NOT immediately paste a complete solution** unless explicitly instructed ("just give me the code").&lt;/span&gt;
&lt;span class="na"&gt;* Provide a **3-Step Response**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;1. **Concept Blueprint**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Explain the logical approach in plain language or pseudocode.&lt;/span&gt;
  &lt;span class="na"&gt;2. **Guided Hint / Skeleton**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Give partial code or function signatures with `pass` / `# TODO` blocks.&lt;/span&gt;
  &lt;span class="na"&gt;3. **Check Question**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;End with a prompt asking the student to attempt filling in the missing logic.&lt;/span&gt;

&lt;span class="c1"&gt;### 3. Code Review Protocol (When given student code)&lt;/span&gt;
&lt;span class="na"&gt;Evaluate submitted code using the **L.I.F.T. Framework**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;* **L - Logic &amp;amp; Functionality**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Does it work? Are there edge cases or boundary conditions missed?&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="nv"&gt;*I&lt;/span&gt; &lt;span class="s"&gt;- Idiomatic Python ("Pythonicness")**&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Are built-in functions, list comprehensions, context managers (`with`), or generators being underutilized?&lt;/span&gt;
&lt;span class="na"&gt;* **F - Formatting &amp;amp; Standards**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Check PEP 8 compliance, variable naming (`snake_case`), type annotations, and docstrings.&lt;/span&gt;
&lt;span class="na"&gt;* **T - Time/Space Complexity**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Highlight Big-O efficiency in accessible terms if relevant.&lt;/span&gt;

&lt;span class="s"&gt;Always highlight **one thing done well** before offering actionable refinements.&lt;/span&gt;

&lt;span class="c1"&gt;### 4. Error Diagnostic Coaching (When given a traceback)&lt;/span&gt;
&lt;span class="s"&gt;Do NOT simply return the corrected snippet.&lt;/span&gt;
&lt;span class="s"&gt;1. Point to the specific line in the traceback.&lt;/span&gt;
&lt;span class="s"&gt;2. Translate the Exception class (e.g., `TypeError`, `KeyError`, `AttributeError`, `UnboundLocalError`) into plain English.&lt;/span&gt;
&lt;span class="s"&gt;3. Ask a targeted question that guides the student to find the missing bracket, wrong type, or uninitialized variable themselves.&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;## Technical Domain Standards&lt;/span&gt;

&lt;span class="c1"&gt;### Code Quality Checklist&lt;/span&gt;
&lt;span class="na"&gt;All code snippets provided by this skill MUST observe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="na"&gt;* **PEP 8 Guidelines**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;4-space indentation, `snake_case` for variables/functions, `PascalCase` for classes, UPPERCASE for constants.&lt;/span&gt;
&lt;span class="na"&gt;* **Type Hinting**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Include type annotations (`from typing import Optional, List, Dict...` or Python 3.10+ native syntax like `int | None`).&lt;/span&gt;
&lt;span class="na"&gt;* **Pythonic Idioms**&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;*&lt;/span&gt; &lt;span class="s"&gt;Use `enumerate()` instead of `range(len())`.&lt;/span&gt;
  &lt;span class="s"&gt;* Use `zip()` for parallel iterations.&lt;/span&gt;
  &lt;span class="s"&gt;* Use dictionary `.get()` or `defaultdict` for missing key safety.&lt;/span&gt;
  &lt;span class="s"&gt;* Use context managers (`with open(...)`) for resource management.&lt;/span&gt;
  &lt;span class="s"&gt;* Use generators for large data streams to conserve memory.&lt;/span&gt;

&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;## Scenario Behavior Matrix&lt;/span&gt;

&lt;span class="pi"&gt;|&lt;/span&gt; &lt;span class="err"&gt;User&lt;/span&gt; &lt;span class="err"&gt;Trigger&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="err"&gt;Primary&lt;/span&gt; &lt;span class="err"&gt;Response&lt;/span&gt; &lt;span class="err"&gt;Strategy&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; :--- | :--- |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; *"Explain [Concept]"* | Use 3-Tier Breakdown (Analogy → Code → Internal Mechanism). |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; *"Why does my code fail?"* + Error Log | Decode stack trace bottom-up; explain exception type; prompt user for line-level bug fix. |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; *"Review my code"* | Apply L.I.F.T. Framework. Show "Good", "Needs Improvement", and "Pythonic Refinement" version. |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; *"Give me exercises for [Topic]"* | Provide 3 exercises: Easy (syntax), Medium (logic), Hard (edge-cases + optimization). |&lt;/span&gt;
&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="s"&gt; *"Just give me the answer"* | Provide the solution, but annotate every non-obvious line with inline pedagogical commentary. |&lt;/span&gt;

&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="s"&gt;--&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="s"&gt;# Terminology Glossary &amp;amp; Translation Style&lt;/span&gt;

&lt;span class="err"&gt;T&lt;/span&gt;&lt;span class="s"&gt;ranslate abstract Computer Science jargon into intuitive developer language:&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="s"&gt; **"Mutable vs. Immutable"**: "Can be changed in place (like a shopping list)" vs. "Cannot be changed after creation (like a printed contract; modifying it means creating a brand new contract)."&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="s"&gt; **"Dunder Methods (`__init__`, `__str__`)"**: "Special hooks that tell Python how standard operators or built-in functions should treat your custom objects."&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="s"&gt; **"Iterable vs. Iterator"**: "An Iterable is a book (you can read it from start to finish). An Iterator is a bookmark (it tracks where you currently are in the book)."&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="s"&gt; **"Decorators (`@syntax`)"**: "A wrapper that adds extra behavior around a function without altering the original function's core code."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ How to Implement This
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Web LLMs (ChatGPT / Claude / Lumo AI / Gemini):&lt;/strong&gt; Copy everything &lt;em&gt;below&lt;/em&gt; the top YAML frontmatter (&lt;code&gt;---&lt;/code&gt;) and paste it directly into your platform's Custom Instructions or System Prompt section.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Frameworks (Claude Code, OpenClaw, Codex CLI):&lt;/strong&gt; Save the file as &lt;code&gt;python-senior-teacher/SKILL.md&lt;/code&gt; inside your project's &lt;code&gt;skills/&lt;/code&gt; directory. The agent runner will pick up the YAML configuration and load the skill whenever Python learning or code review topics come up.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💬 Over to You: How Can We Improve This?
&lt;/h2&gt;

&lt;p&gt;I’m sharing this because I want to make tech mentorship accessible to everyone, regardless of whether they can afford formal computer science education. &lt;/p&gt;

&lt;p&gt;To the educators, senior devs, and self-taught coders in the DEV community: &lt;strong&gt;What is missing here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are there specific pedagogical anti-patterns or bad developer habits this skill should actively discourage?&lt;/li&gt;
&lt;li&gt;How would you adapt or tweak the &lt;strong&gt;L.I.F.T.&lt;/strong&gt; framework or Socratic scaffolding?&lt;/li&gt;
&lt;li&gt;Would you add any specific modern Python standards (e.g., Python 3.12/3.13 features, &lt;code&gt;asyncio&lt;/code&gt; rules, typing enforcement)?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop your thoughts, critiques, or suggestions in the comments below!&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>learning</category>
    </item>
    <item>
      <title>How I Built a Zero-Trust Docker Sandbox for AI Coding Agents &amp; Untrusted Repos</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Mon, 24 Aug 2026 18:46:36 +0000</pubDate>
      <link>https://dev.to/henderson01/how-i-built-a-zero-trust-docker-sandbox-for-ai-coding-agents-untrusted-repos-4o7b</link>
      <guid>https://dev.to/henderson01/how-i-built-a-zero-trust-docker-sandbox-for-ai-coding-agents-untrusted-repos-4o7b</guid>
      <description>&lt;p&gt;My vision a lightweight, permission-headache-free Docker setup for running OpenCode, uv, and untrusted Python code without risking your host OS.&lt;/p&gt;

&lt;p&gt;When contributing to unfamiliar open-source projects or letting AI coding agents (like &lt;code&gt;OpenCode&lt;/code&gt;) run terminal commands, there's always a slight hesitation. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;What if a build script touches my system Python, or a rogue command wipes host files?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To solve this, I built &lt;strong&gt;&lt;code&gt;saferun&lt;/code&gt;&lt;/strong&gt; a zero-trust, disposable Docker sandbox designed specifically for Python developers and AI agent workflows on macOS and Linux.&lt;/p&gt;

&lt;p&gt;Here’s how it works, the permission nightmares I had to solve, and how you can set it up in under two minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal
&lt;/h2&gt;

&lt;p&gt;I wanted a workspace that gave me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Absolute Isolation:&lt;/strong&gt; Runtime scripts, &lt;code&gt;pytest&lt;/code&gt;, &lt;code&gt;ruff&lt;/code&gt;, and AI agent commands execute strictly inside a disposable Linux container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless IDE Integration:&lt;/strong&gt; Files edited inside PyCharm or VS Code on the host machine sync instantly with the container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Permission Headaches:&lt;/strong&gt; Any files generated inside the sandbox belong to my host user account—not &lt;code&gt;root&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistent Speed:&lt;/strong&gt; Package downloads cached permanently via &lt;code&gt;uv&lt;/code&gt; so environment startup stays millisecond-fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolated Credentials:&lt;/strong&gt; Global SSH and Git keys remain safely on the host machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solving the "Non-Root" Docker Nightmare
&lt;/h2&gt;

&lt;p&gt;The hardest part of containerized dev environments is file ownership. If you run Docker as &lt;code&gt;root&lt;/code&gt;, any file your AI agent generates belongs to &lt;code&gt;root&lt;/code&gt;, locking you out on your host machine. &lt;/p&gt;

&lt;p&gt;If you pass your local user ID (&lt;code&gt;-u "$(id -u):$(id -g)"&lt;/code&gt;), Docker mounts non-existent directories as &lt;code&gt;root:root&lt;/code&gt;, causing &lt;code&gt;Permission Denied&lt;/code&gt; crashes when tools like &lt;code&gt;uv&lt;/code&gt; try to write to cache folders.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;saferun&lt;/code&gt; solves this inside the base Dockerfile by pre-creating cache directories and granting open write permissions upfront:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.12-slim&lt;/span&gt;

&lt;span class="c"&gt;# Install curl and essential build tools&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nt"&gt;--no-install-recommends&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl &lt;span class="se"&gt;\
&lt;/span&gt;    build-essential &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Install uv globally&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-cache-dir&lt;/span&gt; uv

&lt;span class="c"&gt;# Install OpenCode, copy the binary, and clean up installer leftovers&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://opencode.ai/install | bash &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    find /root &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"opencode"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; /usr/local/bin/ &lt;span class="se"&gt;\;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /root/.cache /root/.local /tmp/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Pre-create paths and fix permissions for dynamic non-root UIDs&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /uv-cache /app-data /tmp/.config &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;777 /uv-cache /app-data /tmp/.config

&lt;span class="c"&gt;# Fix the "I have no name!" prompt for dynamic UIDs&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'export PS1="Docker Terminal:\w\$ "'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/bash.bashrc

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["bash"]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The One-Liner Alias:
&lt;/h2&gt;

&lt;p&gt;Once the base image is built, everything ties together into a single terminal alias added to your ~/.zshrc or ~/.bashrc:&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;alias &lt;/span&gt;&lt;span class="nv"&gt;saferun&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'docker run --rm -it -u "$(id -u):$(id -g)" -e HOME=/tmp -e UV_CACHE_DIR=/uv-cache -e XDG_DATA_HOME=/app-data -v "$(pwd):/app" -v uv-cache:/uv-cache -v ~/.config/opencode:/tmp/.config/opencode -v ~/.local/share/opencode:/app-data/opencode -w /app saferun-base'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this does under the hood:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--rm&lt;/code&gt;: Destroys the container instantly when you type exit.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v "$(pwd):/app"&lt;/code&gt;: Live-mounts your current working directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v uv-cache:/uv-cache&lt;/code&gt;: Mounts a dedicated Docker volume for package caching.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v ~/.config/opencode...&lt;/code&gt;: Maps your host OpenCode login and agents.md settings so you don't have to re-authenticate every session.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Workflow in Action:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clone any repository locally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open your terminal at the project root and type &lt;code&gt;saferun&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You are now inside an isolated Linux shell. Run untrusted code, let &lt;code&gt;uv&lt;/code&gt; handle dependencies (&lt;code&gt;uv run pytest&lt;/code&gt;), or ask &lt;code&gt;opencode&lt;/code&gt; to refactor code safely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Type &lt;code&gt;exit&lt;/code&gt;. The container vanishes, while all code edits remain safely saved on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check out the Repo:
&lt;/h2&gt;

&lt;p&gt;The full step-by-step setup guide and Dockerfile details are open-source on GitHub.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/henderson-01/saferun" rel="noopener noreferrer"&gt;github.com/henderson-01/saferun&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;If you try it out or have ideas to improve it, I'd love to hear your feedback in the comments!&lt;/p&gt;

</description>
      <category>python</category>
      <category>docker</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Beyond For Loops: My Journey to Python, AI Agents, and "Vibe Coding" as a Self-Taught Dev</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Fri, 07 Aug 2026 23:25:14 +0000</pubDate>
      <link>https://dev.to/henderson01/beyond-for-loops-my-journey-to-python-ai-agents-and-vibe-coding-as-a-self-taught-dev-fml</link>
      <guid>https://dev.to/henderson01/beyond-for-loops-my-journey-to-python-ai-agents-and-vibe-coding-as-a-self-taught-dev-fml</guid>
      <description>&lt;p&gt;When I first decided to learn Python, I quickly ran into a wall that a lot of aspiring developers face: time and money.&lt;/p&gt;

&lt;p&gt;Being based in the UK with strict time restrictions, I couldn't afford a top-tier bootcamp or college course. On top of that, my local colleges simply weren't offering anything focused on Python development. So, I took the only route available to me: I became a self-directed learner.&lt;/p&gt;

&lt;p&gt;Things have been going really well, but my learning path has taken some unexpected turns. Here is what I’ve learned about navigating the modern junior developer landscape.&lt;/p&gt;

&lt;p&gt;Building the Foundation (The Hard Way)&lt;br&gt;
In the beginning, it was just me, a code editor, and the internet. I lived in books, practically memorised YouTube tutorials, and scoured GitHub repositories to see how real applications were structured.&lt;/p&gt;

&lt;p&gt;I’m still fully committed to progressing in manual coding. Knowing how to write for loops, build functions, and structure classes is the bedrock of everything we do. But as I started looking around at this ever-evolving industry, I had a massive realisation: just understanding and being able to write manual code is no longer enough.&lt;/p&gt;

&lt;p&gt;My New Pair Programmer: AI&lt;br&gt;
Because I didn't have a senior developer sitting next to me, I started leveraging AI. But I didn't just use it to generate code snippets. I started treating AI as my:&lt;/p&gt;

&lt;p&gt;Teacher &amp;amp; Mentor: Breaking down complex computer science concepts.&lt;/p&gt;

&lt;p&gt;Debugger: Helping me spot the missing colon or logical error that had me stuck for hours.&lt;/p&gt;

&lt;p&gt;Friend / Pair Developer: Bouncing architectural ideas back and forth before writing a single line of code.&lt;/p&gt;

&lt;p&gt;Using AI this way opened my eyes to where the industry is heading.&lt;/p&gt;

&lt;p&gt;The Epiphany: Welcome to the "Vibe Coding" Era&lt;br&gt;
If you’ve been hanging around dev communities lately, you’ve probably heard the term "vibe coding." It’s the idea that developers are increasingly prompting, testing, and iterating alongside AI to build software, rather than typing out every single line by hand.&lt;/p&gt;

&lt;p&gt;I feel like this has almost become a mandatory part of the job. Companies hiring junior developers today want more than just someone who knows syntax. They want someone who can orchestrate AI. The career path for a junior coder has fundamentally shifted.&lt;/p&gt;

&lt;p&gt;Levelling Up: Agents, Skills, and MCP Servers&lt;br&gt;
Because of this shift, I decided to dive headfirst into AI engineering concepts to complement my Python skills. Right now, I'm doing extra study on:&lt;/p&gt;

&lt;p&gt;AI Agents &amp;amp; Skills: How to build agents, give them specific tools (skills), and get them to work autonomously on complex tasks.&lt;/p&gt;

&lt;p&gt;MCP (Model Context Protocol) Servers: Learning how MCPs securely connect AI models to external tools, file systems, and databases to give them real-world context.&lt;/p&gt;

&lt;p&gt;Local vs. Cloud Models: I’m actively testing workflows on cloud-based LLMs as well as local models to understand the tradeoffs in privacy, speed, and capability.&lt;/p&gt;

&lt;p&gt;OpenCode Environment: I'm using OpenCode (both the Desktop app and the CLI) to experiment with these agentic workflows in real-time.&lt;/p&gt;

&lt;p&gt;My Thoughts&lt;br&gt;
The barrier to entry is changing. The floor isn't just "can you write a function?" anymore; it's "can you read, review, and direct an AI to build a scalable system?"&lt;/p&gt;

&lt;p&gt;I'm incredibly grateful for the manual foundation I’ve built, because without it, vibe coding just turns into blind copy-pasting. But by combining my self-taught Python fundamentals with learning a deep understanding of Agents and MCP servers, I finally feel like I'm not just learning to code; I'm learning how to build software in 2026.&lt;/p&gt;

&lt;p&gt;Are there any other self-taught devs out there balancing manual coding with AI agents? I’d love to hear what tools you are testing in the comments!&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>career</category>
      <category>beginners</category>
    </item>
    <item>
      <title>[ShowDev] I built a Git terminal dashboard in Python (my first proper project!) and would love some feedback 🚀</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Tue, 04 Aug 2026 20:29:42 +0000</pubDate>
      <link>https://dev.to/henderson01/showdev-i-built-a-git-terminal-dashboard-in-python-my-first-proper-project-and-would-love-some-3hmb</link>
      <guid>https://dev.to/henderson01/showdev-i-built-a-git-terminal-dashboard-in-python-my-first-proper-project-and-would-love-some-3hmb</guid>
      <description>&lt;p&gt;Hey DEV community! 👋&lt;/p&gt;

&lt;p&gt;I’m currently learning Python and building my skills as a developer. Because I don't know many other developers in real life to ask for advice, I’m hoping to borrow a few minutes of your time!&lt;/p&gt;

&lt;p&gt;I recently finished building my first "proper" project, and I would love to get some fresh eyes on the code.&lt;/p&gt;

&lt;p&gt;🛠 What I Built&lt;br&gt;
It's called giteyes. It is a Python-based terminal dashboard that lets you explore a repository's git commit activity, view heatmaps, and track file churn hotspots directly from the command line.&lt;/p&gt;

&lt;p&gt;You can check out the repository here:&lt;br&gt;
👉 &lt;a href="https://github.com/henderson-01/giteyes" rel="noopener noreferrer"&gt;https://github.com/henderson-01/giteyes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Why I Built It&lt;br&gt;
I wanted a way to quickly visualise Git history without leaving the terminal or opening up a web browser, and I figured building a CLI (Command Line Interface) tool would be the perfect way to push my Python skills further.&lt;/p&gt;

&lt;p&gt;🔍 What I’m Looking For&lt;br&gt;
Since this is my first major project, I know there is a lot I don't know yet. I would be incredibly grateful for any feedback, but I'm specifically curious about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Structure:&lt;/strong&gt; Are my Python files logically organised?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt; Are there any glaring anti-patterns or non-Pythonic ways I'm doing things?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt; How does it behave if you feed it a weird repository?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;General Readability:&lt;/strong&gt; Is the code easy to follow?&lt;/p&gt;

&lt;p&gt;Please feel free to be completely honest; I'm here to learn and improve, still a bit nervous though. You can drop a comment below or open an issue on GitHub if you spot something specific.&lt;/p&gt;

&lt;p&gt;Thank you so much in advance to anyone who takes the time to look! Happy coding!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>beginners</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How Local AI Became My 24/7 Python Tutor (Without Doing the Work for Me)</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Fri, 31 Jul 2026 14:04:00 +0000</pubDate>
      <link>https://dev.to/henderson01/how-local-ai-became-my-247-python-tutor-without-doing-the-work-for-me-5en</link>
      <guid>https://dev.to/henderson01/how-local-ai-became-my-247-python-tutor-without-doing-the-work-for-me-5en</guid>
      <description>&lt;p&gt;When people talk about using AI for coding, the conversation usually goes straight to "AI writes all my code now."&lt;/p&gt;

&lt;p&gt;That isn't how I use it, and honestly, if you're trying to actually learn, letting an LLM write your entire project defeats the purpose.&lt;/p&gt;

&lt;p&gt;For me, AI has completely changed my Python learning journey, not as an automated code generator, but as a personal, 24/7 tutor that helps me debug, unpack complex logic, and write cleaner code. Best of all? I run everything locally, keeping my code completely private.&lt;/p&gt;

&lt;p&gt;Here is how I use local LLMs to accelerate my learning without shortcuts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning Concepts by Example (The args and kwargs Paradigm).
When you're learning object-oriented programming (OOP), reading static documentation can sometimes feel abstract. If I want to see how kwargs work inside an OOP class hierarchy, I don't ask the AI to "write my project for me."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, I ask for a minimal, targeted example:&lt;/p&gt;

&lt;p&gt;"Can you show me a simple example of passing kwargs up to a parent class's init method in Python?"&lt;/p&gt;

&lt;p&gt;Once the AI gives me a 10-line example, I break down what each line is doing and apply that pattern to my own project in my own way. It’s like having a teacher standing at a whiteboard who draws a diagram, answers your specific question, and then lets you go back to your desk to build the actual feature.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Having a 24/7 Debugging Partner.
We’ve all spent hours staring at a Python traceback, missing a simple scoping issue or a subtle type mismatch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of getting stuck late at night, I paste the error message along with my logic into my local LLM. Rather than just taking a fixed line of code, I ask:&lt;/p&gt;

&lt;p&gt;"Why is this KeyError happening here?"&lt;/p&gt;

&lt;p&gt;"What is the flow of execution that leads to this TypeError?"&lt;/p&gt;

&lt;p&gt;It instantly spots the logic flaw and explains why it failed. I get the answer immediately, understand the mistake, fix it myself, and move on, without waiting for a response on forum posts or struggling alone for hours.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning to Write Readable Code.
Getting code to run is only half the battle; writing code that is readable and Pythonic is the other.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I get a feature working (even if it looks like messy "spaghetti code"), I’ll pass it to the AI with a prompt like:&lt;/p&gt;

&lt;p&gt;"This code works, but how can I make it more readable and follow PEP 8 standards? Explain why your suggested changes are better."&lt;/p&gt;

&lt;p&gt;It might suggest turning a clunky for loop into a list comprehension, breaking a massive function down into smaller helper functions, or using better variable names. Reading those explanations helps me train my brain to write cleaner code on the first try next time.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unpacking Complex Logic.
Sometimes you encounter a library function or an algorithm that feels like magic. Instead of blindly trusting it, I use the AI to deconstruct it step by step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I can ask it to walk through a function loop by loop, telling me what the variable states are at each iteration. Having an interactive tutor that never gets tired of answering "But why did that variable change here?" makes deep technical concepts stick much faster.&lt;/p&gt;

&lt;p&gt;Why Local LLMs Are the Sweet Spot&lt;br&gt;
One rule I stick to is running local LLMs for my coding work.&lt;/p&gt;

&lt;p&gt;Complete Privacy: Your code, projects, and ideas stay entirely on your hardware. Nothing is sent to an external server or used to train public models.&lt;/p&gt;

&lt;p&gt;Offline Access: You can code and learn anywhere, even without an internet connection.&lt;/p&gt;

&lt;p&gt;No Limits: You don't have to worry about running out of daily prompts or hitting rate limits while you're deep in a learning session.&lt;/p&gt;

&lt;p&gt;Modern open weight models (like Qwen Coder, Llama, or DeepSeek Coder running via Ollama or LM Studio) are more than powerful enough to serve as top tier Python mentors on a consumer machine.&lt;/p&gt;

&lt;p&gt;My Thoughts.&lt;/p&gt;

&lt;p&gt;AI shouldn't be a crutch that replaces thinking; it should be an amplifier for your curiosity.&lt;/p&gt;

&lt;p&gt;By treating a local LLM as a 24/7 mentor, asking it for isolated examples, requesting explanations of error messages, and studying its suggestions for readable code, you learn significantly faster while still building the actual muscle memory of writing Python yourself.&lt;/p&gt;

&lt;p&gt;How are you using AI in your developer journey? Are you running local models or relying on cloud tools? Let me know in the comments! &lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>Building Alien Invasion: My Journey Through Python Crash Course</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Wed, 29 Jul 2026 16:54:19 +0000</pubDate>
      <link>https://dev.to/henderson01/building-alien-invasion-my-journey-through-python-crash-course-1p53</link>
      <guid>https://dev.to/henderson01/building-alien-invasion-my-journey-through-python-crash-course-1p53</guid>
      <description>&lt;p&gt;Hey everyone! 👋 &lt;/p&gt;

&lt;p&gt;As part of my learning journey, I'm currently working through the 3rd edition of Eric Matthes' Python Crash Course.&lt;/p&gt;

&lt;p&gt;I've just hit the famous Alien Invasion project (I'm on page 283), building the Pygame arcade game from scratch. &lt;/p&gt;

&lt;p&gt;Since I've already used OOP quite a bit in previous projects—like building desktop GUIs with customtkinter. &lt;/p&gt;

&lt;p&gt;It’s been really cool to see how those same concepts apply to game loops, sprite management, and real-time user input handling.&lt;/p&gt;

&lt;p&gt;Once I wrap up the base project, I plan to:&lt;/p&gt;

&lt;p&gt;Make the repository public on GitHub.&lt;/p&gt;

&lt;p&gt;Create a second branch to add a few custom extras (Not sure what they will be yet).&lt;/p&gt;

&lt;p&gt;Is anyone else currently working through this book or building Pygame projects? I'd love to connect, trade tips, or see what extra features you added to your game! &lt;/p&gt;

</description>
      <category>python</category>
      <category>learning</category>
      <category>beginners</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Hi, I'm Mr Henderson! 👋 Self-Directed Developer Joining DEV</title>
      <dc:creator>Carl Henderson</dc:creator>
      <pubDate>Tue, 28 Jul 2026 23:29:31 +0000</pubDate>
      <link>https://dev.to/henderson01/hi-im-mr-henderson-self-directed-developer-joining-dev-4c24</link>
      <guid>https://dev.to/henderson01/hi-im-mr-henderson-self-directed-developer-joining-dev-4c24</guid>
      <description>&lt;p&gt;I'm Mr Henderson, a self-directed student developer. My coding journey so far has been entirely self-taught, relying on incredible free resources like YouTube, books, and freeCodeCamp.&lt;/p&gt;

&lt;p&gt;Over on my GitHub, I've built a variety of small scripts and mini-projects to test my skills and build my muscle memory. I recently made a project that I’m particularly proud of. I like it, so I've pinned it to my DEV profile if you'd like to check it out! And maybe leave me some feedback; that would be great.&lt;/p&gt;

&lt;p&gt;I joined DEV.to to connect with other developers, follow along with what people are building, and keep growing my skills and learning journey and maybe get some help and feedback on my learning.&lt;/p&gt;

&lt;p&gt;Glad to be here! Thankyou&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>beginners</category>
      <category>showdev</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
