{
  "generatedAt": "2026-10-22T00:24:25Z",
  "org": "oekit",
  "modules": [
    {
      "module": "pkg",
      "latest": "v0.21.0",
      "nested": [],
      "matrixDeps": [],
      "breakingIndex": [
        {
          "version": "v0.17.0",
          "line": "原实现 `keep = min(Keep, n/2)` 的收缩逻辑，在 `n ≤ 2*Keep` 时让**头尾两段保留位 首尾相接覆盖整段原文**——掩码主体 `****` 只是插在中间的装饰，原值被完整留在输出里"
        },
        {
          "version": "v0.17.0",
          "line": "实测（Keep=4）：`Mask(\"01234567\")` → `0123«probe:****»4567`（8 个字符原文全部可见）； `Mask(\"0123\")` → `01«probe:****»23`（4 个字符原文全部可见）——**脱敏原语等于没生效**"
        },
        {
          "version": "v0.17.0",
          "line": "修法：对齐同族 `guardx/logredact.MaskHint` 的 `HintMinLenRatio=4` 口径—— 命中长度 `n < Keep*4` 一律**整段全量打码**（不做头尾保留）；`n >= Keep*4` 才保留首尾各 Keep 个"
        },
        {
          "version": "v0.17.0",
          "line": "判据是**运行期按实际命中长度**判定（不是声明比声明）：`n=4/7/8` 全掩、`n=16` 起保留"
        },
        {
          "version": "v0.17.0",
          "line": "影响：依赖旧短值输出的消费方需同步——「留 8 藏 1 等于没藏」"
        },
        {
          "version": "v0.10.0",
          "line": "**BREAKING** refactor!: `uidgen`、`validator` 两包拆分至新仓 [kitx](https://github.com/oekit/kitx)——机械替换 import 即可迁移：`github.com/oekit/pkg/uidgen` → `github.com/oekit/kitx/uidgen`、`github.com/oekit/pkg/valida"
        },
        {
          "version": "v0.9.0",
          "line": "**BREAKING** feat(container): 新增泛型容器包 `container`，整体收编原 `collectionx` 子包——`Set`/`Ring`/`Queue`/`SafeMap` 类型名与方法签名不变，仅 import 路径由 `github.com/oekit/pkg/collectionx` 改为 `github.com/oekit/pkg/container`（"
        }
      ]
    },
    {
      "module": "concurrency",
      "latest": "v0.20.0",
      "nested": [],
      "matrixDeps": [
        "pkg"
      ],
      "breakingIndex": [
        {
          "version": "v0.5.3",
          "line": "fix(deps): pkg 地板 v0.9.3 → v0.10.0（BREAKING 拆分版；本仓仅引用 singleflighttest，零代码改动）"
        }
      ]
    },
    {
      "module": "logx",
      "latest": "v0.7.1",
      "nested": [
        {
          "path": "hertzlog",
          "latest": "v0.1.0",
          "hostVersion": "v0.2.0"
        },
        {
          "path": "hlog",
          "latest": "v0.1.4",
          "hostVersion": "v0.7.1"
        },
        {
          "path": "kitexlog",
          "latest": "v0.1.4",
          "hostVersion": "v0.7.1"
        },
        {
          "path": "sink",
          "latest": "v0.1.0",
          "hostVersion": "v0.4.0"
        }
      ],
      "matrixDeps": [
        "core"
      ],
      "breakingIndex": [
        {
          "version": "v0.7.0",
          "line": "`ParseLogLevel` 签名改为 `(Level, error)`（#13：原 `*Level` 失败为 nil，漏判空会在 LOG_LEVEL 配错时远端解引用 panic）；新增 `ParseLogLevelOr(s, def)`——「配错退默认」 免判空形态。矩阵内无外部消费方（已核对），BREAKING 影响面为矩阵外"
        },
        {
          "version": "v0.4.0",
          "line": "**refactor(shutdown)**：`Manager` 原语迁至 [oekit/core](https://github.com/oekit/core) `lifecycle` 包（与 `lifecycle.App` 契约同域，lifecycle 零外部依赖）。 `logx/shutdown` 保留类型别名转发一个版本（Deprecated），**v0.5.0 删除**； 请迁移到 `g"
        },
        {
          "version": "v0.4.0",
          "line": "**refactor(sink)**：`Sink`/`MultiSink`/`FileSink`/`RotatingSink`/`RotatingOption` 整体迁至嵌套模块 `github.com/oekit/logx/sink`（含 lumberjack）。根包自此 **纯 stdlib、零外部依赖**，不再向只用门面的消费者传递 lumberjack （[#7](https://gith"
        },
        {
          "version": "v0.3.0",
          "line": "**breaking / behavior change**：`NewSlogLogger` 尊重 `LOG_LEVEL`（原先忽略）。 级别优先级：`WithLevel` > `LOG_LEVEL` > 默认 `LevelInfo`。裸调 `NewSlogLogger(svc)` 的消费方在部署了 `LOG_LEVEL=warn|error` 时会过滤 Info/Debug——**审计/合规类 "
        },
        {
          "version": "v0.2.0",
          "line": "**refactor**：本仓改为**嵌套多模块**布局——`hlog`/`hertzlog`/`kitexlog` 三个桥接 子包各自持有独立 go.mod（module `github.com/oekit/logx/hlog` / `.../hertzlog` / `.../kitexlog`，同仓不同模块，先例 oekit/bootstrap 的 `nacos/`、`obs/`）。 **im"
        },
        {
          "version": "v0.1.8",
          "line": "**breaking**：hertzlog 删除旧适配别名 `AsHlogLogger`/`AsHlogLoggerFromXxx`， 统一 `AsHlogLoggerXxx` 系列并改为自包含实现（四后端均直接实现 hlog.FullLogger）"
        }
      ]
    },
    {
      "module": "core",
      "latest": "v0.12.0",
      "nested": [],
      "matrixDeps": [],
      "breakingIndex": [
        {
          "version": "v0.9.2",
          "line": "**breaking(检查行为)**：移除 `ValidateTags` 中依赖进程环境的 env「拼写冒烟检查」——会误报 `PATH`/`HOME` 等系统变量（合法配置在 CI/宿主机启动失败，如字段 `Path` + `env:\"LOG_PATH\"` 撞上系统 `PATH`），且漏掉无人设置的真拼写错误（[#8](https://github.com/oekit/core/issues/8"
        },
        {
          "version": "v0.6.0",
          "line": "**breaking**：`config.ConfigWatcher` 日志接口改为 `*slog.Logger`（原 `logx.Logger`）， `SetLogger(*slog.Logger)`。core 模块自此**不再依赖 logx**，消除 L0→L1 反向依赖 （[oekit#1](https://github.com/oekit/oekit/issues/1)）"
        }
      ]
    },
    {
      "module": "kitx",
      "latest": "v0.3.0",
      "nested": [],
      "matrixDeps": [
        "pkg"
      ],
      "breakingIndex": []
    },
    {
      "module": "metrics",
      "latest": "v0.1.9",
      "nested": [],
      "matrixDeps": [
        "core"
      ],
      "breakingIndex": []
    },
    {
      "module": "tracing",
      "latest": "v0.3.0",
      "nested": [],
      "matrixDeps": [
        "logx"
      ],
      "breakingIndex": [
        {
          "version": "v0.2.0",
          "line": "删除逐字节重复包 `instrumentation/redis`（≡ `redisotel`）与 `instrumentation/httpotel`（≡ `httpotel`）"
        },
        {
          "version": "v0.2.0",
          "line": "`httpotel` 包名 `httpxotel` → `httpotel`（目录名=包名对齐）"
        },
        {
          "version": "v0.2.0",
          "line": "`gormotel` 删除 `WithoutServerAddress` 选项（server.address 改为 `WithServerAddress` 显式配置）"
        },
        {
          "version": "v0.2.0",
          "line": "`instrumentation/redis` → `redisotel`；`instrumentation/httpotel` → `httpotel`"
        }
      ]
    },
    {
      "module": "registry",
      "latest": "v0.5.0",
      "nested": [
        {
          "path": "nacos",
          "latest": "v0.1.0",
          "hostVersion": "v0.5.0"
        },
        {
          "path": "nacosimpl",
          "latest": "v0.1.0",
          "hostVersion": "v0.5.0"
        }
      ],
      "matrixDeps": [
        "core"
      ],
      "breakingIndex": [
        {
          "version": "v0.4.0",
          "line": "**SPI 包提升至模块根**（与 bootstrap/gormx/hertz/httpx/middleware/network 收平先例一致）："
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/registry/registry` → `github.com/oekit/registry`"
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/registry/registry/nacos` → `github.com/oekit/registry/nacosimpl`"
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/registry/registry/sdbridge` → `github.com/oekit/registry/sdbridge` 仅移动目录与导入路径，代码零逻辑变化"
        },
        {
          "version": "v0.4.0",
          "line": "删除 `Instance.GetWeight()`——负载均衡已迁至 httpx/loadbalance Selector，经 `Node.Weight()` 读取"
        },
        {
          "version": "v0.3.0",
          "line": "`config` 子包整体迁出至 [oekit/core](https://github.com/oekit/core) v0.4.0 （`github.com/oekit/registry/config` → `github.com/oekit/core/config`，API 不变）。 config 只依赖 yaml+logx，原先挂在 registry 下导致只需文件加载的服务被迫拖 Nac"
        }
      ]
    },
    {
      "module": "data",
      "latest": "v0.17.0",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "gormx",
        "logx",
        "pkg",
        "redisx",
        "timertask"
      ],
      "breakingIndex": [
        {
          "version": "v0.17.0",
          "line": "**BREAKING**: 最低 Go 版本地板 1.24.0 → 1.26.0——工具链被钉在 1.24/1.25 的下游（GOTOOLCHAIN=local）会直接报 \"go: go.mod requires go >= 1.26.0\"，需升到 Go 1.26+。对外发布的地板本就是 1.26+（oekit BOM 徽章与 go.mod 均为 1.26），故不改变对外契约，只影响直接依赖本仓的"
        },
        {
          "version": "v0.15.0",
          "line": "`timertask` 壳移除 `RedisBackend` / `ShardManager` / `NewRedisBackend` / `NewShardManager` 四个转发符号：源仓 timertask v0.2.0 起把 Redis 后端迁至嵌套模块 `github.com/oekit/timertask/redis`（根包不再引 go-redis，纯 stdlib 嵌入式场景可用）"
        },
        {
          "version": "v0.15.0",
          "line": "`timertask` 壳新增 `BackendConfig` / `ResolveOptions`（源仓 v0.2.0 新增—— 嵌套后端模块经该结构接收选项解析结果，下游选项写法 `timertask.WithWorkers(4)` 不变）"
        },
        {
          "version": "v0.14.0",
          "line": "go 地板 1.24.0 → **1.25.0**（`data/crud` 壳的类型别名从 `[T]` 参数化为 `[T, ID comparable]` 需要泛型 type alias 语言特性；CI 工具链已为 1.26 无需改动）"
        },
        {
          "version": "v0.14.0",
          "line": "`data/crud`：`Reader`/`Writer`/`Repository`/`TxRepository`/`Service`/`BaseService` 别名 → `[T, ID comparable]`，`NewBaseService[T, ID, CreateReq, UpdateReq]` 转发签名跟随 （与源包保持同一类型，双向赋值互通不变）"
        },
        {
          "version": "v0.14.0",
          "line": "`data/cached`：`CachedRepository[T]` → `[T, ID comparable]`，全部 `CachedOption` 跟随； `WithID(fn func(*T) ID)`；`GetByIDs(ctx, ids []ID) (map[ID]*T, error)`；bloom 门与 事务失效清单全链路 ID 泛型"
        },
        {
          "version": "v0.14.0",
          "line": "**新增 `WithIDCodec`**：缓存键 ID 段编解码逃生口。缺省编解码支持 string 直通与全部 整型（十进制，**与 v0.13 及之前 int64 时代的键格式完全兼容**，存量缓存键零迁移）； 其余 comparable 类型（复合键等）必须显式注入，键解码失败 fail-fast 报错（绝不猜测性回源）"
        },
        {
          "version": "v0.14.0",
          "line": "缺省 ID 探测收紧：`GetID()` 方法 / `ID` 字段的类型须与 `ID` **精确一致** （int64 实体 + `ID=int64` 行为不变）"
        },
        {
          "version": "v0.14.0",
          "line": "`QueryCache[T]` 不涉及主键，签名不变"
        },
        {
          "version": "v0.14.0",
          "line": "gormx 地板 v0.5.5 → **v0.6.0**（门面跟版税）"
        },
        {
          "version": "v0.14.0",
          "line": "迁移：存量 int64 调用点机械补实参——`cached.NewRepository[User]` → `[User, int64]`、 `cached.WithID[User]` → `[User, int64]` 等；string 文本主键 / UUID 实体现已原生可用"
        },
        {
          "version": "v0.14.0",
          "line": "新增文本主键端到端测试（string PK：Create/GetByID/UpdateFields 失效/GetByIDs/Delete， 走真实 sqlite + SingleFlightCache，钉缺省键编解码往返）"
        },
        {
          "version": "v0.9.0",
          "line": "**BREAKING** fix(cache/cachetest): 删除壳残留的原生 AsideCache 族——`cache` 侧 `AsideCache`/`NewAsideCache`/`AsideOption`/`SourceFuncWithTTL`/`SourceFrom`/ `TTLCacheAside`/`OnStaleFunc`/`WithStaleIfError`/`WithO"
        },
        {
          "version": "v0.5.0",
          "line": "**breaking** feat!: data 门面化——八子包 re-export 复刻 ekit data/ 能力面 （cache/rediscache/crud/distlock/gormx/redisx/timertask/cachetest，类型为 泛型 type alias 与源包同一类型；实现住 pkg 与各子仓）"
        },
        {
          "version": "v0.5.0",
          "line": "**breaking** feat(all)!: `all/` 聚合模块全部版本 retract——一键全家桶由本 门面取代（期间短暂引入的 all/ 聚合嵌套模块一并废弃）"
        },
        {
          "version": "v0.4.0",
          "line": "**breaking** refactor(cache): 目录正名 `data/cache` → `cache`——import 路径 `github.com/oekit/data/data/cache` → `github.com/oekit/data/cache`（包名保持 `cache` 不变）；零已知消费方，redis 模块（github.com/oekit/redis）的 import"
        },
        {
          "version": "v0.4.0",
          "line": "**breaking** feat(cache): `LocalCache.Close()` → `Close(ctx context.Context) error` 对齐仓库生命周期硬规则——sync.Once 幂等保留，stop 后台 cleanup goroutine， ctx 预留（当前实现同步返回 nil，ctx 不阻塞）；零已知消费方"
        }
      ]
    },
    {
      "module": "gormx",
      "latest": "v0.6.1",
      "nested": [],
      "matrixDeps": [
        "logx",
        "pkg"
      ],
      "breakingIndex": [
        {
          "version": "v0.6.0",
          "line": "**BREAKING**: crud/gormrepo 主键类型泛型化（#7 问题 1）——接口全链路加 `ID comparable`"
        },
        {
          "version": "v0.6.0",
          "line": "crud：`Reader[T]`/`Writer[T]`/`Repository[T]`/`TxRepository[T]`/`Service[T, C, U]` → `[T, ID comparable]`；`BaseService`/`NewBaseService`/Set*Hook 签名同步（`id int64` → `id ID`）。 存量调用点机械迁移：`NewBaseService[T"
        },
        {
          "version": "v0.6.0",
          "line": "gormrepo：`GormRepository[T]` → `[T, ID comparable]`；`WithQueryDecorator`/`WithScopeRequired` 维持 `[T]`（decorator 不接触 ID，无需迁移）"
        },
        {
          "version": "v0.6.0",
          "line": "**行为加固（同波）**：GetByID/Delete/BatchDelete 主键条件从 GORM 内联值改为 `clause.PrimaryColumn`（schema 解析 + 参数化）——GORM 将内联非数字 string 按 SQL 片段解析， 内联形态对文本主键是注入面/语法错误；int64 路径 SQL 语义不变；GetByID 未命中错误格式 `id=%d` → `id=%v`"
        },
        {
          "version": "v0.6.0",
          "line": "根包 `model.go`（BaseModel 系列）与 `singleton.go`（Identifier）**保留 int64**： 自增主键便捷基类，文本主键项目自定义实体 struct 即可"
        },
        {
          "version": "v0.6.0",
          "line": "新增文本主键回归测试（string PK 全路径：GetByID/UpdateFields/Delete/BatchDelete/ BaseService 事务路径/-race）"
        }
      ]
    },
    {
      "module": "redisx",
      "latest": "v0.10.0",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "logx",
        "pkg"
      ],
      "breakingIndex": [
        {
          "version": "v0.10.0",
          "line": "**BREAKING**: 最低 Go 版本地板 1.24.0 → 1.26.0——工具链被钉在 1.24/1.25 的下游（GOTOOLCHAIN=local）会直接报 \"go: go.mod requires go >= 1.26.0\"，需升到 Go 1.26+。对外发布的地板本就是 1.26+（oekit BOM 徽章与 go.mod 均为 1.26），故不改变对外契约，只影响直接依赖本仓的"
        },
        {
          "version": "v0.5.0",
          "line": "**breaking（0.x minor）**：模块更名 `github.com/oekit/redis` → `github.com/oekit/redisx`， 消除与 go-redis（`package redis`）的包名撞车与 `/redis/redis` 路径口吃"
        },
        {
          "version": "v0.4.0",
          "line": "**null 哨兵变更**：`__NULL__` → `\"\\x00oekit:null\"`（以 `\\x00` 开头的值保留为 null 标记专用前缀）。旧哨兵可被 `SetRaw` 合法写入精确碰撞（写入字面 `__NULL__` 即被永久误判为\"数据不存在\"，GetOrLoad 不再回源）；新哨兵带 `\\x00` 前缀，合法 JSON 序列化输出不会自然撞上。**存量影响**：旧缓存中由 Get"
        },
        {
          "version": "v0.4.0",
          "line": "`SetRaw` 新增契约约束：data 不得以 `\\x00` 开头（保留为 null 标记前缀； 精确等于哨兵的字节按 null marker 处理，其余 `\\x00` 开头值不认作 null）"
        },
        {
          "version": "v0.2.0",
          "line": "`redisx.NewClient` / `NewClientFromAddr` / `NewClientFromConfig` **不再自动注入 OTel tracing** （原先强制 `redisotel.InstrumentTracing`，无出口）；go.mod 不再依赖 go-redis extra"
        }
      ]
    },
    {
      "module": "etcdx",
      "latest": "v0.1.6",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "logx",
        "registry"
      ],
      "breakingIndex": []
    },
    {
      "module": "httpx",
      "latest": "v0.8.2",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "logx",
        "metrics",
        "pkg",
        "registry",
        "tracing"
      ],
      "breakingIndex": [
        {
          "version": "v0.8.0",
          "line": "**breaking(包删除)**：移除 v0.7.0 内置的 `httpx/urlguard` 独立实现 （`IsBlockedIP`/`IsBlockedHost`/`IsBlockedURL`/`GuardAddr`/`GuardAddrContext`/ `SafeDialer`/`SetAllowPrivateForTest`）——与 pkg v0.15.0 的 `pkg/urlguar"
        },
        {
          "version": "v0.4.0",
          "line": "`loadbalance` 包重写为 Selector 形态（参照 go-kratos selector）： Node 携带完整实例信息（Address/Weight/ServiceName/Metadata）、`WithFilter` 按元数据过滤、 `DoneFunc` 回写调用结果（`WithDoneHook` 采集，为 P2C/EWMA 预留）"
        },
        {
          "version": "v0.4.0",
          "line": "删除：`loadbalance.Balancer`/`Instance`/`ToInstances`/`New`/`NewRoundRobin`/`NewRandom`/`NewWeighted`、 `httpx.BalanceStrategy`/`WeightedBalanceStrategy`/`NewBalanceAdapter`/`HashBalance`、 `httpx.WithBala"
        },
        {
          "version": "v0.4.0",
          "line": "`EndpointManager` 重构为节点快照缓存（`GetNodes`/`SetNodes`，替代 `GetEndpoints`/`SetEndpoints` ——后者保留但等权合成）；`Pick(ctx, key)` 返回 `(addr, DoneFunc, err)`，调用出口回写最终错误"
        },
        {
          "version": "v0.4.0",
          "line": "registry 依赖升级 v0.4.0（SPI 包提升至模块根）"
        },
        {
          "version": "v0.3.0",
          "line": "**核心包提升到模块根**：import 从 `github.com/oekit/httpx/httpx` 改为 `github.com/oekit/httpx`（包名仍为 `httpx`）"
        }
      ]
    },
    {
      "module": "network",
      "latest": "v0.5.5",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "logx",
        "tracing"
      ],
      "breakingIndex": []
    },
    {
      "module": "timertask",
      "latest": "v0.2.1",
      "nested": [
        {
          "path": "redis",
          "latest": "v0.2.1",
          "hostVersion": "v0.2.1"
        }
      ],
      "matrixDeps": [
        "pkg"
      ],
      "breakingIndex": [
        {
          "version": "v0.2.1",
          "line": "v0.2.0 的 Breaking 段写「改用 `github.com/oekit/timertask/redis`（import 路径替换即可，API 不变）」 ——**这句是错的**：`timertask/redis` 不是根包下的子目录，它是**独立的 Go module** （有自己的 go.mod、自己的 tag `redis/v0.2.0`）。消费方只改 import 路径、**不新增"
        },
        {
          "version": "v0.2.0",
          "line": "**Redis 后端迁至嵌套模块**：`RedisBackend`/`NewRedisBackend`/`ShardManager`/`NewShardManager` 从根包移除，改用 `github.com/oekit/timertask/redis`（**API 不变，但 import 路径与 go.mod require 两处都要改**——`timertask/redis` 是**独立 m"
        },
        {
          "version": "v0.2.0",
          "line": "**根包不再依赖 `github.com/oekit/logx`**：日志改用标准库 `log/slog`（消费方经 `slog.SetDefault` 汇流）；同时剥离 `github.com/oekit/concurrency`（`async.GoSafe` 改为包内等价实现）"
        },
        {
          "version": "redis/v0.2.0",
          "line": "**从根包迁出**：`RedisBackend`/`NewRedisBackend`/`ShardManager`/`NewShardManager` 原位于 `github.com/oekit/timertask` 根包，v0.2.0 起迁至本模块——import 路径替换即可，API 不变："
        }
      ]
    },
    {
      "module": "middleware",
      "latest": "v0.13.1",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "core",
        "logx",
        "metrics",
        "pkg",
        "registry",
        "tracing"
      ],
      "breakingIndex": [
        {
          "version": "v0.5.0",
          "line": "**核心包 `mw` 提升到模块根**：import 从 `github.com/oekit/middleware/middleware` 改为 `github.com/oekit/middleware`（包名仍为 `mw`）"
        },
        {
          "version": "v0.5.0",
          "line": "**删除重复层** `middleware/contrib/`（与根 `contrib/` 字节级重复的副本）"
        },
        {
          "version": "v0.5.0",
          "line": "**删除废弃转发层** `middleware/traceid/hmw/`（原 Deprecated 兼容层）"
        }
      ]
    },
    {
      "module": "k8s",
      "latest": "v0.1.3",
      "nested": [],
      "matrixDeps": [
        "logx"
      ],
      "breakingIndex": []
    },
    {
      "module": "nns",
      "latest": "v0.4.4",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "core",
        "logx",
        "registry"
      ],
      "breakingIndex": [
        {
          "version": "v0.4.0",
          "line": "**包提升至模块根**："
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/nns/nns` → `github.com/oekit/nns`"
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/nns/nns/client` → `github.com/oekit/nns/client`"
        },
        {
          "version": "v0.4.0",
          "line": "`github.com/oekit/nns/nns/metadata` → `github.com/oekit/nns/metadata` 仅移动目录与导入路径，代码零逻辑变化"
        },
        {
          "version": "v0.4.0",
          "line": "依赖升级：registry v0.4.0（SPI 包提升至模块根）"
        }
      ]
    },
    {
      "module": "nns-endpoint",
      "latest": "v0.2.5",
      "nested": [],
      "matrixDeps": [
        "httpx",
        "logx",
        "metrics",
        "nns",
        "registry"
      ],
      "breakingIndex": [
        {
          "version": "v0.2.0",
          "line": "`balancerCache` → `selectorCache`（`loadbalance.Selector`，经服务配置 Lb 字段 `NewSelector(NormalizeSelectorName(lb))` 构造，不可识别回退 roundrobin）"
        },
        {
          "version": "v0.2.0",
          "line": "`HTTPEndpointFactory.ResetBalancer`/`GRPCEndpointFactory.ResetBalancer` → `ResetSelector`"
        },
        {
          "version": "v0.2.0",
          "line": "HTTP/gRPC 选点从 `Balancer.Pick(索引)` 切换为 `Selector.Select`（Node 携带元数据、 调用结果经 DoneFunc 回写）"
        },
        {
          "version": "v0.2.0",
          "line": "新增 `WithSelector(sel loadbalance.Selector)` 工厂选项：全服务共用注入的选择器， 覆盖服务治理配置中的 lb 策略"
        },
        {
          "version": "v0.2.0",
          "line": "依赖升级：httpx v0.4.0 / nns v0.4.0 / registry v0.4.0（三仓均扁平化/Selector 化）"
        }
      ]
    },
    {
      "module": "bootstrap",
      "latest": "v0.6.4",
      "nested": [
        {
          "path": "nacos",
          "latest": "v0.3.5",
          "hostVersion": "v0.6.4"
        },
        {
          "path": "obs",
          "latest": "v0.2.9",
          "hostVersion": "v0.6.4"
        }
      ],
      "matrixDeps": [
        "concurrency",
        "core",
        "logx"
      ],
      "breakingIndex": [
        {
          "version": "nacos/v0.3.0",
          "line": "**feat!**：`WithNNS` 注册延迟到 `App.Ready()` 之后——修复「注册先于 server 监听、反注册后于 server 关闭」双序错误，关停序 nns-deregister → server.Shutdown 对齐 kratos Stop"
        },
        {
          "version": "v0.5.0",
          "line": "**核心包提升到模块根**：import 从 `github.com/oekit/bootstrap/bootstrap` 改为 `github.com/oekit/bootstrap`（包名仍为 `bootstrap`）"
        },
        {
          "version": "v0.5.0",
          "line": "**healthz 路径同步**：`github.com/oekit/bootstrap/bootstrap/healthz` → `github.com/oekit/bootstrap/healthz`"
        },
        {
          "version": "nacos/v0.3.0",
          "line": "**注册时机变更**：`WithNNS`/`WithRequiredNNS` 的服务注册由组件 Init 阶段延迟到 `app.Ready()` 之后（bootstrap v0.6.0 就绪门）。调用方必须在 server 就绪后触发 `app.Ready()`（推荐经 hertz/kitex `RunServer` 的 `WithOnReady`），否则服务不会 进入注册中心；Ready 永不触"
        },
        {
          "version": "nacos/v0.3.0",
          "line": "**停机序修正**：反注册改在注册成功后经 `app.AddResource` 挂载——close 阶段按注册 逆序释放，关停序为 nns-deregister → server.Shutdown（对齐 go-kratos Stop 语义； 旧实现 server 已关闭后才反注册）"
        },
        {
          "version": "nacos/v0.3.0",
          "line": "依赖升级：nns v0.4.0 / registry v0.4.0（双仓包提升至模块根）"
        }
      ]
    },
    {
      "module": "hertz",
      "latest": "v0.8.1",
      "nested": [],
      "matrixDeps": [
        "bootstrap",
        "concurrency",
        "core",
        "gormx",
        "kitx",
        "logx",
        "metrics",
        "middleware",
        "nns",
        "pkg",
        "registry",
        "tracing"
      ],
      "breakingIndex": [
        {
          "version": "v0.8.0",
          "line": "**BREAKING**: `CheckResult.Status` 由 `string` 改为 `health.Status`（底层仍是 `string`）。与字面量比较的调用点不受影响；把 `CheckResult.Status` 赋给 `string` 变量的调用点需显式 `string(...)` 转换"
        },
        {
          "version": "v0.7.0",
          "line": "**BREAKING**: crudh 主键类型泛型化（跟随 gormx v0.6.0 `[T, ID comparable]`，gormx#7 问题 1）"
        },
        {
          "version": "v0.7.0",
          "line": "`Handler[T, C, U]` → `Handler[T, ID comparable, C, U]`；`HandlerOption`/`WithSortableColumns`/ `NewHandler` 签名跟随（`crud.Service[T, ID, C, U]`）"
        },
        {
          "version": "v0.7.0",
          "line": "新增 `WithIDParser(fn func(string) (ID, error))`：路径参数 → ID 解析注入"
        },
        {
          "version": "v0.7.0",
          "line": "缺省解析（不注入时）：int 系主键 `strconv.ParseInt`（宽度随 ID 类型，int64 与 v0.6 之前 行为一致）、string 主键直通；其余 comparable 类型必须显式注入，缺省解析失败按 400 拒绝 （fail-closed）"
        },
        {
          "version": "v0.7.0",
          "line": "存量 int64 调用点机械迁移：`NewHandler[Item, C, U]` → `NewHandler[Item, int64, C, U]`； 文本主键项目传恒等解析 `WithIDParser[Doc, string, C, U](func(s string) (string, error) { return s, nil })`"
        },
        {
          "version": "v0.7.0",
          "line": "新增文本主键端到端测试（hex 串路径参数经 WithIDParser 直通 + Get/Delete/404 链）与 `defaultParseID` 单测（int64/string 双形态）"
        },
        {
          "version": "v0.5.1",
          "line": "**核心包 `hertz` 提升到模块根**：import 从 `github.com/oekit/hertz/hertz` 改为 `github.com/oekit/hertz`（包名仍为 `hertz`），消除双层目录"
        },
        {
          "version": "v0.5.1",
          "line": "**子包收成一级**：`hertz/health` → `health`、`hertz/sse` → `sse`、 `hertz/metrics` → `metrics`、`hertz/render` → `render`、`hertz/adaptor` → `adaptor`"
        },
        {
          "version": "v0.5.1",
          "line": "**适配器扁平化**： `governance/hertz` → `governance`（包名 govhertz 不变，避免与 core/governance 冲突）、 `registry/hertz` → `registry`（包名 hertz → registry）、 `nns/hertz` → `nns`（包名 hertz → nns）"
        },
        {
          "version": "v0.5.1",
          "line": "**可观测路径收拢**：`observability/tracing/instrumentation/hertzotel` → `hertzotel`、 `observability/tracing/instrumentation/hertztracer` → `hertztracer`"
        }
      ]
    },
    {
      "module": "kitex",
      "latest": "v0.6.5",
      "nested": [],
      "matrixDeps": [
        "bootstrap",
        "concurrency",
        "core",
        "logx",
        "metrics",
        "nns",
        "pkg",
        "registry"
      ],
      "breakingIndex": [
        {
          "version": "v0.6.0",
          "line": "**主包提升至模块根**：`github.com/oekit/kitex/kitex` → `github.com/oekit/kitex`、 `.../kitex/kitex/kitexmeta` → `.../kitex/kitexmeta`（仅移动目录与导入路径，零逻辑变化）"
        }
      ]
    },
    {
      "module": "workflow",
      "latest": "v0.3.2",
      "nested": [],
      "matrixDeps": [
        "concurrency",
        "logx"
      ],
      "breakingIndex": [
        {
          "version": "v0.3.0",
          "line": "**包提升至模块根**：`github.com/oekit/workflow/workflow` → `github.com/oekit/workflow` （仅移动目录与导入路径，代码零逻辑变化；矩阵内无消费方）"
        }
      ]
    },
    {
      "module": "kitex-examples",
      "latest": "v0.1.20",
      "nested": [],
      "matrixDeps": [
        "bootstrap",
        "core",
        "kitex",
        "logx",
        "tracing"
      ],
      "breakingIndex": []
    }
  ]
}
