source-fingerprint-self-upgrade-yashu

v2026.09.24

【参考资料·被动·不自动触发】"源码指纹自升级(Source Fingerprint Self-Upgrade)"机制的设计原理与可运行 Node.js 示例集合。程序启动时对自身 .js 源码算 sha256 指纹,比对已在运行的旧程序指纹,决定自升级或防重复启动。本 skill 仅作参考资料,AI 不会主动调用;请主动 @ 或在明确要求查阅时加载。

GitHub
Install command
npx skhub add steelan9199/source-fingerprint-self-upgrade-yashu
Markdown
SKILL.md

源码指纹自升级(Source Fingerprint Self-Upgrade)—— 参考资料

⚠️ 本 skill 是参考资料,不是可执行功能。AI 不会自动触发它去做任何事;只有你主动 @ 它、或明确要求查阅时才会加载。其价值在于:把「源码指纹自升级」这套设计思路归档成规范形态,供你阅读、或往自己项目里套。

这是什么

"源码指纹自升级"是一种让程序在启动时自己判断该不该启动、要不要替换掉已经在跑的旧程序的做法。

核心思路:不靠人手动输出版本号,而是直接对程序自身的源码算一个哈希指纹。源码有任何改动,指纹就变;没动,指纹就不变。

启动流程

  1. 程序启动,先算自己的源码指纹 FP_new。
  2. 检查目标端口有没有已经在跑的旧程序。
  3. 没有旧程序 → 直接正常启动。
  4. 有旧程序 → 向它要它的指纹 FP_old。
    • FP_old === FP_new → 两份代码一模一样,说明"我"就是已经在跑的那个 → 直接退出(不要重复启动)。
    • FP_old !== FP_new → 代码升级了 → 先优雅关闭旧程序(释放端口),再启动自己(替掉旧的)。

为什么不用版本号

版本号是"人写的字符串",容易漏改:

  • 改了代码但忘了 bump 版本号 → 两份不同代码被认为"同一版本" → 旧程序不会被替换,bug 还在。
  • 没改代码但误 bump 版本号 → 被认为是"新版本" → 白白重启一次。

源码指纹是"代码算出来的",代码变它才变,不存在"忘了改"的问题。

大公司通常结合使用:版本号(给人看)+ commit 哈希 / 构建摘要(给机器比)+ 健康检查接口。源码指纹是其中"给机器比"的一种,且不需要 git、不需要构建步骤,纯 JS 项目直接可用。

采集哪些指纹(规则)

指纹模块 demo/fingerprint.js 的规则如下:

规则说明
只采集 .js 文件这是真正的"源码",会影响程序行为。非 JS 脚本(.sh/.py/.bat 等)不算。
递归扫描从根目录开始,子目录、子子目录全部递归进去,包括任意层嵌套子模块。
按路径排序先 sort() 再拼接,保证不同机器、不同文件名顺序下指纹一致。
算法 sha256用 Node 内置 crypto,无第三方依赖。
取前 16 位十六进制digest("hex").slice(0,16),够区分又好展示。
文件间用 \0 分隔每个文件内容后加一个 \0,避免两个文件首尾拼接产生误判。
排除运行期目录node_modules、runtime、以 . 开头的目录不计入(这些不是源码)。
读不到就跳过单个文件读失败不影响整体,保证健壮性。

关键:非 JS 脚本(如 demo/scripts/run.sh)是程序的一部分,但按规则不计入指纹。 因为改个部署脚本不该触发"代码升级重启"。

文件结构

source-fingerprint-self-upgrade/
├── SKILL.md            # 本文件(skill 入口)
├── README.md           # 详细原理与规则文档
├── package.json        # type: module
├── demo/               # 示例程序(可运行)
│   ├── fingerprint.js  # 指纹计算模块(核心,纯函数)
│   ├── main.js         # 入口:HTTP 服务 + 自升级协调逻辑
│   ├── lib/            # 递归扫描验证用的嵌套模块
│   └── scripts/        # 非 JS 脚本(不计入指纹)
└── test/
    └── test.js         # 最简单的测试

怎么跑(验证用,非 skill 功能)

cd source-fingerprint-self-upgrade
node demo/main.js            # 启动示例服务(默认端口 9421)
# 另开终端
curl http://localhost:9421/version   # 看指纹
curl http://localhost:9421/health    # 健康检查
node test/test.js           # 跑测试(验证指纹行为)

验证指纹是否生效:

  • 改一个 .js 文件(例如给 lib/util.js 加一行注释)→ 指纹立刻变化。
  • 改 scripts/run.sh → 指纹不变(它不计入指纹)。

给 AI 的提示(套用到你自己的项目时看)

如果你(AI)要帮用户实现这套机制:

  1. 把 fingerprint.js 当成一个纯函数模块引入,不要在里面写副作用。
  2. 入口文件在启动逻辑最前面调用 computeFingerprint(),并在 /version 接口返回它。
  3. 自升级协调要遵守顺序:先让旧程序释放端口,再启动自己。绝不允许"先启动新的、再杀旧的"——新程序会因端口被占而启动失败。
  4. 关闭旧程序优先用程序自己提供的优雅停机接口(如 POST /shutdown);没有的话再回退到按 PID 杀进程。
  5. 指纹不一致且旧程序无响应时,要有超时兜底,避免卡死。
  6. 永远不要为了"方便"把 node_modules、上传目录、截图目录算进指纹,否则指纹会天天变。

备注:更完整的背景说明见同目录 README.md。

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

Not specified

Source path

skills/source-fingerprint-self-upgrade-yashu

Default branch

main

Latest commit

03b646a

Tree SHA

e79e9ee