{
  "source_file": "0930",
  "source_platform": "Dev.to",
  "author": "xbill",
  "title_listed": "Four Debian 13 Boxes, One Brief: 1,923 Packages on Metal, 328 in the Cloud",
  "keywords": "",
  "domain": "大模型算法",
  "content_type": "工程实践",
  "is_paid_flag": "否",
  "url": "https://dev.to/aws-builders/four-debian-13-boxes-one-brief-1923-packages-on-metal-328-in-the-cloud-and-the-backup-gpt-2jn9",
  "publish_date": "2026-09-09",
  "corpus_stage": "",
  "notes": "",
  "id": "81eb5878da2b",
  "collected_at": "2026-10-02T13:51:39",
  "title": "Four Debian 13 Boxes, One Brief: 1,923 Packages on Metal, 328 in the Cloud - DEV Community",
  "body_markdown": "This article covers one afternoon of running the same Debian 13 on four machines — one laptop and three clouds — and asking each of them the same question about its own hardware.\nA cloud image is not a small Debian. It is a different bet about what you will need.\nThe laptop install carries 1,923 packages. The three cloud images carry 328, 337 and 350. That is not a rounding difference, and the interesting part is not the count — it is that all four are booting from NVMe, and only two of them ship anything that can read an NVMe health log.\nWhat that creates is a gap with two halves. The hardware is present and the kernel can see it. The default toolset cannot. And because nothing fails, nothing tells you:\nEvery cloud image ships\nzero firmware packages\nand logs\nzero firmware load attempts\n— consistent, not broken, and you have to check to know which.\nAWS and Azure ship no\nnvme-cli\n, on machines whose only disk is NVMe.\nGCE alone\nships\ndmidecode\nand\nnvme-cli\n. It is the most complete of the three by a clear margin.\nAzure reports\nVulnerability Retbleed: Vulnerable\n. AWS and GCE do not.\nAWS carries a\nbackup GPT header its own volume resize never relocated\n—\nGPT:16777215 != 41943039\n, still wrong at the boot I measured. GCE emits the identical warning and\nfixes it in the same boot\n.\nThat last pair is the whole article. Same kernel, same message, opposite correct answers.\nhttps://github.com/xbill9/local-bench\nThe Machines\nFour hosts, all Debian 13 (trixie), all measured on 2026-09-09:\nImage\nShape\nCPU\nKernel\nlocal\ninstalled, bare metal\nLenovo 83B1\ni7-1360P, Raptor Lake, 16 threads\n7.1.8+deb13-amd64\n(backports)\nAWS\nami-0871da4641e8b4413\nc7i.large\nXeon 8488C, Sapphire Rapids, 2 vCPU\n6.12.107+deb13-cloud-amd64\nGCE\ndebian-13-trixie-v20260908\nc4-standard-2\nXeon 8581C, Emerald Rapids, 2 vCPU\n6.12.107+deb13-cloud-amd64\nAzure\nDebian:debian-13:13-gen2:0.20260831.2587\nStandard_D2s_v7\nXeon 6973P-C, Granite Rapids, 2 vCPU\n6.12.107+deb13-cloud-amd64\nOne detail decides how to read everything below.\nThe AWS and Azure images are the same upstream Debian build\n—\n2587\n, dated 2026-08-31 — running the same kernel. GCE builds its own, a week newer. So where AWS and Azure differ, the distro is not the variable. The platform is.\nAt This Point You Should Have\nAn account on whichever clouds you want to compare, and the CLI for each already authenticated\nThe ability to launch a VM and throw it away\nssh\n, and a key you are willing to put on a throwaway host\nSomewhere durable to write findings that is not your shell scrollback\nSteps 0 through 2 are reads and launches. Step 3 installs software, and\nStep 3 is the point of no return for the baseline\n— see Step 1 for why that ordering is not optional.\nStep 0 — Pin the Image, Not the Family\nAn image family is a moving target, and \"Debian 13\" is not a measurement. Resolve it to an ID before you launch anything, and write the ID down.\n# AWS — the official Debian account is 136693071363\naws ec2 describe-images\n--owners\n136693071363\n\\\n--filters\n\"Name=name,Values=debian-13-amd64-*\"\n\"Name=state,Values=available\"\n\\\n--query\n'sort_by(Images,&CreationDate)[-1].{Name:Name,ID:ImageId,Date:CreationDate}'\n# GCE — resolve the family to the image it currently points at\ngcloud compute images describe-from-family debian-13\n\\\n--project\ndebian-cloud\n--format\n=\n\"value(name)\"\n# Azure — the stable offer is debian-13; debian-13-daily is a different thing\naz vm image list\n--publisher\nDebian\n--offer\ndebian-13\n--sku\n13-gen2\n--all\n\\\n--query\n\"[?offer=='debian-13'] | sort_by(@,&version)[-1].urn\"\n-o\ntsv\nEnter fullscreen mode\nExit fullscreen mode\nThat third one has a trap in it. Asking Azure for\n--offer debian-13\nwith\n--all\nwill happily return\ndebian-13-daily\nURNs alongside the stable ones, because the filter matches loosely. The\n[?offer=='debian-13']\nclause is doing real work — without it you will pin a daily build and not notice.\nThis is also where the AWS/Azure coincidence shows up: both resolved to build\n2587\n, dated 2026-08-31. That is not a fluke, it is the same upstream Debian cloud image, and it is the single most useful fact for interpreting the rest.\nStep 1 — Scan Before You Install Anything\nThis step exists because I got it wrong the first time.\nThe first EC2 instance I launched had a\nuser-data\nscript that installed about twenty packages before I ever logged in. Then I scanned it and wrote down what was present. Every one of those findings was worthless: I was measuring my own cloud-init, not Debian's image. That instance had to be discarded and relaunched with no\nuser-data\nat all.\nA default-install analysis has exactly one chance to be correct, and it is before the first\napt-get install\n.\nThe scanner has to run on a machine where nothing is installed, which means it can only use what a minimal cloud image actually ships — bash, coreutils,\n/proc\n,\n/sys\n,\ndpkg\n. No\njq\n. No\nlspci\n, because\npciutils\nmight not be there. Absence is the data, so nothing may fail:\n# hardware, without needing dmidecode\nfor\nf\nin\nsys_vendor product_name bios_version bios_date\n;\ndo\n[\n-r\n\"/sys/class/dmi/id/\n$f\n\"\n]\n&&\nprintf\n'%-16s %s\\n'\n\"\n$f\n\"\n\"\n$(\ncat\n/sys/class/dmi/id/\n$f\n)\n\"\ndone\n# what the image actually ships, by dpkg, not by PATH\nfor\np\nin\npciutils usbutils dmidecode nvme-cli smartmontools lm-sensors\n\\\nethtool intel-microcode fwupd build-essential gcc git unzip\n;\ndo\ns\n=\n$(\ndpkg-query\n-f\n'${db:Status-Status}'\n-W\n\"\n$p\n\"\n2>/dev/null\n)\n[\n\"\n$s\n\"\n=\ninstalled\n]\n&&\necho\n\"PRESENT\n$p\n\"\n||\necho\n\"absent\n$p\n\"\ndone\nEnter fullscreen mode\nExit fullscreen mode\nCheck packages with\ndpkg\n, not with\ncommand -v\n.\nThis is the second thing I got wrong, and it is worth more than the first. My initial pass over the laptop reported\ndmidecode\n,\nnvme-cli\n,\nsmartmontools\n,\nhdparm\n,\nethtool\n,\npowertop\nand\nturbostat\nas missing. All seven were installed. My login\nPATH\ncontained no\n/usr/sbin\n, no\n/sbin\n, no\n/usr/local/sbin\n, and a bare\ncommand -v\ncannot see a binary it has no path to. Seven false negatives from one unstated assumption, on the machine I know best.\nThe full scanner is\nevidence/baseline-scan.sh\nin the repo. Run it, keep the output, then install things.\nStep 2 — Launch Pristine\nNo\nuser-data\n, no startup script, no custom image. Lock SSH to your own address rather than the world — every one of these CLIs will happily open port 22 to\n0.0.0.0/0\nif you let it.\nMYIP\n=\n$(\ncurl\n-s\nhttps://checkip.amazonaws.com\n)\n/32\n# AWS\naws ec2 run-instances\n--image-id\n<ami>\n--instance-type\nc7i.large\n\\\n--key-name\n<key>\n--security-group-ids\n<sg>\n--subnet-id\n<subnet>\n\\\n--associate-public-ip-address\n--metadata-options\n'HttpTokens=required'\n# GCE\ngcloud compute instances create baseline\n--zone\n=\nus-east1-b\n\\\n--machine-type\n=\nc4-standard-2\n--image-family\n=\ndebian-13\n--image-project\n=\ndebian-cloud\n# Azure — --nsg-rule SSH opens 22 to the internet; narrow it afterwards\naz vm create\n-g\n<rg>\n-n\nbaseline\n--image\n<urn>\n--size\nStandard_D2s_v7\n\\\n--admin-username\nazureuser\n--ssh-key-values\n~/.ssh/id_ed25519.pub\n--nsg-rule\nSSH\naz network nsg rule update\n-g\n<rg>\n--nsg-name\nbaselineNSG\n--name\ndefault-allow-ssh\n\\\n--source-address-prefixes\n\"\n$MYIP\n\"\nEnter fullscreen mode\nExit fullscreen mode\nAzure will also refuse a size that is not offered to your subscription in that region, and the CLI reports it badly — mine crashed inside its own error handler with\nRuntimeError: The content for this response was already consumed\n, having created nothing. The real cause was that\nStandard_D2s_v6\ndoes not exist for that subscription in\neastus\n. Ask before you launch:\naz vm list-skus\n-l\neastus\n--size\nStandard_D2s_v7\n\\\n--query\n\"[].{Name:name,Restrictions:restrictions[].reasonCode}\"\n-o\njson\nEnter fullscreen mode\nExit fullscreen mode\nAn empty array means the SKU is not available to you. That is the answer the failed deployment was trying to give.\nStep 3 — Install Claude Code, and Notice What It Does Not Need\ncurl\n-fsSL\nhttps://claude.ai/install.sh | bash\nEnter fullscreen mode\nExit fullscreen mode\nOn all three clouds, on images with\nno\nnode\n, no\nnpm\n, no\nunzip\nand no compiler\n:\nAWS\nGCE\nAzure\nElapsed\n10 s\n8 s\n12 s\nVersion\n2.1.266\n2.1.266\n2.1.266\nInstalled size\n206 MB\n206 MB\n206 MB\nldd\non the binary returns\nlinux-vdso\n,\nlibrt\n,\nlibc\n,\nlibpthread\n,\nlibdl\n,\nld-linux\n— glibc 2.41 and nothing else. The prerequisites are\ncurl\nand a writable\n$HOME\n, and every one of these images has both.\nAll three printed the same warning:\n~/.local/bin is not in your PATH\n. Debian's\n~/.profile\nadds that directory only if it exists\nat login\n, and the installer creates it mid-session. Three for three, and it resolves itself on the next login.\nStep 4 — Give Each Machine the Same Brief\nThis is the part that changes the result. Rather than SSH-ing in and running commands from outside, install Claude Code on each box and have it examine the machine it is running on:\nclaude\n-p\n\"\n$(\ncat\nbrief.txt\n)\n\"\n--allowedTools\nBash\nEnter fullscreen mode\nExit fullscreen mode\n--allowedTools Bash\npre-approves the one tool the job needs. The blunter\n--permission-mode bypassPermissions\ndisables the permission system wholesale and is the wrong instrument here.\nThe brief asks for seven things in order — identity, drivers, firmware, kernel errors, failed units, system tools, gaps — and ends by asking for a verdict of at most eight lines. The full text is\nevidence/deep-analysis-prompt.txt\n.\nOne clause in it earned its place:\nIMPORTANT: check with an explicit PATH that includes /usr/sbin, /sbin and /usr/local/sbin, and cross-check against dpkg — a tool in /usr/sbin is NOT missing just because a bare\ncommand -v\nunder a login PATH cannot see it. This exact mistake has already been made once in this project.\nWithout it, four machines would have independently reproduced my Step 1 error. With it, the Azure instance flagged\nethtool\nas \"the tool a bare login-PATH\ncommand -v\nmissed earlier in this project\" — it had read the warning and applied it.\nOne caveat, and it is mine.\nThe brief says \"use your Bash tool\" and never says read-only. The laptop's instance ran\nupdate-initramfs -u\nduring its analysis, rebuilt the boot image, and said so at the top of its report. The result was benign — it incidentally shipped the\nrtl8156b-2.fw\nblob that had been missing from that initrd — and the three cloud instances wrote nothing. But that was the brief's luck, not its design.\nIf you reuse this, say read-only.\nWhat the Default Image Ships\ndpkg\n-verified, on pristine images, before anything was installed:\nPackage\nlocal\nAWS\nGCE\nAzure\npciutils\nYES\nYES\nYES\nYES\nethtool\nYES\nYES\nYES\nYES\ncurl\n/\nwget\n/\npython3\nYES\nYES\nYES\nYES\ndmidecode\nYES\n—\nYES\n—\nnvme-cli\nYES\n—\nYES\n—\nsmartmontools\nYES\n—\n—\n—\nlm-sensors\nYES\n—\n—\n—\nlshw\n/\nusbutils\nYES\n—\n—\n—\nlinux-cpupower\n/\npowertop\nYES\n—\n—\n—\nintel-microcode\n/\nfwupd\nYES\n—\n—\n—\nbuild-essential\n/\ngcc\n/\ngit\nYES\n—\n—\n—\nnumactl\n/\nhwloc\n/\ngawk\n—\n—\n—\n—\nTotal installed\n1,923\n337\n350\n328\nFive packages are universal. Everything else is a choice, and\nGCE makes the most generous one\n— it is the only image of the three that can inspect its own disk or decode its own SMBIOS out of the box.\nWhat the Hypervisor Takes Away\nThe gap has a second half that no package closes. Some facilities are absent because the hypervisor does not expose them, and installing the tool achieves nothing:\nlocal\nAWS\nGCE\nAzure\n/sys/class/hwmon\npresent\nabsent\nabsent\nabsent\nthermal_zone*\n10\nnone\nnone\nnone\n/sys/class/powercap\n(RAPL)\npresent\nempty, modules loaded\nabsent\nabsent\nthermal_throttle\ncounters\npresent\nabsent\nabsent\nabsent\nEDAC\npresent\nabsent\nabsent\nabsent\nTPM\npresent\nnone\nvTPM present\ndisabled by config\nmicrocode revision\n0x6134\n0x2b000661\n0xffffffff\n0xffffffff\nTwo of these repay a second look.\nAWS's RAPL is not simply missing.\nThe instance found\nintel_rapl_msr\nand\nintel_rapl_common\nloaded and a\npsys\nPMU domain registered — KVM is exposing the MSRs — but\n/sys/class/powercap\nis empty because the\nmsr\nmodule is not loaded and no reader is installed. On AWS, power is recoverable with\nlinux-cpupower\nand a\nmodprobe\n. On GCE and Azure, RAPL is not virtualised at all, and no tooling will bring it back. Those two states look identical from a distance and are not the same problem.\nGCE and Azure mask the microcode revision\nto\n0xffffffff\n. AWS reports a real one. If your compliance story involves auditing microcode level in-guest, it works on one of these three.\nThe GPT Header, and Why Only the Machine Could Tell\nAWS and GCE both emit this during boot:\nGPT:16777215 != 41943039\nGPT: Use GNU Parted to correct GPT errors.\nEnter fullscreen mode\nExit fullscreen mode\n16,777,215 sectors is 8 GiB. 41,943,039 is 20 GiB. Both disks were created at 8 GiB and requested at 20; the primary GPT was updated and the backup header at the end of the disk was not moved to match. The kernel falls back to the primary and boots.\nOn AWS it is\nstill wrong\n. The instance ranked it as action item #1 and gave the fix:\nsudo\nsgdisk\n-e\n/dev/nvme0n1\nEnter fullscreen mode\nExit fullscreen mode\nOn GCE the same warning appears at t=1.95s and t=2.23s and is then\ncorrected inside the same boot\n, because Google ships\ngce-disk-expand\nin the image and AWS ships nothing equivalent. Azure never emits it at all.\nSame kernel. Same message. On one machine it is a defect you must fix; on another it is a transient you must ignore. Nothing in the message says which, and no amount of reading the message from outside the machine would tell you — you need the boot timeline, the package list and the agent's behaviour together.\nThree Findings You Only Get From the Inside\nAzure is exposed to Retbleed.\nlscpu\nreports\nVulnerability Retbleed: Vulnerable\n, tied to the microcode Hyper-V presents to the guest. AWS and GCE report no such thing. There is no in-guest fix; it depends on Azure host-side updates. Azure also has Secure Boot\nand\nvTPM available and\nboth disabled\non a default VM.\nGCE fails a boot step every time.\nThe\nhwclock\nbinary is absent, so\ngoogle_guest_agent\n's clock-skew-setup step fails on every boot. Impact is near zero —\nkvm-clock\nis authoritative — but it is a permanent error in a log nobody reads.\nAzure has zero unbound PCI devices.\nIt presents three PCI devices, all bound, plus thirteen VMBus devices, all bound. AWS presents about 45 with four unbound legacy stubs (440FX, PIIX3 ISA, PIIX4 ACPI, an emulated VGA); GCE presents 15 with three. Hyper-V Gen2 emulates no legacy chipset at all, and AWS still boots\nlegacy BIOS\nwith an unused EFI System Partition mounted at\n/boot/efi\n.\nWhere They're Alike\nWorth stating plainly, because it is the larger part of the result. On all four machines:\nkernel taint 0\n,\nzero failed systemd units\n,\nis-system-running: running\n, and every PCI device with a real function had its driver bound. On all three clouds:\nzero firmware-load attempts and zero firmware packages\n— which is consistent rather than broken, because\nena\n,\ngve\n,\nmana\n,\nnvme\nand\nvirtio\nrequest no blobs.\nThe shared noise is shared exactly:\nsystemd-ssh-generator\nfails its AF_VSOCK probe every boot on all three clouds, none of which expose a working vsock CID.\nCheat Sheet\n# 0. pin the image to an ID, never a family\naws ec2 describe-images\n--owners\n136693071363\n--filters\n\"Name=name,Values=debian-13-amd64-*\"\n\\\n--query\n'sort_by(Images,&CreationDate)[-1].ImageId'\ngcloud compute images describe-from-family debian-13\n--project\ndebian-cloud\n--format\n=\n\"value(name)\"\naz vm image list\n--publisher\nDebian\n--offer\ndebian-13\n--sku\n13-gen2\n--all\n\\\n--query\n\"[?offer=='debian-13'] | sort_by(@,&version)[-1].urn\"\n-o\ntsv\n# 1. confirm the SKU is actually offered to you before launching\naz vm list-skus\n-l\neastus\n--size\nStandard_D2s_v7\n--query\n\"[].name\"\n-o\ntsv\n# 2. scan BEFORE installing anything -- packages by dpkg, never by command -v\ndpkg-query\n-f\n'${db:Status-Status}\\n'\n-W\nnvme-cli dmidecode smartmontools\ndpkg-query\n-f\n'.\\n'\n-W\n|\nwc\n-l\n# 3. tools by an sbin-inclusive PATH, or you will invent false negatives\nPATH\n=\n/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\ncommand\n-v\nnvme smartctl turbostat\n# 4. is the facility absent, or just unreadable? absent = no package will help\nls\n/sys/class/hwmon /sys/class/powercap /sys/devices/system/edac 2>&1\nlsmod |\ngrep\n-c\nrapl\n# loaded modules + empty powercap = recoverable\ngrep\n-m1\nmicrocode /proc/cpuinfo\n# 0xffffffff = hypervisor is masking it\n# 5. the backup GPT header, on any volume you have ever grown\nsudo\ndmesg |\ngrep\n-i\n'GPT:'\nsudo\nsgdisk\n-e\n/dev/nvme0n1\n# only if the mismatch persists after boot\n# 6. install Claude Code and let the machine read itself\ncurl\n-fsSL\nhttps://claude.ai/install.sh | bash\nclaude\n-p\n\"\n$(\ncat\nbrief.txt\n)\n\"\n--allowedTools\nBash\nEnter fullscreen mode\nExit fullscreen mode\nSummary\nThe goal was to find out what a stock Debian 13 cloud image knows about the hardware underneath it. The answer is: less than the hardware is willing to say, and the shortfall is different on every platform, in ways that a package list alone does not predict.\nThe key to getting a usable answer was giving each machine the same brief and letting it read its own boot log, because the two most interesting findings — a broken partition table on one cloud and a self-correcting one on another — are the same kernel message, and only the machine can tell you which one it is looking at.\nThe method's own two mistakes are in the article on purpose. Both were unstated assumptions, both produced confident wrong answers, and one of them was on the machine I know best.\nRepo:\ngithub.com/xbill9/local-bench\n—\ndocs/debian-across-clouds/\ncarries the four self-analyses, the pristine baseline scans, the brief, and the benchmark and pricing data. Every evidence file ends with a \"NOT measured\" section listing which claims are inferences rather than measurements.",
  "metadata": {
    "title": "Four Debian 13 Boxes, One Brief: 1,923 Packages on Metal, 328 in the Cloud - DEV Community",
    "description": "The same Debian 13 on a laptop and on AWS, GCE and Azure. The cloud images ship 328-350 packages against 1,923 on metal, no firmware package at all, and no tool to read the NVMe they all boot from. Each machine was then given the same brief and asked to analyse itself. Three of them agreed. The fourth found a partition table its own resize had broken. Tagged with debian, linux, claudecode, devops.",
    "keywords": "debian, linux, claudecode, devops, software, coding, development, engineering, inclusive, community",
    "author": null,
    "og:type": "article",
    "og:url": "https://dev.to/aws-builders/four-debian-13-boxes-one-brief-1923-packages-on-metal-328-in-the-cloud-and-the-backup-gpt-2jn9",
    "og:title": "Four Debian 13 Boxes, One Brief: 1,923 Packages on Metal, 328 in the Cloud",
    "og:description": "The same Debian 13 on a laptop and on AWS, GCE and Azure. The cloud images ship 328-350 packages against 1,923 on metal, no firmware package at all, and no tool to read the NVMe they all boot from. Each machine was then given the same brief and asked to analyse itself. Three of them agreed. The fourth found a partition table its own resize had broken.",
    "og:site_name": "DEV Community",
    "og:image": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fxbill9%2Flocal-bench%2Fmaster%2Fdocs%2Fdebian-across-clouds%2Fdevto-cover.ce332564.jpg",
    "twitter:site": "@thepracticaldev",
    "twitter:creator": "@",
    "twitter:title": "Four Debian 13 Boxes, One Brief: 1,923 Packages on Metal, 328 in the Cloud",
    "twitter:description": "The same Debian 13 on a laptop and on AWS, GCE and Azure. The cloud images ship 328-350 packages against 1,923 on metal, no firmware package at all, and no tool to read the NVMe they all boot from. Each machine was then given the same brief and asked to analyse itself. Three of them agreed. The fourth found a partition table its own resize had broken.",
    "twitter:card": "summary_large_image",
    "twitter:widgets:new-embed-design": "on",
    "twitter:image:src": "https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fxbill9%2Flocal-bench%2Fmaster%2Fdocs%2Fdebian-across-clouds%2Fdevto-cover.ce332564.jpg"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/81eb5878da2b/code/body-000.txt",
      "chars": 661,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-001.txt",
      "chars": 527,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-002.txt",
      "chars": 766,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-003.txt",
      "chars": 125,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-004.txt",
      "chars": 47,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-005.txt",
      "chars": 49,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-006.txt",
      "chars": 68,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-007.txt",
      "chars": 28,
      "language": "text"
    },
    {
      "file": "attachments/81eb5878da2b/code/body-008.txt",
      "chars": 1562,
      "language": "text"
    }
  ],
  "images": [],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://github.com/xbill9/local-bench",
      "label": "https://github.com/xbill9/local-bench",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:48:35Z",
  "source_url": "https://dev.to/aws-builders/four-debian-13-boxes-one-brief-1923-packages-on-metal-328-in-the-cloud-and-the-backup-gpt-2jn9",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 17639,
  "expected_body_images": 0,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/81eb5878da2b/pages/source.html",
  "local_html": "attachments/81eb5878da2b/pages/article.html",
  "body_base_path": "attachments/81eb5878da2b/pages/",
  "body_markdown_path": "attachments/81eb5878da2b/pages/article.md"
}