<?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: Alex </title>
    <description>The latest articles on DEV Community by Alex  (@upstood).</description>
    <link>https://dev.to/upstood</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%2F3867440%2F0f92e308-f422-407d-b558-73be7c120c4a.png</url>
      <title>DEV Community: Alex </title>
      <link>https://dev.to/upstood</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/upstood"/>
    <language>en</language>
    <item>
      <title>Give Your Auditor AWS Access — Without Sharing a Single Credential</title>
      <dc:creator>Alex </dc:creator>
      <pubDate>Fri, 10 Jul 2026 19:20:42 +0000</pubDate>
      <link>https://dev.to/upstood/give-your-auditor-aws-access-without-sharing-a-single-credential-140k</link>
      <guid>https://dev.to/upstood/give-your-auditor-aws-access-without-sharing-a-single-credential-140k</guid>
      <description>&lt;p&gt;If your auditor asks for that, that should be the first finding. 🚩&lt;/p&gt;

&lt;p&gt;An external auditor needs access to your AWS accounts, and the first instinct in most companies is one of two things: create an IAM user and share the access keys, or provision the auditor a user in your identity provider so they can log into the console.&lt;/p&gt;

&lt;p&gt;Neither is necessary. An auditor doesn’t need a login in your organization at all — API access is enough. And AWS has had a mechanism for exactly this situation for over a decade. It’s the same one AWS partners and every third-party monitoring tool use:&lt;/p&gt;

&lt;p&gt;A cross-account IAM role with a trust relationship. No credentials ever change hands.&lt;/p&gt;

&lt;p&gt;In this article I’ll walk through how the pattern works and share two CloudFormation templates I built — one for a single AWS account, one that covers an entire AWS Organization. You can deploy either in about five minutes. Both templates are also on GitHub: &lt;a href="https://github.com/up-cdk/aws-audit-access" rel="noopener noreferrer"&gt;https://github.com/up-cdk/aws-audit-access&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just create a user?
&lt;/h2&gt;

&lt;p&gt;Because every credential you create is a liability you now own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Access keys are long-lived. They work until someone remembers to delete them. Every audit I’ve read about that went wrong involved keys that outlived the engagement.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passwords get shared insecurely. Email, Slack, a text message — the moment credentials travel, you’ve lost control of where they end up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IdP users pollute your directory. An external party in your identity provider inherits whatever group memberships and app assignments someone clicks together, and deprovisioning is a manual step someone has to remember.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The pattern: cross-account role + External ID
&lt;/h2&gt;

&lt;p&gt;The idea is simple. Instead of giving the auditor your credentials, you create a role in your account that the auditor’s own AWS account is allowed to assume.&lt;/p&gt;

&lt;p&gt;Four pieces make it safe:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The trust policy names exactly one AWS account — the auditor’s. Not a user, not a password: an account-to-account trust. The auditor authenticates in their account with their credentials, then calls STS &lt;code&gt;AssumeRole&lt;/code&gt; to get temporary credentials for the role in yours.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An External ID guards the trust. This is a shared secret agreed between you and the auditor, set as a condition on the trust policy. Without presenting it, the role cannot be assumed — even by the trusted account. This protects against the &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html" rel="noopener noreferrer"&gt;confused deputy problem&lt;/a&gt;: if the auditor works with many clients, a malicious client can’t trick the auditor’s tooling into accessing your account, because they don’t know your External ID.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All access is temporary. STS sessions expire (1 hour by default in these templates, configurable). There is no long-lived credential anywhere in the setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Everything is logged. Every &lt;code&gt;AssumeRole&lt;/code&gt; call and every API call the auditor makes lands in your CloudTrail, attributable to the audit role’s session. You can see exactly what was looked at, and when.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And the permissions? Read-only, and scoped for the job: AWS’s managed &lt;code&gt;ReadOnlyAccess&lt;/code&gt; and &lt;code&gt;SecurityAudit&lt;/code&gt; policies, optionally &lt;code&gt;AWSBillingReadOnlyAccess&lt;/code&gt; for cost review, plus a small supplementary policy for audit-relevant services the managed policies miss (GuardDuty findings, Security Hub, Cost Explorer, Trusted Advisor, and a few others).&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: single account
&lt;/h2&gt;

&lt;p&gt;Deploy this template in the account being audited. Two parameters matter: the auditor’s 12-digit AWS account ID, and the External ID they give you.&lt;/p&gt;

&lt;p&gt;Template: aws-audit-readonly-role.yaml in the GitHub repo — &lt;a href="https://github.com/up-cdk/aws-audit-access" rel="noopener noreferrer"&gt;https://github.com/up-cdk/aws-audit-access&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deploy it from the console (CloudFormation → Create stack → Upload template), or from the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudformation deploy &lt;span class="nt"&gt;--template-file&lt;/span&gt; aws-audit-readonly-role.yaml &lt;span class="nt"&gt;--stack-name&lt;/span&gt; external-audit-access &lt;span class="nt"&gt;--capabilities&lt;/span&gt; CAPABILITY_NAMED_IAM  &lt;span class="nt"&gt;--parameter-overrides&lt;/span&gt; &lt;span class="nv"&gt;AuditorAWSAccountId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;111122223333 &lt;span class="nv"&gt;ExternalId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;the-external-id-from-your-auditor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then send the auditor the role ARN from the stack outputs. That’s it — that’s the entire exchange. An ARN is not a secret; combined with the External ID (which the auditor already has, since they generated it) and the trust policy, it’s everything they need and nothing more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: the entire AWS Organization
&lt;/h2&gt;

&lt;p&gt;Auditing one account is rare — most audits cover an Organization with anywhere from a handful to hundreds of member accounts. Creating the role by hand in each one doesn’t scale.&lt;/p&gt;

&lt;p&gt;The second template solves this with a service-managed CloudFormation StackSet. You deploy one stack in the management account, and it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;creates the audit role in the management account itself,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;creates a StackSet that rolls the same role out to every member account under the OUs you target (pass your root ID, e.g. &lt;code&gt;r-abcd&lt;/code&gt;, to cover the whole organization),&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;optionally auto-deploys to any new account added to those OUs later — no gaps if accounts are created mid-audit,&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;and tears everything down centrally when you delete the stack.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One prerequisite: service-managed StackSets require trusted access between AWS Organizations and CloudFormation to be activated (CloudFormation console → StackSets → “Activate trusted access”, a one-time click in the management account).&lt;/p&gt;

&lt;p&gt;Template: aws-audit-organization-stackset.yaml in the same repo. The deploy command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws cloudformation deploy  --template-file aws-audit-organization-stackset.yaml --stack-name external-audit-access-org --capabilities CAPABILITY_NAMED_IAM --parameter-overrides AuditorAWSAccountId=111122223333 ExternalId=the-external-id-from-your-auditor TargetOrganizationalUnitIds=r-abcd DeploymentRegions=us-east-1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;IAM is a global service, so one deployment region is enough for the stack instances.&lt;/p&gt;

&lt;p&gt;After deployment, every in-scope account contains a role with the same name, so the auditor can iterate over account IDs with a single ARN pattern:&lt;/p&gt;

&lt;p&gt;arn:aws:iam:::role/ExternalReadOnlyAuditRole&lt;/p&gt;

&lt;h2&gt;
  
  
  The auditor’s side
&lt;/h2&gt;

&lt;p&gt;From their own account, the auditor assumes the role:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;aws sts assume-role --role-arn arn:aws:iam::444455556666:role/ExternalReadOnlyAuditRole --role-session-name aws-audit  --external-id THE_EXTERNAL_ID&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For an organization audit, the auditor loops the same profile pattern over the account list — which they can fetch with &lt;code&gt;organizations:ListAccounts&lt;/code&gt;, included in the role’s permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ending the audit
&lt;/h2&gt;

&lt;p&gt;This is my favorite part, because it’s one line:&lt;/p&gt;

&lt;p&gt;aws cloudformation delete-stack --stack-name external-audit-access&lt;/p&gt;

&lt;p&gt;Delete the stack (or the org stack, which removes the StackSet instances from every member account). Access is gone. Nothing to rotate, nothing to deprovision, no forgotten IAM user with active keys waiting for the next auditor to find.&lt;/p&gt;

&lt;p&gt;The way you grant audit access says a lot about how you manage access everywhere else. If your next audit starts with “please create a user for us” — send them this article instead.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>security</category>
      <category>devops</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>I tried Karpathy's LLM Wiki pattern on my AWS consulting work — here's what changed</title>
      <dc:creator>Alex </dc:creator>
      <pubDate>Tue, 14 Apr 2026 00:22:22 +0000</pubDate>
      <link>https://dev.to/upstood/i-tried-karpathys-llm-wiki-pattern-on-my-aws-consulting-work-heres-what-changed-571g</link>
      <guid>https://dev.to/upstood/i-tried-karpathys-llm-wiki-pattern-on-my-aws-consulting-work-heres-what-changed-571g</guid>
      <description>&lt;p&gt;I tried Karpathy's LLM Wiki principle on my own AWS consulting work a few weeks ago, and I can't go back.&lt;/p&gt;

&lt;p&gt;If you missed it, Andrej Karpathy published a short gist called &lt;strong&gt;&lt;a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f" rel="noopener noreferrer"&gt;LLM Wiki: A Pattern for Persistent Knowledge Bases&lt;/a&gt;&lt;/strong&gt;. His thesis: instead of using RAG to re-derive answers from raw sources on every query, let the LLM maintain a persistent, compounding wiki. Humans curate sources and ask questions. The model handles the bookkeeping — summarizing, cross-linking, keeping pages consistent over time.&lt;/p&gt;

&lt;p&gt;So I tried it. I rebuilt my entire AWS consulting knowledge base around Karpathy's three-layer pattern. This post is what I actually did, what the folder looks like now, the frontmatter schema that makes it queryable by Claude Code skills, and the three rules I had to enforce to stop it from rotting.&lt;/p&gt;

&lt;p&gt;At the bottom there's a copy-pasteable Claude Code prompt that scaffolds the same structure in an empty directory — if you want to try it yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I tried this on AWS consulting specifically
&lt;/h2&gt;

&lt;p&gt;Every engagement I run has the same four information streams, and all four used to decay fast:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client-specific context&lt;/strong&gt; — their account structure, compliance posture, team, kickoff constraints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-project AWS patterns&lt;/strong&gt; — cross-account alarm routing, IAM boundaries, cost allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decisions&lt;/strong&gt; — why I picked Aurora over RDS for this client, what tradeoff I accepted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gotchas&lt;/strong&gt; — what broke, in what AWS service, under what conditions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before Karpathy's pattern, all four lived, well not in the same place let's say. Every new engagement brought the same conclusion that I was the bottleneck :).&lt;/p&gt;

&lt;p&gt;Now the LLM compiles it once and keeps it current for me. I'm not the bottleneck anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three layers, as I actually set them up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Layer 1 — Raw sources (immutable)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./raw/
├── assets/                      # Downloaded images, screenshots
├── aws-reinvent-2024-obs.md     # Clipped article
├── client-kickoff-2026-03.md    # Meeting transcript
├── datadog-quote-client-a.pdf   # Vendor docs
└── aws-bill-client-b-q1.csv     # Cost exports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Raw never changes. If the wiki layer gets corrupted or I change conventions, I can re-derive from raw. That immutability is what gave me the confidence to let Claude aggressively refactor the wiki.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2 — Wiki (LLM-maintained markdown)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./wiki/
├── projects/
│   ├── client-a/
│   │   ├── _status.md             # Dashboard — I start here every session
│   │   ├── client-a-overview.md   # Architecture + key decisions
│   │   ├── decisions/             # ADR-style, one file per decision
│   │   ├── workflows/             # Automation-ready procedures
│   │   └── gotchas/               # What broke and why
│   └── client-b/
├── sa/                            # Solutions architecture patterns (cross-client)
├── aws/                           # AWS service patterns + gotchas
└── standards/                     # CDK conventions, tagging, account standards
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One vault, per-client folders. Cross-client patterns live in &lt;code&gt;sa/&lt;/code&gt;, &lt;code&gt;aws/&lt;/code&gt;, &lt;code&gt;standards/&lt;/code&gt; — my opinion library. Client folders stay isolated so I never accidentally leak Client A's IAM choices into a Client B audit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3 — &lt;code&gt;CLAUDE.md&lt;/code&gt; (the schema)
&lt;/h3&gt;

&lt;p&gt;Karpathy calls this the "config for how the LLM operates on the wiki." For me, it's a single file at the vault root that defines the directory structure, the frontmatter schema, what belongs in the wiki and what doesn't, and the workflows I want Claude to follow (ingest a source, update &lt;code&gt;_status.md&lt;/code&gt;, lint for orphans).&lt;/p&gt;

&lt;p&gt;Change &lt;code&gt;CLAUDE.md&lt;/code&gt; and you change how every future Claude Code session operates on the vault. It's the load-bearing file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The frontmatter schema I landed on
&lt;/h2&gt;

&lt;p&gt;Every page has YAML frontmatter. Not for me to read — for skills to query:&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;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cross-account&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;CloudWatch&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;alarm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;routing"&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pattern&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;aws&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;cloudwatch&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;cross-account&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;observability&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;sources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;raw/aws-reinvent-2024-obs.md&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;client-a&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-03-02&lt;/span&gt;
&lt;span class="na"&gt;updated&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;2026-04-11&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;type&lt;/code&gt; field is the workhorse. Allowed values: &lt;code&gt;pattern | gotcha | decision | concept | process | status | workflow&lt;/code&gt;. When I run an audit skill, it reads only &lt;code&gt;type: gotcha&lt;/code&gt; and &lt;code&gt;type: decision&lt;/code&gt; pages — not the whole vault. That's the difference between fitting in the context window and blowing it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sources&lt;/code&gt; is non-negotiable for me. It keeps the agent honest when it synthesizes — every claim in the wiki traces back to something in raw.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first skill I wrote that made me a believer
&lt;/h2&gt;

&lt;p&gt;Here's the one that convinced me this was worth the effort: an &lt;code&gt;architecture-review&lt;/code&gt; skill I can run when a client proposes a change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&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;architecture-review&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;Reviews a proposed architecture change against client constraints and cross-client patterns&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

Inputs:
&lt;span class="p"&gt;1.&lt;/span&gt; Client name (must match a folder in wiki/projects/)
&lt;span class="p"&gt;2.&lt;/span&gt; Proposed change (free text or linked diagram)

Steps:
&lt;span class="p"&gt;1.&lt;/span&gt; Read wiki/projects/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;/_status.md for current phase and constraints
&lt;span class="p"&gt;2.&lt;/span&gt; Read wiki/projects/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;-overview.md for architecture baseline
&lt;span class="p"&gt;3.&lt;/span&gt; Query wiki/sa/ and wiki/aws/ for pages where tags intersect with the change
&lt;span class="p"&gt;4.&lt;/span&gt; Query wiki/projects/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;/gotchas/ for anything relevant
&lt;span class="p"&gt;5.&lt;/span&gt; Query wiki/projects/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;/decisions/ for prior decisions that constrain this change
&lt;span class="p"&gt;6.&lt;/span&gt; Produce a review document with:
&lt;span class="p"&gt;   -&lt;/span&gt; Compatibility with existing architecture
&lt;span class="p"&gt;   -&lt;/span&gt; Relevant cross-client patterns that apply
&lt;span class="p"&gt;   -&lt;/span&gt; Prior decisions that would be affected
&lt;span class="p"&gt;   -&lt;/span&gt; Gotchas that could bite
&lt;span class="p"&gt;   -&lt;/span&gt; Recommended next steps

Output: wiki/projects/&lt;span class="nt"&gt;&amp;lt;client&amp;gt;&lt;/span&gt;/decisions/&lt;span class="nt"&gt;&amp;lt;YYYY-MM-DD&amp;gt;&lt;/span&gt;-&lt;span class="nt"&gt;&amp;lt;slug&amp;gt;&lt;/span&gt;.md (draft for human review)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's no magic prompt here. The whole point is that the skill is running against &lt;strong&gt;structured, maintained context&lt;/strong&gt; — not a blank LLM. The quality of the output is about the quality of the wiki, not the prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three rules I had to enforce
&lt;/h2&gt;

&lt;p&gt;Karpathy warns that maintenance is what kills human wikis. Even with an LLM doing the work, I found three rules that actually matter in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontmatter or it didn't happen.&lt;/strong&gt; No frontmatter = skills can't index it. I make Claude add frontmatter before content on every new page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;_status.md&lt;/code&gt; updates at session end, not start.&lt;/strong&gt; I set up a Claude Code Stop hook that blocks me from ending a session until the dashboard moves forward. Without the hook, dashboards went stale inside a week.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One page, one concept.&lt;/strong&gt; Gotchas get their own pages, not subheadings under a shared "troubleshooting.md". The retrieval unit is a page — keep it small enough that multiple fit in context without bleed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What actually changed in my work
&lt;/h2&gt;

&lt;p&gt;Three concrete things shifted after a few weeks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture designs are regenerated, not rewritten.&lt;/strong&gt; A client constraint changes → I update the relevant page → rerun the design skill → new design doc. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audits are reproducible.&lt;/strong&gt; Same vault + same skill on the same day = same findings. I couldn't get that property out of ad-hoc Claude chats no matter how careful I was with prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handover is the deliverable.&lt;/strong&gt; At the end of an engagement, the client gets the CDK &lt;em&gt;and&lt;/em&gt; their vault folder. The vault &lt;em&gt;is&lt;/em&gt; the documentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The output layer
&lt;/h2&gt;

&lt;p&gt;Everything Claude generates in my setup ends up as CDK. I open-sourced the constructs at &lt;strong&gt;up-cdk&lt;/strong&gt; — compliance-aligned building blocks for S3, VPC, pipelines, so every stack is compliant by default. Wiki + skills + opinionated output library is the combination that finally made the setup reproducible across clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to try it — the bootstrap prompt
&lt;/h2&gt;

&lt;p&gt;The fastest way to see if this pattern works for you is to try it. Here's the Claude Code prompt I use to scaffold the whole structure in an empty directory. No scripts, no deps, just markdown and conventions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;You are setting up a new LLM Wiki following Andrej Karpathy's pattern
(https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f),
adapted for AWS consulting / platform engineering work.

The wiki has three layers:
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`raw/`&lt;/span&gt; — immutable source material (meeting notes, clipped articles, bills, screenshots)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`wiki/`&lt;/span&gt; — LLM-maintained markdown synthesized from raw + conversation
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="sb"&gt;`CLAUDE.md`&lt;/span&gt; at the root — the schema document that tells you how to operate on the wiki

Create the following structure in the current directory. For every file below,
create it with the frontmatter and seed content described. Do not skip any
file. Do not invent additional files.

&lt;span class="gu"&gt;## Directory tree&lt;/span&gt;

./
├── CLAUDE.md
├── index.md
├── log.md
├── raw/
│   ├── assets/.gitkeep
│   └── README.md
├── templates/
│   ├── project-status.md
│   ├── page.md
│   └── workflow.md
└── wiki/
    ├── projects/
    │   └── _example-client/
    │       ├── _status.md
    │       ├── _example-client-overview.md
    │       ├── decisions/.gitkeep
    │       ├── workflows/.gitkeep
    │       ├── gotchas/.gitkeep
    │       └── diagrams/.gitkeep
    ├── sa/.gitkeep
    ├── aws/.gitkeep
    └── standards/.gitkeep

&lt;span class="gu"&gt;## CLAUDE.md (the schema document)&lt;/span&gt;

Write a root CLAUDE.md that defines:
&lt;span class="p"&gt;-&lt;/span&gt; Purpose: personal AWS knowledge base following Karpathy's LLM Wiki pattern.
&lt;span class="p"&gt;-&lt;/span&gt; The three layers: raw/ (immutable), wiki/ (LLM-generated), CLAUDE.md (schema).
&lt;span class="p"&gt;-&lt;/span&gt; What belongs in the wiki: durable knowledge (gotchas, decisions, patterns,
  strategy, workflows, status dashboards). What does NOT belong: raw doc
  summaries, git state, ephemeral task context.
&lt;span class="p"&gt;-&lt;/span&gt; Page format — every wiki page must have YAML frontmatter with fields:
  title, type (pattern | gotcha | decision | concept | process | status |
  workflow), tags, sources, created, updated.
&lt;span class="p"&gt;-&lt;/span&gt; File naming — kebab-case. Overview files: &lt;span class="nt"&gt;&amp;lt;project&amp;gt;&lt;/span&gt;-overview.md. Status
  files: _status.md (underscore prefix sorts to top).
&lt;span class="p"&gt;-&lt;/span&gt; Cross-references — [[filename]] Obsidian-style wiki links.
&lt;span class="p"&gt;-&lt;/span&gt; Every page ends with a ## Related section.
&lt;span class="p"&gt;-&lt;/span&gt; Workflows (document all four):
&lt;span class="p"&gt;  1.&lt;/span&gt; Quick context recovery at session start — read
     wiki/projects/&lt;span class="nt"&gt;&amp;lt;project&amp;gt;&lt;/span&gt;/_status.md first.
&lt;span class="p"&gt;  2.&lt;/span&gt; Update _status.md at session end — refresh Last/Next session lines,
     append one row to Session History (keep last 5), update Recent Decisions
     and Open Questions, set updated: to today.
&lt;span class="p"&gt;  3.&lt;/span&gt; Ingest a raw source — read thoroughly, write/update pages in the right
     wiki/ subdirectory, cross-link, update index.md, append to log.md.
&lt;span class="p"&gt;  4.&lt;/span&gt; Lint — find orphan pages, stale content, missing back-links.
&lt;span class="p"&gt;-&lt;/span&gt; Common tags taxonomy — starter list for AWS, SA, meta tags.
&lt;span class="p"&gt;-&lt;/span&gt; Persistence layer rules — wiki is the single source of truth for durable
  knowledge.

&lt;span class="gu"&gt;## index.md&lt;/span&gt;
A one-page catalog. Headers for each top-level wiki directory (## Projects,
&lt;span class="gu"&gt;## Solutions Architecture, ## AWS, ## Standards), each with "No pages yet."&lt;/span&gt;

&lt;span class="gu"&gt;## log.md&lt;/span&gt;
Append-only activity log. Seed with today's date and "Initialized wiki
following Karpathy LLM Wiki pattern."

&lt;span class="gu"&gt;## templates/project-status.md&lt;/span&gt;
Template for _status.md files. type: status. Sections: Phase, Last session,
Next session, Current State, Recent Decisions, Open Questions, Session
History (Date | Summary table), Quick Links.

&lt;span class="gu"&gt;## templates/page.md&lt;/span&gt;
Generic page template. Frontmatter + ## Key Points / ## Details / ## Related
/ ## Sources.

&lt;span class="gu"&gt;## templates/workflow.md&lt;/span&gt;
Automation-ready procedure template. type: workflow. Sections: Goal,
Prerequisites, Steps (numbered, imperative), Verification, Rollback (if
applicable), Related.

&lt;span class="gu"&gt;## wiki/projects/_example-client/_status.md&lt;/span&gt;
Realistic example status dashboard. Phase: active. Plausible placeholder
content. Marked as example.

&lt;span class="gu"&gt;## wiki/projects/_example-client/_example-client-overview.md&lt;/span&gt;
Example architecture overview. Frontmatter + 3-sentence overview + Key
Points + Architecture + Recent Decisions + Related.

&lt;span class="gu"&gt;## raw/README.md&lt;/span&gt;
One-page explanation of what goes in raw/ and the immutability rule: never
edit raw files after adding them.
&lt;span class="p"&gt;
---
&lt;/span&gt;
After creating everything, print a summary (file count + tree) and next
steps: (1) add your first raw source to raw/, (2) create your first real
project folder under wiki/projects/, (3) commit to git.

Do not add files beyond what's specified. Do not add a root README.md.
Do not add a LICENSE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it from an empty directory, then &lt;code&gt;git init&lt;/code&gt;, then add your first raw source. I had a working LLM Wiki in under two minutes.&lt;/p&gt;

&lt;p&gt;The original gist is short and worth reading: &lt;a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f" rel="noopener noreferrer"&gt;Karpathy — LLM Wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you try it, drop a comment with how you ended up shaping it. I'd genuinely like to compare notes.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>documentation</category>
      <category>llm</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
