Fzakaria Blog

31 篇内容

工具笔记Fzakaria Blog

Hiding my AI slop from my Nix friends

文章讨论作者如何在使用 AI 编码代理时,避免自己和代理产出“AI 腔”文本。他把 home-manager 的 agent-settings.nix 声明式生成 ~/.claude/CLAUDE.md 与 AGENTS.md,汇总维基百科和 Simon Willison 的 AI 写作特征,禁用 delve、tapestry 等词及“不是 X 而是 Y”等句式。发现提示无法稳定约束后,他复用代理自己写出的 tools/check-prose.py,在 CI 中以确定性检查拦截禁用词、短语和破折号,认为可验证、可复现的检查优于上下文提示。作者还统计历年博文,发现 2025-2026 年破折号与违禁词明显上升,并引用 Goodhart 定律提醒该指标本身会失效。内容偏个人实践与反思,缺少系统评测和推广验证。

推荐收录,因为它给出可迁移的具体做法:用可运行、可验证的 CI 脚本来约束 AI 生成代码与文档的写作风格,而不是依赖易被忽略的提示词,并用 Goodhart 定律诚实地指出该指标的局限。适合在仓库中大量使用编码代理、关心代码与文档风格的工程读者参考;风险是内容以个人实践为主,样本和评测有限。

工程实践Fzakaria Blog

Every package is already installed

文章介绍 omnibin:一个基于 FUSE 的文件系统,把 nixpkgs 历史中几乎全部二进制放到 $PATH 上,实现“无需安装、无需构建”的按需包访问。其核心是利用 cache.nixos.org 上 Hydra 生成的 .ls 元数据作为索引,再结合 nixpkgs-multiverse 将 (attribute, version) 解析到已构建的 store path,并在首次读取时从缓存拉取 NAR 解包。作者展示了 5 万多个顶层二进制、88 万级二进制树、版本化命令(如 python3@3.6.2)以及 Docker/NixOS 集成方式。为避免 FUSE 全树 stat 过慢,工具只列出每个二进制的最新版本,并提供 index.db 和 omnibin CLI 查询。代价是首次访问需下载解包(示例约 2.7 秒),后续因 store 已存在而瞬时返回。

推荐收录。文章不是泛泛介绍 Nix,而是给出 omnibin 的完整机制:利用 Hydra .ls 索引和 nixpkgs-multiverse 做版本解析,再用 FUSE 懒加载 NAR,并讨论了 ls 性能、首次访问延迟和查询接口等真实约束。对研究包管理、FUSE/文件系统、开发环境与可复现构建的读者有直接迁移价值。

技术文章Fzakaria Blog

A build graph that rolls dice

文章围绕 Nix 动态 derivations,用 applicative 与 monadic 类比说明传统构建图必须预先可知,而动态 derivations 把 bind 从求值器下移到调度器,使构建中可继续生成新 .drv。作者以掷骰子为例:step 掷 d6,非 6 则生成 passthrough 并递归 depth+1,6 则终止并输出深度,涉及 builtins.outputOf、content-addressed derivation 与 recursive-nix。约 900 次实验得到链长均值 6.18、中位数 4、最长 46,与几何分布吻合。文章指出当前 --dry-run 等工具无法内省动态图,并讨论 Mario 模拟、状态空间搜索和爬虫等超出 lang2nix 的用法,同时留下图深度与规模边界未知的问题。

推荐收录:文章不是泛泛介绍 Nix 新特性,而是用类型系统和调度层差异解释动态 derivations 的根本变化,并给出可运行示例、实验数据和可迁移的搜索/爬虫等场景。适合构建系统、开发者工具和编程语言实现方向的读者,能帮助理解增量/动态依赖图的代价与当前工具链局限;主要风险是动态 derivations 仍属实验特性,文中 --dry-run 不可用等结论需结合版本验证。

工具笔记Fzakaria Blog

Visualizing Nix closures

文章介绍作者用 Hilbert 曲线构建的 seenix.dev:一个完全在浏览器本地运行、无需服务端的单页应用,以“一字节一像素”的方式可视化 Nix closure。核心做法是把 closure 内各 store path 的 NAR 按名称排序拼接成一维字节流,再用 Hilbert 曲线折叠成正方形,从而保持字节局部性,使 store path、文件乃至 ELF section 都对应连续方形区域。布局只需 narinfo 中的 NarSize,因此整张图在下载任何 NAR 前即可毫秒级完成,缩放时再从 cache.nixos.org 按需取 NAR 并按字节类型上色(可打印 ASCII、控制字节、0x00 等)。作者据此验证某争议二进制实际不含 ffmpeg 与 ruby(41 个 path、234 MiB),并展示了 1,324 个 path、5.3 GiB 的 GNOME 桌面 closure,工具支持 nix path-info 导出与额外二进制缓存。其边界是主要用于探索与可视化,不改变 Nix 语义,且读者需具备基本 Nix 背景。

推荐收录:文章给出了明确且可复现的技术机制(Hilbert 曲线字节布局、仅凭 narinfo 提前绘图、缩放时按需拉取 NAR),并用真实 closure(含争议二进制与 GNOME 桌面)验证结论,而非停留在概念演示。适合使用 Nix/NixOS 的开发者、做二进制或依赖体积分析的工程师,以及关注可视化实现的人;其局部性布局与懒加载思路可迁移到其他大体积产物的可视化与审计场景。

技术文章Fzakaria Blog

A Nix store is three functions

文章指出成为 Nix 二进制缓存只需实现三个 GET 请求:nix-cache-info、对应 32 位哈希的 narinfo 元数据、以及 narinfo 中 URL 指向的压缩归档,客户端并不关心底层传输介质。作者据此把 nix copy --to file:// 产出的缓存目录发布到 GitHub Pages/Releases 与 npm 等静态文件服务,并用 npm 完整演示了打包、签名、发布,再从 unpkg 作为 substituter 拉取闭包并用 bwrap 运行的流程。文章还解释签名只覆盖 StorePath、NarHash、NarSize、References,不含 URL/FileHash,因此归档可托管于任意主机并仍通过校验。文末列举 gachix、DNS TXT、pastebin、OCI、npm 等替代实现,并指出 npm 不支持增量发布、每次版本重复上传整个闭包这一主要局限。

推荐收录:文章把 Nix 二进制缓存抽象为三个 GET 请求,并用 GitHub、npm、git 对象库等真实实现佐证,签名覆盖范围与 npm 无法增量发布等边界说明清晰。适合使用 Nix 的开发者及包管理、内容寻址存储方向读者,其最小接口与签名校验思路可迁移到自建缓存、制品分发等场景。

工具笔记Fzakaria Blog

Review a pull request by booting it

文章介绍作者为 trynix 新增的 trynix-preview GitHub Action:它会在 Pull Request 下自动评论一条链接,评审者点击即可在浏览器标签页中启动 Linux 环境,并把该 PR 构建出的二进制加入 PATH,无需 clone、构建、服务器、SSH、Docker 或虚拟机。该 Action 不负责构建与缓存,只通过 nix eval 取出 store 路径,并把缓存地址与公钥交给浏览器,因此前提是目标路径已被构建并推入缓存(如 Cachix)。安全方面需在 fork PR 场景开启 allow-unsafe-pr-checkout,工作流运行于默认分支再检出 PR 代码以防 fork 篡改,并建议为 PR 构建使用隔离的私有缓存。作者也坦承大型二进制执行仍需 1-2 分钟,更适合中小型二进制的评审场景。

推荐收录。该文并非单纯工具发布,而是给出了可复制的工作流配置、缓存前置条件、fork PR 的安全权衡(默认分支运行、隔离私有缓存)以及大二进制启动耗时 1-2 分钟的明确边界。对设计 CI/CD 评审流程、探索浏览器内可执行环境或使用 Nix 的团队有直接可迁移价值。

工程实践Fzakaria Blog

Any Nix package, live in your browser

文章介绍了一个名为 trynix 的浏览器内 Nix 包运行器,允许用户通过静态网页直接启动一个完整 Linux 虚拟机,并运行 nixpkgs 历史上任意版本的任意包。作者结合此前构建的 nixpkgs-multiverse、grail 和 omniflake 等工具,实现了“属性+版本号→store path”的映射;利用 cache.nixos.org 等公开缓存提供的 CORS 支持,使浏览器可以直接获取 NAR 包;再借助 QEMU 与 WebAssembly 在浏览器中启动真实的 x86_64 Linux 内核,并通过 9p 文件系统挂载内存中的 Nix store。文章还讨论了性能优化,如后台预取引擎和虚拟机快照恢复,使得首次启动约 4 秒、二次访问约 1.5 秒。作者分析了该方案的边界:二进制仍处于模拟执行、首次运行有翻译开销、闭包大小受制于标签页内存和 WebAssembly 的 32 位地址空间。最后作者展望了 PR 评测试用、Agent 产物共享、可复现 bug 报告、可运行文档和软件考古等应用场景。整体是一个完整的工程实践案例,展现了将多种既有技术组合成新系统的思路。

推荐收录。文章展现了真实工程系统的完整构建过程,从组件设计、缓存复用、性能优化到边界约束均有具体细节。对关注 Nix、WebAssembly、浏览器端执行或可复现构建的读者,文中的架构拆解和应用场景推演极具迁移价值,也有助于启发新的工具链设计。

技术文章Fzakaria Blog

Keeping one version of everything

这篇文章讨论在 Nix 生态中混用不同 nixpkgs revision 时产生的菱形依赖问题:同一进程可能经由不同依赖链载入同一库的两个版本,导致符号冲突或内存破坏,如 fluent-bit 自带的 zstd 与 libsystemd dlopen 的 zstd 互不兼容而破坏地址空间。作者在 grail 工具中新增 --one <attr> 约束,要求求解器为所选全部 revision 只保留指定库的单一版本,文中用 python3/postgresql 和 zstd/openssl 的示例展示约束如何让 python 回退到更早 revision,并在无解时精确报告会混合的版本。文章明确该保证仅到版本级 ABI 一致,不等于统一 commit 或 /nix/store 路径,若要严格同路径仍需强制单 revision;glibc 等具备向后兼容的库未来可以放宽。全篇以 SAT 求解器为底色,展示了把依赖一致性变成可求解约束的技术路线。

收录理由:文章不是空谈一致性,而是用真实崩溃案例和不含糊的求解输出展示了一种工程解法,并明确点出能得到与得不到的边界。适合 Nix/nixpkgs 维护者、依赖解析或包管理系统的设计者阅读;把多版本冲突转化为 SAT 约束并让求解器报告冲突的思路,也能迁移到其他语言生态。缺点是内容较垂直,要求读者具备 Nix revision 等前置知识。

工程实践Fzakaria Blog

The holy grail of nixpkgs: version ranges

文章围绕给 Nixpkgs 引入版本区间支持展开。作者利用 nixpkgs-multiverse 对 nixos-unstable 历史版本的索引,把传统包管理器中的依赖求解问题建模为 Answer Set Programming(ASP),并用 clingo 求解。工具 grail 提供类似 Spack 的查询语法,支持版本区间、共存组、日期范围等约束,能在数秒内找到满足多包版本条件的历史修订版本,并生成锁文件供 nixpkgs-multiverse 使用。文章还展示了如何在 derivation 中直接编写版本区间并在 build 时通过 import-from-derivation 完成解析。针对跨修订版本可能带来的 glibc 兼容问题,作者给出了基于 ELF 符号版本需求实现跨 era 混合的方案。目前该工具以命令行和 WebAssembly 演示形式提供,计划整合进 nixmultiverse.com。

推荐收录。文章不是抽象理念,而是用可运行的 grail 工具和一个实网索引给出了从版本区间语法、ASP 建模、求解策略到 glibc 兼容验证的完整方案,证据链清晰。适合对包管理器设计、依赖求解、SAT/ASP 应用或 Nix 生态深入探索的读者。文中的将版本历史当作可查询数据库的思路,以及用 ELF 元数据放宽兼容边界的做法,也具有跨生态的可迁移价值。

技术文章Fzakaria Blog

How safe is follows?

本文用 omniflake 索引的 11,936 个 Nix flake 数据,量化分析 `follows` 统一 nixpkgs 输入的安全性。作者统计各 flake 锁定 nixpkgs 的年龄、渠道来源和选择时的陈旧度,发现半数 flake 在选定时使用的 nixpkgs 不足 17 天,如今中位数已超过 506 天;约八成修订曾是 Hydra 构建的渠道发布,生态整体并非故意用旧版本,而是长期未更新。由此推断,`follows` 通常迫使 flake 用比原作者测试时新约一年半的 nixpkgs 构建,可能引入轻微破坏,尤其在 nix-darwin 场景。文章同时承认该研究只能从修订版本分布推断风险,不能直接测量构建失败率,结论属经验性参考。

本文是少见的以真实生态数据回答 `follows` 安全性的分析,提供了具体的年龄分布和渠道统计,可帮助 Nix 用户和库维护者理解风险并决定是否使用 `follows`。研究方法(利用索引和发布存档做交叉分析)也值得借鉴;但由于没有直接测量构建失败,结论应视为风险提示而非最终定论。

工程实践Fzakaria Blog

One flake to rule them all

文章针对 Nix flakes 在管理输入时反复添加 follows、无法统一 nixpkgs 的痛点,提出了一个名为 omniflake 的单一 flake,将近一万两千个 flake 打包为一个输入。作者先解释了 flake.lock 的传递依赖和重复问题,说明 Nix 的惰性求值使大量输入在被访问前不会被拉取。随后描述了他为 Nix 上游修复的输入数量多时锁文件命名碰撞导致的二次复杂度问题,给出了优化前后性能对比。核心设计是 omniflake 只声明少量真实输入,通过内置 index.json 的 pin 信息和自定义加载器在请求时按需实例化各 flake,并支持 overrides 覆盖输入。文章还讨论了这个方案的边界,如部分 flake 缺少 flake.lock 时的变通,以及集中化与联邦化的权衡。

本文以真实的 Nix 生态痛点为出发点,不仅提出了 omniflake 这一新颖方案,还贡献了 Nix 上游性能修复,并附有清晰的机制解释和基准数据。适合 Nix 用户、包管理工具设计者和对惰性求值与依赖图感兴趣的系统工程师阅读。其中'用元数据代替真实输入、按需加载'的设计思路,以及性能问题的定位与优化方法,可以迁移到其他依赖管理或构建系统。

工程实践Fzakaria Blog

Stamping build info in constant memory

文章针对构建系统中用 llvm-objcopy 向 ELF 可执行文件附加 build info 时内存占用随文件大小线性增长的问题,提出了一种常量内存的 stamping 方案。作者通过测量确认 llvm-objcopy 的峰值 RSS 约为文件大小的两倍,并分析其根因:objcopy 需要将整个 ELF 读入内存以增加一个 section,并更新 section header table 和 .shstrtab。新方案让链接器在链接时预先发出一个仅含一字节的占位 section,使 section 的名字和 header 已经存在;之后的 stamping 步骤只需把 payload 追加到文件末尾,再原位修改该 header 的 sh_offset 和 sh_size 共 16 字节,完全不需要读取或重写文件其余部分。基准显示新方法内存占用恒定约 9.5 MiB,耗时与文件大小无关。文中给出了完整的 C 实现 elfstamp.c,并指出该技巧仅适用于非 SHF_ALLOC 的元数据 section,不影响内核加载。

推荐收录。文章用真实测量数据揭示了 llvm-objcopy 内存随文件大小线性增长的缺陷,并给出将内存占用降为常量的巧妙方案:利用链接器预留占位 section,stamping 时只追加数据和原位修改 16 字节 header。附带的 elfstamp.c 代码可直接迁移,适合构建系统、二进制后处理和大 ELF 注入元数据的工程师;其'专用小工具替代通用工具'的思路以及从现象到根因的分析方法也具有很强的可迁移性。需注意该方案仅适用于非 SHF_ALLOC 的 section,集成前需确认链接器与目标格式的兼容性。

技术文章Fzakaria Blog

Actually Queryable Executables

本文介绍了一种名为 SELF 的可执行文件格式构想:将程序本身构建为一个 SQLite 数据库,利用 Linux 的 binfmt_misc 机制通过自定义解释器执行,使得可执行文件的内容、元数据乃至运行状态都可以用 SQL 查询和修改。作者给出了一个可运行的 proof-of-concept 服务器 self-httpd,该服务器的程序代码、网页内容、访问日志和业务数据全部存放在同一个 SQLite 文件中,运行时可对自身文件进行 ACID 事务写入,并支持在线更新页面、全文检索和跨版本迁移。文章对比了 redbean 的 ZIP 自解压方案,指出 SELF 借助 SQLite 将容器与查询能力合二为一。文中也说明了当前限制,例如 /proc/self/exe 不可用,以及原型仍较为粗糙。整体上展示了将可执行格式重新定义为数据库后,现有 SQL 工具链可以大幅简化二进制分发、部署和审计流程。

推荐收录。文章提出了一个真正可运行的原型,并用 self-httpd 演示了程序自身可查询、可事务更新、可全文检索等能力,不是空泛概念。它对研究可执行格式、系统软件架构和部署简化的读者有很强的启发价值,其将二进制内容映射为数据库行的方法可以直接迁移到其他工具链设计中。需要注意目前实现依赖 binfmt_misc 且尚不成熟,但作为长期参考和创意起点价值明显。

工程实践Fzakaria Blog

Your executable is a SQLite database

文章提出用 SQLite 数据库文件替代 ELF 作为 Linux 可执行格式,作者在 NixOS 上实现了名为 SELF 的原型。核心做法是把程序头、加载段、符号表等建模成 SQL 表,利用 SQLite 的 application_id 和 binfmt_misc 让数据库文件可直接执行,并编写 self-exec 解释器完成加载、重定位和跳转。文中还展示两种动态链接方案:通过 glibc rtld-audit 用 SQL 查询替换库查找,以及完全用 SQL 实现 dynamic linker;并把整个 userland 的 723 个可执行文件及其依赖打包进一个 611.9 MiB 的数据库。基准显示单文件体积约为 ELF 的两倍,启动有约 5ms 固定开销且缺页共享受限,但通过 closure 去重后整体体积反而略小于源 ELF。文章明确承认这是原型,兼容性和性能仍是适用边界。

推荐收录。文章不是概念空想,而是给出可运行的 SELF 原型、SQL schema、加载器和完整基准,并用一个 723 可执行文件的 userland 数据库验证了可扩展性。对操作系统、二进制格式、动态链接和数据库方向的工程师与研究者,它能启发将“格式”重新理解为可查询数据模型,且作者对体积、延迟和缺页共享的量化边界值得迁移。

技术文章Fzakaria Blog

Three ways to smuggle SQLite into Nix

文章以 nixpkgs-multiverse 的索引文件为背景,探讨如何在 Nix 求值过程中直接调用 SQLite 查询,避免大规模 JSON 整文件解析。作者依次介绍 builtins.exec、builtins.importNative、巨型 .nix 文件和 builtins.wasm 四种方案,并给出关键代码和基准。结果表明:fromJSON 与巨型 .nix 均为固定开销,exec 每条查询约 3.8ms,importNative 因句柄缓存几乎恒定,wasm 需约 2.5s 编译但查询仅 7ms/条。作者最终认为当前无一种适合正式发布,同时指出 wasm 的潜力。文章还覆盖 Nix 字符串无法表示二进制等边界问题。

推荐收录。文章以可复现代码和实测基准系统比较了四种在 Nix 中嵌入 SQLite 的方案,并坦诚列出各自的安全与性能缺陷。适合 Nix 扩展开发者和需要在构建/求值流程中内嵌查询能力的读者;其对比方法和性能分析可迁移到其他“运行时内嵌外部引擎”的场景。注意 builtins.wasm 仍属实验特性,相关 API 可能变化。

工程实践Fzakaria Blog

nixpkgs-multiverse: the fewest nixpkgs

nixpkgs-multiverse 可从单个 flake 固定任意 Nix 包到历史任意版本。文章把版本固定建模为连续 revision 区间,目标是用最少 revision 点覆盖所有 pin,转化为贪心活动选择,O(n log n) 最优。若版本有空洞则 NP-完全,作者取最新连续段保持多项式可解。模拟显示 30 个近期版本 pin 只需约 10 个 revision;工具还提供最优性 plan、Nix API 与断言。需注意按 revision 分组可能拉回较早版本,且同版本字符串的闭包可能不同。

推荐收录。文章不是简单介绍工具功能,而是给出了清晰的算法建模、贪心最优性论证和 NP-完全边界,并用模拟数据验证收益。适合 Nix/Nixpkgs 用户、包管理工具开发者,以及对区间调度和工程权衡感兴趣的读者。可迁移价值在于把版本选择抽象成区间覆盖问题并利用贪心策略;主要风险是工具与 Nixpkgs 特定索引绑定,同类思路迁移到其他包管理器时需重新验证连续性假设。

工程实践Fzakaria Blog

nixpkgs-multiverse: fast mode

文章介绍 nixpkgs-multiverse 项目的 fast mode,它让用户无需下载和求值完整 Nixpkgs 树即可直接获取任意历史版本的 store path。核心方法是利用 Nix 字符串的 context 机制,通过 builtins.appendContext 手动附加 path 上下文,并使用 mkFakeDerivation 技巧构造不依赖 --impure 的假派生,使 Nix CLI 仅从缓存便能实例化路径。作者解释了索引的构造方式:将 nixos-unstable 每期发布的 store-paths.xz 清单与 multiverse 的 (attribute, version) 索引 join 起来,得到每个版本的精确 store path。文章还讨论了边界,如 fake derivation 没有 drvPath 无法构建,需要 .out 后缀或通过 .eval 获取真实派生来支持 override 和 nix develop,且方案依赖 cache.nixos.org 长期保留所有历史路径(普查显示 271,187 个路径仍存活)。最后展示了配套的 mvs 命令行工具,可查询大小、反向依赖和识别 store path。

本文深入揭示了 Nix 求值与缓存的内部机制,提供了跳过求值直接引用 store path 的可行方案,并清楚说明了其局限。对于 Nix 重度用户和包管理工具开发者,文中的 context 操纵技巧与索引设计具有直接借鉴价值,适合作为 Nix 生态进阶参考收录。

技术文章Fzakaria Blog

nixpkgs-multiverse is audacitymaxxing

文章介绍 nixpkgs-multiverse 项目,它通过一个 Nix flake 输入,提供 Nixpkgs 所有历史版本中每一版软件包的每一个独立版本。因 Nix 早于 FHS 的设计允许多版本共存,multiverse 收录了 304,484 个软件包版本对,涵盖 1,537 个 Nixpkgs 修订版,远超其他发行版;文中以 CPython 为例展示 246 个可并存的版本,并配有数据可视化对比。文章还说明 multiverse 帮助解决了 devenv 中依赖固定版本的长期问题,并介绍了 daysBehind 冷却窗口和 provenance 元数据特性。方案本质是 5 MB JSON 和 200 行 Nix 代码,并无复杂技术,但概念大胆,展现了 Nix 可复现构建与版本寻址的潜力。

本文展示了一个充分利用 Nix 可复现、多版本共存特性的创新案例,通过具体数据和真实工程问题解决(devenv 包固定)证明了其长期参考价值。适合对 Nix、开发环境可复现性及依赖管理感兴趣的开发者,文中的设计思路和方法可迁移到其他需要多版本支持或环境锁定的场景。

工程实践Fzakaria Blog

nixpkgs-multiverse: every version that ever existed

文章介绍 nixpkgs-multiverse 项目,通过一个 flake 输入提供 Nixpkgs 所有历史版本的惰性访问,解决多版本依赖时需固定多个 flake 输入的性能和易用性问题。核心方法是用 revisions.json 与 versions.json 索引包版本到修订的映射,并利用 builtins.fetchTree 按需获取;数据编码仅保留每个版本的最新出现修订,将索引大小控制在 5 MB 左右。性能实验表明,相比急切获取多个 flake 输入,该方案解析开销极低且遵循按修订计费原则。项目不构建或镜像任何内容,仅是对已有 Hydra 缓存的映射层,适合需要在 Nix 生态中灵活组合不同版本包的开发或构建环境。

推荐收录,因为它展示了一个真实的工程问题(Nix flake 多版本输入的性能与可用性冲突),并给出了完整的设计方案、数据优化与性能对比,具备可迁移的工程判断和工具设计思路。对使用 Nix、关注包管理与依赖分析的读者有直接参考价值,其惰性索引与按修订计费的设计也可启发其他需要高效版本查询的系统。

工程实践Fzakaria Blog

Super Mario Derivations

文章探索了利用Nix语言的惰性求值特性,将属性路径转化为Super Mario Bros. 3的按键输入序列。作者通过将每次按键操作定义为独立的派生(derivation),并使每个派生依赖前一帧的快照作为输入,从而实现了游戏状态的懒加载与增量构建。Nix store实际上充当了模拟器快照历史的持久层,分支或追加操作只需计算增量部分。文章还分析了递归深度限制(默认约2400次按键)、内核命令行参数长度限制(21,845次按键)以及构建时间线性增长等实际约束,并提出了通过文件输入绕过限制的方案。该工程案例展示了Nix派生机制在游戏状态机中的创意应用,但主要用于技术演示,性能开销较大。

推荐收录,因为这不是简单的技术玩梗,而是深入展示了Nix惰性求值、派生依赖和内容寻址存储的底层机制。文章提供了细致的基准测试和限制分析,对理解Nix的运行模型和扩展能力很有启发。适合对Nix或函数式构建系统感兴趣的工程师,其将输入序列拆分为可复用的派生单元的思想可迁移到其他需要增量构建或状态机复现的场景。

工程实践Fzakaria Blog

A C++ toolchain from 357 bytes, in Bazel

文章介绍了一个在 Bazel 中从 357 字节的 hex0 种子自举构建的 C++ 工具链。作者受 stage0 和发行版自举过程启发,利用 LLM 协助完成了这一机械但步骤繁多的工程,最终工具链能够无补丁编译 Bazel Central Registry 中的 Abseil 和 GoogleTest,并通过 236 项测试。工具链包含审计报告,利用 Bazel aspect 验证构建图中每个动作仅执行工具链自产的程序,确保了极高的封闭性。当前方案仍需系统提供的 shell,但显著提升了 Bazel 构建的可重现性,适用于对构建可信性、可移植性有要求的 C/C++ 项目。

推荐收录,因为它将一个很有挑战性的自举工具链工程在 Bazel 体系中完整实现,并用实际测试和审计报告证明了可行性。这对于关注构建可重现性、供应链安全以及工具链定制的工程师具有直接的参考价值,文中的自举流程和封闭性验证方法可直接迁移至类似基础设施建设项目。

技术文章Fzakaria Blog

The Nix sandbox is a hidden input

文章深入分析了Nix沙盒配置(sandbox-paths)如何成为推导的隐式输入,破坏了推导作为完整构建配方的理想。作者通过一个极简示例演示:当沙盒中不挂载/truth时,推导输出“2+2=4”;挂载包含不实内容的/truth后,输出变为“2+2=5”,但输出哈希不变,说明相同的.drv可以产生不同内容。文章进一步讨论此问题的严重性:默认sandbox-paths取决于Nix二进制的编译选项(如是否带busybox),不同机器上的“相同”Nix版本可能因隐式输入差异而产生不可重复的构建。作者还结合自己构建OpenJDK的实例,说明Guix软件包假设不存在/bin/sh而Nix默认提供,导致构建过程静默走上不同分支并生成损坏产物,该损坏产物还被无心上传至二进制缓存。文章揭示了Nix设计中的一个根本性权衡:将sandbox-paths纳入推导会破坏缓存共享,而排除则损害可重复性。其边界在于仅讨论intensional模型,content-addressed derivations或可缓解。

文章通过一个简洁可复现的例子,直观展示了Nix沙盒路径如何成为隐式输入,破坏推导的完整性和可重复性,并结合作者构建OpenJDK的真实踩坑经历,揭示了该问题在跨机器构建和二进制缓存投毒中的实际风险。适合所有关注构建可重复性和供应链安全的Nix用户、DevOps工程师阅读;其揭示的“隐式输入”原理可迁移至任何追求封闭构建的系统,提醒我们在依赖缓存时需重新审视信任假设。

工程实践Fzakaria Blog

Nix finally has a source-bootstrapped OpenJDK

文章记录了在Nix包管理器中实现从源代码自举构建OpenJDK的完整过程,通过移植Guix的bootstrap链(jikes、GNU Classpath、JamVM等),从零开始逐步构建出OpenJDK 7至25,脱离了对预编译二进制JDK的依赖。作者详细对比了Nixpkgs传统依赖二进制seed与GuixPkgs全源代码构建的闭包差异,量化了引导额外引入的876个推导项,并指出共享的C++工具链占据闭包主体。该工作展示了可复现构建在持久化软件供应链中的进展,同时也揭示了当前JDK自举对特定历史工具链的依赖和构建环境的复杂性。

推荐收录,因为本文不是简单的工具介绍,而是提供了真实的工程方案和可复现的构建链细节,包括从jikes到OpenJDK 25的19次完整构建过程及闭包分析。适合关注可复现构建、软件供应链安全或Nix/Guix生态的开发者,文中的自举策略和依赖分析手法可直接迁移到其他编译型语言的自举实践中。

工程实践Fzakaria Blog

Guix by Nix

文章展示了“Guix by Nix”项目,通过 guix-transfer 工具将 Guix 的软件包派生图翻译为 Nix 派生,并利用 Nix 守护进程构建了一个可启动的虚拟机镜像。该镜像以 Guix 的 Linux-libre 为内核,用户空间全部来自翻译后的 Guix 软件包,并以 GNU Shepherd 作为 init 系统,完全排除了 systemd 和 D-Bus。作者提供了自动化审计机制,验证所有可执行文件和脚本解释器均源自 Guix 输出,确保无 Nixpkgs 组件混入。文章还讨论了与 Nixpkgs 混合、构建非 systemd 系统等潜在拓展,但明确当前仅为最小演示,不适合生产环境。该案例对理解构建系统互操作、可重现系统构建和 init 系统替换具有参考价值。

推荐收录,因为它不是简单的工具使用,而是展示了将 Guix 生态翻译到 Nix 构建系统的完整工程方案,并附带了可验证的审计链。这对研究构建系统、操作系统定制或探索 Nix 作为通用构建语言的读者有直接启发,文中跨生态翻译、派生图转换和自证明验证方法均可迁移到类似项目。

技术文章Fzakaria Blog

The mean means nothing

文章以一次误导性的平均延迟指标为切入点,系统介绍了如何通过多种可视化手段正确理解性能分布数据。作者使用一个合成数据集模拟 Web 服务缓存上线场景,展示平均值、中位数、百分位数给出矛盾结论的原因,并依次通过密度图、累计分布函数(CDF)、位移函数、山脊图、热力图和联合图揭示数据呈双峰分布的实质:缓存命中导致低延迟,缓存未命中的大请求造成长尾。文章重点强调 CDF 能同时展示所有分位数的变化,尤其当两条 CDF 曲线交叉时,单一统计量无法概括整体效果。文中所有图表附有可复现的 Nix 脚本,便于读者在自己的数据上实践。该文既是一堂生动的可视化教学,也是工程师避免数据误读的实用指南。

这篇博文通过清晰的可视化对比,有力地揭示了仅依赖平均值或单一百分位数做技术决策的陷阱,并提供了可直接复现的分析方法。其核心方法(尤其是 CDF 对比和位移函数)可迁移到任何涉及分布变化分析的场景,如性能优化、A/B 测试或系统监控。适合所有需要从数据中提取可靠结论的后端工程师、SRE 和数据分析师,是一份长期值得参考的实践指南。

技术文章Fzakaria Blog

Seriously, what is the large code-model even for?

文章深入分析 x86-64 大代码模型(-mcmodel=large)在处理线程局部存储(TLS)时的根本性缺陷。作者通过构造超过 2 GiB 的 .bss 和 .text 示例,对比普通数据访问与 TLS 访问的编译器重定位类型,指出尽管大代码模型为普通数据生成了 64 位重定位,但 TLS 访问序列仍使用 32 位立即数(如 R_X86_64_TPOFF32),导致二进制文件超出 2 GiB 时链接失败。进一步剖析 GCC 与 LLVM 生成的指令序列,揭示问题并非编译器实现缺陷,而是 x86-64 psABI 从未定义大代码模型下的 TLS 访问模式,使得 64 位 TLS 偏移无法编码到指令中。文章提供了可复用的 Python 脚本用于生成巨型目标文件,验证了现象的通用性,并指出该限制对有大量线程局部变量的静态链接可执行文件尤为严重。

本文并非泛泛而谈,而是通过可复现的构造实验和汇编级分析,定位到 x86-64 ABI 规范的一项具体缺失,揭示了大型二进制工程中的一个隐蔽陷阱。其直接证据清晰、方法可迁移,适合从事工具链、系统软件或性能敏感大型应用开发的读者参考。文章还提供了生成测试用例的脚本,有助于读者在自己的环境中验证和延伸研究,具备长期的参考价值。

技术文章Fzakaria Blog

Linux kernel will support $ORIGIN, sort of

本文介绍了作者通过向 Linux 内核提交补丁,使内核支持在 PT_INTERP 和 shebang 中使用 $ORIGIN 的过程。最初提议在 VFS 层直接添加支持,经 VFS 维护者 Christian Brauner 建议,最终采用 eBPF 和 binfmt_misc 实现可编程解释器选择。文章展示了具体的 eBPF 程序示例,并讨论了新的 loader substitution 模式(L 标志),该模式允许原生执行二进制文件并透明替换解释器,解决了传统 binfmt_misc 中进程标识和 /proc/self/exe 指向解释器的问题。作者计划在相关补丁进入内核主线后,为 NixOS 开发一个可选模块,通过引入新的程序段(如 PT_INTERP_NIX)来保持向后兼容性。该方法不仅支持 $ORIGIN,还可用于动态选择 QEMU 等解释器,边界在于需要内核版本支持且依赖 binfmt_misc 和 eBPF 基础设施。

本文记录了真实的内核开发协作过程,从动机、技术方案迭代到最终实现,展示了如何利用 eBPF 和 binfmt_misc 解决可重定位二进制文件的痛点。对 Linux 内核开发、Nix/Bazel 等构建系统使用者以及关注动态链接器机制的技术人员有直接参考价值,其可编程解释器选择的思路可迁移至其他需要动态加载或仿真环境的场景。

工程实践Fzakaria Blog

Linux kernel will support $ORIGIN, sort of

文章记录了作者为支持 Nix 的 relocatable binaries 而向 Linux 内核提交补丁的完整过程。最初尝试在 VFS 层直接支持 $ORIGIN 失败后,在 VFS 维护者 Christian Brauner 的建议下,转而利用 eBPF 和 binfmt_misc 实现可编程解释器选择。最终方案通过 eBPF 程序在运行时根据 ELF 文件路径动态确定解释器,无需修改内核主体,并衍生出新的分发模式(如 loader substitution 'L')以解决传统 binfmt_misc 导致的进程身份透明性问题。文章还讨论了该机制在 QEMU、shebang 等场景的扩展潜力,并保留了向后兼容性设计——通过新增 PT_INTERP_NIX 段来控制触发。作者展望了在 NixOS 中的集成计划,同时坦诚说明了内核参与门槛、eBPF 所需的配置依赖等边界。

该文以一线开发者的视角完整呈现了一项内核特性的工程实现路径,从问题定义、社区协作、技术方案演化到最终合入主线的全过程,具有很高的可迁移价值。对从事包管理、容器化或需要定制可执行文件加载流程的工程师而言,它不仅展示了 eBPF 在系统软件中的创新用法,还深入分析了 binfmt_misc 的传统缺陷与改进思路,是理解现代 Linux 可执行文件加载机制和内核贡献方法论的良好参考。

技术文章Fzakaria Blog

Who does Anubis actually stop?

文章介绍了一款名为 anubis-fetch 的工具,用于绕过 Anubis 防火墙的工作量证明(PoW)挑战。作者首先描述了为 Linux 内核 BPF binfmt_misc 开发补丁时,遇到 AI 工具无法直接抓取 lore.kernel.org 的问题,继而开发了该工具。工具通过原生实现 PoW 求解、可选的 Chromium 回退,以及对 Chrome TLS/JA3 指纹的模拟,成功绕过了 Anubis 及 Cloudflare 的被动封锁。文章进而批判了 Anubis 的无效性:攻击者可以轻易摊销一次性成本,而人类用户每次访问都要付出等待时间和设备能耗,尤其对移动端、屏幕阅读器等用户形成排斥。作者通过粗略计算,估算了全球范围因 Anubis 挑战消耗的人数和能源,指出这种措施更像是一种累退税,未能阻止真正的 AI 爬虫,反而损害了开放 Web。全文兼具工具实现细节与社会影响分析,边界清晰,不涉及复杂系统设计,但提供了可复现的方法和对反爬技术局限的反思。

推荐收录,因为它不仅是一个工具介绍,更包含了对反爬技术的深度批判和实证分析。文中直接展示了绕过 Anubis 的具体代码思路与效果,并通过估算了这种防御措施对人类用户造成的隐性代价,证据充分。这篇文章适合安全工程师、Web 开发者以及关注互联网开放性的读者,其可迁移价值在于提醒设计反爬系统时需权衡防御真实威胁与用户体验的平衡,避免累退性设计。

个人心得Fzakaria Blog

A TacoSprint 2026 Retrospective

文章回顾了作者在墨西哥 La Saladita 组织的 TacoSprint 2026,这是一场面向 Nix 社区的首次北美 sprint。作者从选址、搭网站、拉赞助到招募参与者,详细记录了新活动在报名不足、旅行安全顾虑和航班紧张上的现实阻力。活动期间,冲浪与编码交替的日程让团队保持了稳定节奏,并在一周内推进了动态链接、可重定位二进制、远程构建、模块系统、OCaml 运行时裁剪和跨发行版打包等工作。文中还提到 LLM agents 的交流,以及一篇仿学术风格的 trip report,整体更偏社区组织与生产力经验,而非单点技术教程。

可收录,因为它直接呈现了首个北美 Nix sprint 的组织过程、现实阻力和可持续协作节奏,适合开源社区组织者、Nix 贡献者和想提升团队产出的读者。需要注意的是,文章主要是 retrospective,技术细节分散,不适合作为某一技术方案的深入参考。

技术文章Fzakaria Blog

Hijacking ELF entry points for NixOS compatibility or WTF is wrap-buddy?

这篇文章深入讲解了 wrap-buddy 如何通过篡改 ELF 入口点、动态段和辅助向量,绕过 NixOS 上预编译二进制因动态链接器路径不兼容而无法运行的问题。作者先用一个最小 C 程序演示 patchelf/autoPatchelf 在特殊 ELF 布局下的失败场景,再逐步拆解 wrap-buddy 的做法:保存原始入口指令、清空 PT_INTERP、注入自定义 RUNPATH,并在内存中恢复原样后把控制权交给 NixOS 的动态加载器。文章的核心结论是:这种方案并不是通用替代品,而是面向“常规修补失效”的病理场景,为旧二进制兼容性提供了一条极低层但有效的路径。

推荐收录,因为它不是简单介绍 Nix 工具链,而是把 ELF 启动、动态链接与启动劫持的机制讲得非常透彻,适合长期作为系统底层兼容性问题的参考。读者可以迁移的不只是某个工具的用法,更是“当静态修补失败时,如何从进程启动链路下手”的分析方法。