Commit Graph

2 Commits

Author SHA1 Message Date
6d38a164eb chore(module): Go module 路径随托管地迁移 gitcode → github
## 背景

仓库早已迁移到 GitHub(`github.com/JianFeeeee/HomeAgent`,CI/CD 都在那边跑),
gitcode 保留为**国内只读镜像**(`ci.yml` 的 sync-gitcode-main 快进推送)。
但 go.mod 的 module 路径一直是 `gitcode.com/JianFeeeee/...` —— 既与权威源
不符,`meta.SourceURL`(AGPL §13 的源码提供入口)也指向镜像而非实际运行的代码。

## 关键区分(这是本次改动安全的前提)

两个 module 是**不同**的,影响面差一个数量级:

| module | 谁依赖 | 改它的后果 |
|---|---|---|
| `.../HomeAgent`(主仓) | **只有主仓自己** | 内部重构,零外部影响 |
| `.../homeagent-sdk`(SDK 仓) | 主仓 49 文件 + 所有外部插件 | 需重编插件 |

★ 实测确认:**插件不 import 主仓 module**(`strings qq/plugin.bin | grep HomeAgent` = 0),
只依赖 SDK 仓。而插件与内核的边界是 **RPC 方法名字符串**
(`plugin.init` / `tool.invoke`…,见 proc/protocol.go),**与 Go module 名无关**。
⇒ module 改名**不改变任何 wire 协议**,现网已装的插件照常运行。

SDK 的 GitHub 仓名是 `homeagentsdk`(无连字符),module 路径必须与之精确匹配,
否则 `go get` 会因路径不符失败,故取 `github.com/JianFeeeee/homeagentsdk`。

## 改动

- `go.mod` / `go.sum`:两个 module 路径 + require/replace
- 277 个 Go 文件 + Makefile + 打包脚本的 import 与 ldflags 路径
- SDK 仓 `meta.CoreModule`、`tools/hmapdev` 的 module 声明与工程模板
- 对外文档/链接的仓库地址(README、PLUGIN_DEV、OVERVIEW 等)

## 明确**保留** gitcode 的地方(镜像机制,不能动)

- `GITCODE_TOKEN`、`GC_URL="…@gitcode.com"`(CI 同步 job)
- `gitcode.com/api/v5/...`(release 附件上传)
- git remote `gitcode`(镜像拉取/推送)
- `docs/zh/ci-cd-runbook.md`(整篇讲镜像运维)

## 验证

- `go build ./...` / `go vet ./...` 绿
- `go test ./... -count=1` → 48 包 ok / 0 FAIL
- hmapdev 工具链编译通过(`third_party/homeagent-sdk/tools/hmapdev`)
- 全仓残留检查:module 形态的 `gitcode.com/JianFeeeee` = 0
- 镜像机制抽验:GC_URL / @gitcode / api/v5 / remote 均完好

## 顺带修正

`hmapdev/templates.go` 的注释此前写「gitcode 的模块不在 proxy.golang.org 上」——
module 已迁 GitHub,该论断不再成立。改为如实说明**为何仍默认 replace 到本机 SDK**:
离线可构建、避免版本漂移、内网可用。理由与托管地无关,故 replace 保留。
2026-10-08 10:40:17 +08:00
9c2d9b7a9c test(proc): 共享内存数据面成本分解基准(纯测量,判断 C 化是否值得)
针对「共享内存应由 C 实现」这个直觉做量化。结论:**收益判据不成立**。
基准拆出三类成本,只有分开测才知道哪类是 C 的甜区。

## 实测(small:2 toolResults + 2 ctxMsgs)

| 项 | ns/op | allocs | 占比 |
|---|---:|---:|---:|
| ③ 描述符记账(18 个 Slice) | **51** | 0 | **0.4%** |
| ① 段内字节搬运 1KB | **18** | 0 | **0.2%** |
| ① 段内字节搬运 16KB | **210** | 0 | **2%** |
| ② JSON (Marshal+Unmarshal) | **3900** | 15 | **34%** |
| 整体 write+read+compact | 10376 | 84 | 100% |

字节拷贝 1KB=18ns / 16KB=210ns(3 次重复,稳定在 ±5%):
Go 的 copy 已达 **44~71 GB/s**,接近内存带宽上限,**无余量可榨**。

## ★ 更正一处我自己的错误口径
我先前报「编解码只占端到端 9%」——**那是单次非成对采样,是错的**。
成对重测(各 3 次取中位):

| | ns/op |
|---|---:|
| 工具调用往返(inline/small,跨进程) | 30305 |
| 纯编解码(small) | 10376 |
| **占比** | **34%** |

即编解码其实是**端到端的三分之一**,比 9% 重要得多。
但结论**不变**,且理由换成更有力的两条:
1. **C 的甜区恰好是最小的那块**:字节搬运仅占 0.2%~2%。
   真正的大头是 **JSON 反射占 34%**、描述符记账 51ns 占 0.4%。
2. **JSON 恰是本轮三刀反复验证「跨语言重建语义不划算」的领域**。

顺带记:这轮我又被自己的**测量方式**坑两次 ——
① 基准脚本用 `CLOCK_MONOTONIC` 却只取 `tv_nsec`(漏 `tv_sec`),
   算出 -4201ns 负值;② 用 `grep 'ns/op'` 批量取数时,
   把 `JsonOnly/empty`(0.4ns)误当成 `small`(3310ns)读了进来。
⇒ 拿荒谬数值先怀疑工具;批量取数要确认匹配到的是**哪一行**。

## 三条判据
1. 大头是 JSON 反射(34% 时间、15 分配),不是内存带宽。
2. C 的甜区(memcpy 类)只占 0.2%~2%,无榨取空间。
3. 段内读是**不可信偏移**(arena.go 注释自述 offset 由插件转述,
   伪造会破坏块链;payload 可达 MB 级)—— Go 的边界检查 + panic +
   `-race` + 模糊测试覆盖它;C 越界是静默堆破坏。

## 另一条架构判据
格式常量在两仓各写一份(内核 `shm.go` 与 SDK `proc_main.go.tmpl`
各有 `shmStageFieldCount=18`/`sliceSize=8`/`offMagic`)。
C 化一旦动 ABI 须走 SDK 发版 + 两仓版本对齐(MIT vs AGPL),
否则「新内核 + 旧插件」静默错位。本文件只是基准,不涉及 ABI 变更。

## 「C 是共享内存原生语言」在本项目为何不成立
1. **插件侧根本不用指针**:SDK 模板只做 `syscall.Mmap` 拿 `[]byte`,
   全程相对偏移 `{off,len}`、零指针重解释、零 unsafe。
   跨进程 mmap 到不同虚拟地址 —— 这正是必须用偏移的原因,
   C 的指针模型在这里用不上。
2. **真正原生的部分是 Go 更强的地方**:memfd 惰性物理内存
   (未触碰页不占物理内存,MB 级 arena 近零常驻)+ first-fit +
   邻块合并 + owner 校验;OS 语义 cgo 一样要调。
3. C 化还会破坏「整个新架构零 cgo」这条已达成的不变量。

验证:go test -benchtime 全绿,无回归。
2026-09-26 11:22:55 +08:00