vxlan 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -0
  3. data/README-zh.md +32 -4
  4. data/README.md +32 -4
  5. data/bin/README.md +203 -0
  6. data/bin/vxlan +8 -0
  7. data/docs/architecture-zh.md +62 -60
  8. data/docs/evidence-contracts.md +54 -0
  9. data/docs/remediation.md +84 -0
  10. data/docs/review-2026-10-19.md +31 -0
  11. data/docs/superpowers/plans/2026-10-19-command-line.md +69 -0
  12. data/docs/superpowers/plans/2026-10-19-connector-integration.md +83 -0
  13. data/docs/superpowers/plans/2026-10-19-evidence-contracts.md +64 -0
  14. data/docs/superpowers/plans/2026-10-19-vxlan-examples.md +47 -0
  15. data/docs/superpowers/plans/2026-10-20-fabric-consistency.md +28 -0
  16. data/docs/superpowers/specs/2026-10-19-command-line-design.md +78 -0
  17. data/docs/superpowers/specs/2026-10-19-connector-integration-design.md +100 -0
  18. data/docs/superpowers/specs/2026-10-19-evidence-contracts.md +11 -0
  19. data/examples/README.md +20 -0
  20. data/examples/collect.rb +8 -0
  21. data/examples/parse.rb +5 -0
  22. data/lib/vxlan/acl_policy.rb +50 -0
  23. data/lib/vxlan/change_plan/svi_acl.rb +76 -0
  24. data/lib/vxlan/change_plan/svi_gateway.rb +36 -0
  25. data/lib/vxlan/change_plan/vlan_vni.rb +40 -0
  26. data/lib/vxlan/change_plan.rb +131 -0
  27. data/lib/vxlan/cisco_nxos/configuration_state.rb +1 -4
  28. data/lib/vxlan/cisco_nxos/evpn_l2route.rb +1 -1
  29. data/lib/vxlan/cisco_nxos/parsers/show_bgp_l2vpn_evpn_summary.rb +65 -11
  30. data/lib/vxlan/cisco_nxos/parsers/show_cdp_neighbors_detail.rb +32 -8
  31. data/lib/vxlan/cisco_nxos/parsers/show_mac_address_table.rb +1 -1
  32. data/lib/vxlan/cisco_nxos/parsers/show_nve_peers.rb +3 -2
  33. data/lib/vxlan/cisco_nxos/parsers/show_nve_vni.rb +9 -1
  34. data/lib/vxlan/cisco_nxos/parsers/show_running_config.rb +11 -5
  35. data/lib/vxlan/cisco_nxos/parsers/show_vpc_brief.rb +10 -4
  36. data/lib/vxlan/cisco_nxos/syntax/policies.rb +16 -0
  37. data/lib/vxlan/cisco_nxos/syntax/routing.rb +16 -6
  38. data/lib/vxlan/cli/apply.rb +172 -0
  39. data/lib/vxlan/cli/collect.rb +210 -0
  40. data/lib/vxlan/cli/connector.rb +23 -0
  41. data/lib/vxlan/cli/options.rb +311 -0
  42. data/lib/vxlan/cli/parse.rb +58 -0
  43. data/lib/vxlan/cli/report.rb +223 -0
  44. data/lib/vxlan/cli/review/fabric.rb +102 -0
  45. data/lib/vxlan/cli/review/report.rb +165 -0
  46. data/lib/vxlan/cli/review.rb +125 -0
  47. data/lib/vxlan/cli/templates/env.example +12 -0
  48. data/lib/vxlan/cli/templates/vxlan.yml +32 -0
  49. data/lib/vxlan/cli.rb +41 -0
  50. data/lib/vxlan/collector.rb +59 -28
  51. data/lib/vxlan/config/evidence.rb +18 -0
  52. data/lib/vxlan/config/review.rb +56 -0
  53. data/lib/vxlan/{configuration.rb → config.rb} +1 -1
  54. data/lib/vxlan/fabric/review.rb +324 -0
  55. data/lib/vxlan/fabric/scope.rb +43 -0
  56. data/lib/vxlan/observation.rb +3 -0
  57. data/lib/vxlan/recommendations.rb +193 -0
  58. data/lib/vxlan/service/catalog.rb +77 -0
  59. data/lib/vxlan/service/mapping.rb +53 -0
  60. data/lib/vxlan/snapshot.rb +3 -0
  61. data/lib/vxlan/subnet_index.rb +88 -0
  62. data/lib/vxlan/version.rb +1 -1
  63. data/lib/vxlan.rb +4 -2
  64. metadata +137 -7
  65. data/lib/vxlan/cisco_nxos/configuration.rb +0 -10
  66. data/lib/vxlan/configuration_review.rb +0 -54
@@ -1,95 +1,97 @@
1
- > 本文保留模块从 Motor 提取前的领域设计、覆盖范围、限制与验证记录,供兼容迁移和故障分析使用。
2
- > 当前独立 gem 的安装、依赖、开发与发布入口以 [README-zh.md](../README-zh.md) 为准。
3
- > 涉及 `Motor::*`、`Sync`、`Baseline::Check`、数据库、Rails、Rake 运维任务及私有实机证据的内容均属于 Motor 宿主集成,不随 gem 提供;历史验证记录不代表当前用户设备已经验证。
1
+ # VXLAN 业务与实现边界
4
2
 
5
- # VXLAN 设备采集与入库
6
-
7
- 这个目录保存 Motor 自有的 VXLAN 业务实现,参考 Netstack 的 NX-OS 能力和已验证的完整性规则,提供配置关联核验,不搬入 Fabric 规划、报表、CLI 或远程下发引擎。Rails 通过 `config.paths` 自动加载 `lib/vxlan`;数据模型仍使用现有 `Motor::Vxlan*` 类和 Rails 可推导的关联。不新增数据表;prefix-list 以节点、名称、地址族作为唯一身份,已有记录默认 IPv4。
3
+ 当前实现是独立 Ruby gem,不依赖 Rails、数据库或 Motor。它把设备证据、业务判断、候选变更、设备执行分开;宿主决定清单、凭据、报告目录和执行时机。使用入口见 [CLI 说明](../bin/README.md),设备操作规则见 [修复建议](remediation.md)。
8
4
 
9
5
  ## 业务链路
10
6
 
11
7
  ```text
12
- Motor::Device
13
- → Motor::Devices::Connector(凭据、平台、严格主机密钥、超时、会话生命周期)
14
- → CtxDriver::Reader(net-connector 单命令采集边界)
15
- → Vxlan::Collector(同一设备逐条读取)
16
- → Configuration / RuntimeParser(维度与 Observation 适配)
17
- → CiscoNxos::Profile / Parsers::Show*(平台与型号策略、按命令解析)
18
- → Snapshot / Observation
19
- → Vxlan::Sync(锁设备、复核来源与版本、事务)
20
- → ConfigurationInventory / L2routeInventory / vxlan_segments
8
+ CLI Options:配置 + 本批有效环境 + 显式 Fabric 策略
9
+ → Collect:设备选择、并发、逐设备结果和报告
10
+ → Connector:独占操作租约与会话生命周期
11
+ → Collector / CtxDriver::Reader:同设备顺序读取
12
+ → CiscoNxos::Profile / Parsers:命令解析与证据完整性
13
+ → Observation / Snapshot:不可变事实
14
+ → Recommendations + Fabric::Review:本机诊断与共同业务比较
15
+ → Report:总览、设备诊断、证据、可选脚本、聚合计划
16
+ → Apply:单项选择、交互确认、重读、逐条记账、配置回读
21
17
  ```
22
18
 
23
- 采集通过 [`CtxDriver::Reader`](https://github.com/gatework/ctx_driver) 使用 net-connector 的 `send_commands`,统一验证单命令响应、记录来源摘要并隔离失败;不自己实现 SSH、提示符处理或登录。单脚本解析异常不丢弃已完成维度,断线后标记剩余命令 skipped。配置下发继续由 `Motor::Devices::Script` 和 Netconf 的审批快照、执行认领及设备复核负责;执行开始后的未知结果保留为未知,不自动重放。采集任务不隐式下发配置、自动保存 running-config 或修改设备配置。
19
+ `collect`、`parse`、`review` 不下发业务配置。`--scripts` 只导出建议;只有 `apply --plan plan.json --item ID` 可以进入变更链路。cfg 是审阅产物,不能作为任意脚本交给 apply 执行。
24
20
 
25
- ## 调用
21
+ ## 领域职责
26
22
 
27
- ```ruby
28
- result = Vxlan::Sync.new.call(device: Motor::Device.find(device_id), fabric_key: "LAB")
29
- result.counts
30
- result.observation.complete?
23
+ | 对象 | 负责的知识 | 不承担的职责 |
24
+ | --- | --- | --- |
25
+ | `Config` / `RuntimeParser` | 平台、型号及维度解析,返回 Observation | 清单、凭据、设备连接 |
26
+ | `CiscoNxos::ConfigurationState` | 一次解析的可变状态、关联归约 | 跨设备基线或变更意图 |
27
+ | `Observation` / `Snapshot` | 事实、完整性、来源摘要、时间与不可变身份 | 宣告网络健康 |
28
+ | `Config::Review` | 完整配置内 VLAN/NVE/EVPN/VRF 关系 | 运行可达性和部署意图 |
29
+ | `Config::Evidence` | 保存快照中唯一、外层及记录层均完整的配置证据 | 补全缺失字段或替调用者猜测完整性 |
30
+ | `Fabric::Scope` | 显式 Fabric/角色、唯一成员归属、覆盖缺口 | 根据设备名猜测角色 |
31
+ | `Service::Catalog` | 联合 VLAN/NVE/EVPN 识别业务,保留不完整部署;归一化 RT 与有效 NVE 组播 | 推断所有设备都应部署业务 |
32
+ | `Fabric::Review` | 同角色共同 VNI 的网关、ACL、承载、路由比较;Fabric 内网段冲突 | 以多数票选择策略或删除保护 |
33
+ | `Service::Mapping` | 用完整一致对端证明本机唯一缺失 VLAN/VNI 关联,返回满足前提的计划对象 | 根据 VNI 数字编码猜 VLAN |
34
+ | `SubnetIndex` | 单设备 SVI 按 VRF、地址族和前缀查询重叠,保留重复地址及来源顺序 | 将非法地址判为无冲突、替代变更执行前检查 |
35
+ | `AclPolicy` | 有序转发规则与已解析地址组的不可变策略身份 | 把未知依赖当作空策略、选择权威基线 |
36
+ | `ChangePlan` | 唯一构造入口、不可变参数与命令、配置上下文保持不变的约束 | 任意 CLI、连接会话、自动重试或自动回退 |
37
+ | `ChangePlan::VlanVni` / `SviGateway` / `SviAcl` | 各自业务增量的参数校验、命令、执行前提、目标回读和允许变化的字段 | 重复判断其他动作类型 |
38
+ | CLI `Report` / `Apply` | 产物发布、交互确认、执行记账 | 将配置回读等同业务流量验收 |
31
39
 
32
- # 仅刷新两类 L2RIB 路由;其他维度保持原有证据和数据。
33
- Vxlan::Sync.new.call(device: device, fabric_key: "LAB",
34
- dimensions: %i[l2route_macs l2route_mac_ips])
40
+ 解析状态可以可变;对外交付的 Observation/Snapshot 深复制并冻结事实。解析器使用 Symbol 键,报告和计划使用 JSON 字符串键;审查输入是保存后的设备文档。不要把解析状态、报告文档和执行计划混用。
35
41
 
36
- # 离线解析不建立设备会话,不写数据库。
37
- observation = Vxlan::Configuration.new.parse(configuration_text, complete: true)
38
- observation.status
39
- observation.records
40
- ```
42
+ 子职责的目录与常量对应:`cli/review/report.rb` 定义 `CLI::Review::Report`,`cli/review/fabric.rb` 定义 `CLI::Review::Fabric`,`cli/connector.rb` 定义 `CLI::Connector`。审查模块编排业务产物,`CLI::Report` 拥有批次目录与原子发布;采集连接适配器拥有设备会话。新增子职责沿用这一归属关系,测试目录跟随实现目录组织。
41
43
 
42
- 保留已有运维入口,避免现有调用脚本失效:
44
+ ## 采集和配置来源
43
45
 
44
- ```sh
45
- bundle exec rake 'motor:netstack:vxlan[456,LAB]'
46
- ```
46
+ 参数优先级统一为命令行 > 进程环境 > YAML > `.env` > 内置默认值。文件按系统目录、用户配置目录、脚本目录、启动目录、显式文件逐层覆盖,数组整体替换,文件中的相对路径以各自来源目录为准。`.env` 合并到本批独立环境;凭据、Netdisco 与参数共享该有效环境,不改写调用者 ENV。Fabric 策略在连接前验证并固定,文件中途改变不影响本批。
47
47
 
48
- 默认支持 Cisco NX-OS 的配置、CDP、NVE peer/VNI、BGP EVPN 邻居、OSPF 邻居、vPC、接口、Port-channel、MAC 地址表、L2RIB MAC 和 MAC-IP。命令集中在 `Collector::COMMANDS`。新增设备输出格式时,应先补脱敏 fixture 和完整/截断用例,再修改对应解析器;不能把未知输出判定为空结果。
48
+ 静态设备和 Netdisco 来源互斥;先统一校验设备身份、筛选与重复地址,再连接。不同设备并行,同设备命令串行。`Collector#collect` 通过注入的连接器拥有开关会话流程;`collect_session` 借用已有会话,由调用者负责生命周期。原生适配器在操作租约内执行,核心库不实现 SSH、提示符或重连。
49
49
 
50
- Cisco N9K 的具体策略位于 [`lib/vxlan/cisco_nxos`](../lib/vxlan/cisco_nxos/profile.rb),按命令拆分为 `parsers/show_ip_ospf_neighbors.rb` 等独立文件。直接调用 `Vxlan::CiscoNxos::Parsers::ShowIpOspfNeighbors.parse(cli_output, complete: true)` 即可离线解析。`ParserRegistry.fetch(:cisco_nxos, model: device.model)` 选择平台与型号策略;命令清单和解析类统一在 `CiscoNxos::Profile` 中声明。原解析入口继续转换为 `Vxlan::Observation`。公共接口、结果对象和扩展方式见 [`../ctx_parser`](https://github.com/gatework/ctx_parser)。
50
+ 注入连接器必须只回调一次会话。重复回调不会重采或覆盖首次事实,批次记录 `session_reentered` 并保持失败;没有回调记录 `session_not_opened`。
51
51
 
52
- 配置解析按职责组合:`ShowRunningConfig` 编排命令解析,`Syntax::Interfaces/Routing/Policies` 分别解释接口/NVE、路由上下文及策略语法,`CtxParser::Configuration` 管理逐行状态、嵌套来源路径与捕获,`CiscoNxos::ConfigurationState` 持有单次解析状态(旧名 `CiscoNxos::Configuration` 保留为兼容别名),在全部块解析后归约特性列表、校验 BGP 模板引用并关联 SVI/VLAN/VNI 网段。接口地址与网段使用 `CtxParser::Values.ipv4_prefix` 的同一校验。重复身份仍排除歧义记录;语法未知、引用不完整与来源行号继续进入原有 `Result`,供入库边界判断。
52
+ 配置先于依赖它的运行维度读取,结果保持用户请求顺序。只有完整配置证明功能未启用时才接受相应空表;空正文不能普遍解释为无数据。BGP 非空表必须有明确 EVPN 作用域,矛盾路由身份隔离整个作用域;CDP 单值冲突不可由后续声明恢复;NVE 复制地址须为已知标记或合法组播地址。断链后保留首次错误和 skipped 标记,不重放命令。关闭失败保留已获取事实,并使采集状态失败。线程异常或取消先回收本批线程,再结束批次。
53
53
 
54
- 设备连接默认关闭旧版 SSH 算法协商。确认单台旧设备确有算法兼容需求后,可在其现有 `settings["connector"]["legacy_ssh"]` 中显式保存布尔值 `true`;省略或 `false` 保持关闭,字符串、NULL 等非布尔值会在连接前拒绝。该设置直接传给 net-connector,主机密钥仍严格核验 `storage/net_connector/known_hosts`,不启用 Telnet 回退。连接异常仅保留允许列表中的诊断码(例如 `unsupported_host_key_algorithm`),未知码归为 `connection_failed`;VXLAN 未采集维度保存该原因,不保存底层异常文案或 cause。
54
+ ## 从事实到业务建议
55
55
 
56
- ## 数据一致性
56
+ 业务身份是显式 Fabric、角色和已部署 VNI。Leaf 与 Border 分别比较,Spine 出现业务承载时提示角色冲突。VLAN/NVE/EVPN 任一事实均可证明业务已开始部署;缺环节不等于未部署。未部署设备只列覆盖差异,不自动铺开业务。
57
57
 
58
- 设备 I/O 在数据库事务外完成。入库时锁定已有设备,复核设备版本、节点来源、Fabric 及原快照;并发期间已变更的设备或节点、旧结果和同时间不同结果均拒绝写入。节点证据和所有派生清单在同一事务提交,任何写入失败全部回滚。重复投递相同快照保持现有行身份,也可重建缺失的派生行。
58
+ 本机建议、Fabric 审查与执行计划统一通过 `Config::Evidence.complete_record(document)` 取得配置。外层 complete 不能覆盖记录层 partial、缺少审查状态或多份配置的歧义;这些情况明确生成补采任务。离线入口还校验规范主机地址及快照目标,避免不同身份写入同一设备方案。
59
59
 
60
- 配置的 vPC、Underlay、Overlay、VNI、features、prefix-list 只在完整配置时刷新。三层网段同样只在完整配置时更新和清理。部分配置保存在节点证据中,不能把未读到的 anycast、ACL 或被截断的前缀覆盖到权威清单。L2RIB 两种路由各自判定完整性,部分结果保留旧可选字段并合并下一跳,完整结果才清理该类型缺失行。配置失败不阻止已成功采集的运行路由入库。
60
+ ACL 比较包含方向、有序规则及引用地址组成员;保持相对顺序的重新编号和 remark 不改变转发语义。重复或非法序号不能得到策略身份。`AclPolicy.resolve` 对完整已知规则返回不可变值,对未知规则或依赖返回 nil;明确的空 ACL 与未知策略分别表达。缺失、空组、未知依赖不能证明策略一致。`portgroup`、`object-group` 与 `time-range` 的依赖尚未建模,引用这些依赖的 ACL 即使文本相同也会报告依赖未验证,并阻断自动候选。同名不同内容保留为待决,少数节点有 ACL 也不能推导多数节点应该撤销保护。补建 ACL 还需检查其他接口的既有引用,防止单项操作激活共享定义。
61
61
 
62
- `vxlan_nodes.observations` 的每个维度保留 `latest`;新结果不完整时额外保留 `last_complete`。未请求维度不变。新 VXLAN 观察统一使用 `name/status/records/issues/evidence/started_at/completed_at`;既有历史 JSON 无需回填,后续按维度替换,旧 `last_complete` 保持原形状。展示方须同时显示本次状态和旧数据时间,不能把保留数据显示成实时成功。无线与 VXLAN 共用 `Motor::InventoryObservations` 的时间比较和证据合并规则。
62
+ 网关及关联补齐需要明确 VRF、Anycast 身份与唯一地址,并检查全 Fabric 同 VRF 的跨 VNI 网段重叠,包含不同掩码的包含关系;多台 Anycast 的相同网段证据先合并。纯二层业务仍比较 VLAN 映射,同一设备重复映射也须报告。NVE 复制方式包括继承的全局组播;EVPN 与租户 RT 归一化后比较。角色、证据、承载或路由声明冲突会阻止相关变更生成。
63
63
 
64
- 配置中的凭据及原始 CLI 正文不持久化。命令证据只保存命令名、字节数和摘要,诊断不附原始配置行。`complete: true` 表示调用者已确认完整接收;解析器仍会因未知语法、歧义身份或不完整输出降为 `partial`。单有表头不能证明空清单。
64
+ 建议状态分为 candidate、blocked、investigate。candidate 仍需确认业务意图,不能直接代表批准基线。跨设备建议合并到本机诊断后才生成最终产物,已被可靠增量解决的同一缺项不再重复标为无法推导。
65
65
 
66
- ## 验证
66
+ `ChangePlan.build(change)` 只在输入边界判别一次动作类型,拒绝未知类型、未声明字段和非法参数;构造时复制并冻结参数、命令与回退。各子类维护自身不变量,不在多个调用层重复分支。`ChangePlan.candidate(change, config:)` 供推导使用:前提不足返回 nil,保留待核实诊断。报告边界使用 `to_h` 导出普通数据;不序列化 Ruby 对象标识。
67
67
 
68
- ```sh
69
- RAILS_ENV=test bundle exec rspec spec/vendor/vxlan spec/lib/motor/netstack \
70
- spec/services/motor/devices/script_spec.rb spec/services/motor/netconf/executor_spec.rb
71
- RAILS_ENV=test bundle exec rails zeitwerk:check
72
- bundle exec rubocop
73
- ```
68
+ ## 下发与结果确认
69
+
70
+ 下发只接受带 SHA256 校验文件的聚合计划和明确的 item。用户在真实终端审阅目标、前提、影响、命令与回退,准确输入包含目标、批次摘要和 item 的确认文本后,才连接设备。不存在 `--yes` 或管道确认入口。
71
+
72
+ 交互确认前从文件构造并固定一个计划对象,核对文件中的命令与回退;连接后重读完整目标配置,对比计划指纹并重新检查动作前提。确认、发送和回读使用同一对象,命令不会在确认后因输入修改而改变。执行器复制并冻结前后配置,避免会话读取器复用容器而覆盖执行前事实。一次操作只允许一次会话回调;没有回调、回调重复或没有完成配置回读,都不能报告成功。
74
73
 
75
- 测试覆盖离线解析、实际数据库投影、并发冲突及替身设备会话。另有 2026-10-16 全量 83 台 N9K 的真实只读采集及离线重放证据,保存在本机私有 `storage/network-audits`,不把包含凭据的真实配置提交到仓库。
74
+ 每条命令前持久化意图,返回后记录回执;任一步骤失败或中断立即停止。开始发送后出现不确定结果保持 uncertain,不自动重试、回退或保存 running-config。配置验收和会话收尾完成后才记录 configuration_verified,仍需业务流量验收。
76
75
 
77
- ## 配置覆盖与关联核验
76
+ 回读复验动作的不变量:空 SVI 补网关必须恰为计划中的单个地址,且无同 VRF 网段重叠;VLAN/VNI 关联保持 VNI 唯一;新建 ACL 不得激活所选接口和方向以外的引用。这些谓词由生成前提与回读共用,不能仅凭目标字段出现就报告成功。
78
77
 
79
- NVE 的内联 `member vni ... mcast-group ...` 与嵌套组播声明归一为相同事实;全局 multicast default 仅用于没有显式组播、BGP 复制或 L3 关联的成员。无效组播、冲突成员和未知语法保持 partial。`interface breakout` 单独进入 `breakouts`,不伪装成接口;`no feature` 进入 `disabled_features`。
78
+ `plan.satisfied?(after, before:)` 必须同时提供执行前事实,且起点本身须满足 `plan.eligible?(before)`。除所选动作允许的字段外,已建模配置保持一致,包含既有 ACL、Anycast MAC、MTU、接口和承载。原始配置摘要、审查诊断和由事实推导的网段关系会随合法增量变化,不参与这项上下文比较;ACL 序号与备注仍按转发语义比较。额外漂移使结果保持 uncertain。
80
79
 
81
- 接口事实包含 MTU、OSPF network type、switchport 模式/access VLAN、L3 VNI `ip forward`;NVE 和 BGP 保留 `advertise virtual-rmac`、`advertise-pip`、`advertise l2vpn evpn`、标准/扩展社区和显式关闭状态。BGP 邻居描述、route-map 的方向和 next-hop-self 的 all 语义保留在正确的 VRF/邻居/地址族中。
80
+ 目标设备指纹覆盖解析出的配置事实。跨设备参考来自审查批次,apply 当前只重读目标设备,参考设备的新鲜度、设备版本和业务意图仍须确认人核对;该边界不保证跨设备事务或阻止其他运维人员同时修改设备。
82
81
 
83
- `BgpNeighbors` 为 Overlay 投影和策略引用共用模板归约,显式子邻居配置覆盖继承方向;不同 VRF、邻居和地址族的调用位置保持独立。Prefix-list 支持 IPv4/IPv6、address/next-hop/route-source 选择器及邻居/network/重分发/retain/export 调用关系。IPv4 事实继续位于 `prefix_lists`,IPv6 位于 `ipv6_prefix_lists`,历史观察无需重写。
82
+ ## 产物与性能
84
83
 
85
- `ip unnumbered` 保留借用接口关系;同 VRF 的唯一 Loopback IPv4 地址归约到 `unnumbered_addresses`。Underlay 清单使用该物理接口和借用的 /32 主机地址,不猜测链路子网。缺失、歧义、循环或跨 VRF 引用保持 partial;IPv6 Underlay 未被伪装成已支持的 IPv4 清单。
84
+ 日常入口为 summary.txt → devices/*.txt → scripts/*.cfg;evidence/*.json 供程序重放,plan.json 保存全部诊断、Fabric 对比和有限增量。无候选命令不生成空 cfg,无 Markdown 报告。目录 0700、文件 0600。文件及新建目录的父目录均同步,批次目录同步失败时 apply 不连接设备。先发布 incomplete 检查点,最后提交最终摘要;保存失败不能伪装为采集成功。
86
85
 
87
- NX-OS 的 `Document` 与 Baseline 共用 `CtxParser::Banner` 状态机,banner 正文不会生成配置事实;EOF 未闭合会产生 `incomplete_banner`。
86
+ 业务目录预先按 VNI 索引 VLAN 映射,批次收尾按 host 索引已完成设备,地址组按序号索引查重。一次角色组审查按设备和 ACL 名称解析策略并复用;网关冲突查询按设备建立 SVI 网段索引,覆盖相等、包含和被包含的前缀,保留 VRF、VNI 和排除接口边界。相关范围中的非法地址仍使审查失败,不因索引跳过;下次审查重新建立索引,避免输入变化后复用旧事实。跨设备前提成立后才构造候选计划。补挂已有 ACL 无需为每个 SVI 重扫全设备引用;新增定义仍核对全部既有引用,并在被阻断时展示受影响接口。生成计划时每台设备仅计算一次配置指纹,聚合变更原地合并;采集和审查共用设备文件命名方法。并发仅用于独立设备;解析及规则比较保持纯本地计算。性能样例 `benchmark/tables.rb` 校验结果后报告耗时和分配量,合成基准不代表真实网络时延。
88
87
 
89
- 完整配置的 `review_findings` 输出 VLAN/VNI/NVE/EVPN 关联核查项,不改变语法完整性,也不直接表示运行故障。`review_status` 为 partial 时不根据缺失数据生成关联结论。这样保留“配置收到且语法已理解”和“业务关联需要核实”两个事实。
88
+ ## 验证入口
90
89
 
91
- ## Prefix-list 地址族迁移
90
+ 采集宿主直接复用 `Net::Connector::Parallel::Pool` 和 `Net::Connector::Resources`,不维护独立线程池或资源预算。资源不足在创建批次报告和连接设备前失败;预算按筛选后活跃设备数计算。公共执行器保序交付、停止并回收取消的任务,Collector 保持每台设备顺序读取。纯解析核心不加载传输库;公共配置、进度及执行依赖仅由 CLI 按需加载。
92
91
 
93
- 迁移 `20261016020000` 增加 `address_family`,默认 `ipv4`,由模型和 PostgreSQL 同时约束到 IPv4/IPv6;组合唯一索引允许双栈同名列表。RailsAdmin 列表和详情显示地址族,并提供中英文标签。
92
+ - `bundle exec rake`:解析、生命周期、CLI、审查、建议、交互执行、报告故障与取消测试,代码检查及离线示例。
93
+ - `bundle exec ruby script/verify_contracts.rb`:隔离副本中的定向契约变异,原工作树不被修改。
94
+ - `bundle exec ruby -Ilib benchmark/tables.rb`:多规模本地解析及引用构建。
95
+ - `bundle exec rake build` 与 `bundle exec ruby script/verify_package.rb pkg/vxlan-*.gem`:包内容、独立安装、正式命令与离线报告布局。
94
96
 
95
- 部署时先排空旧 VXLAN 采集 worker,执行迁移并切换到新代码后再恢复采集。旧代码只按名称定位列表,不应与已经写入双栈数据的新 worker 重叠。迁移会保留原行身份和数据;存在 IPv6 历史时 rollback 明确拒绝删除地址族,需先导出并协调处理。当前本机 development/test 已执行迁移。
97
+ 本地 PTY 和合成回执验证连接器及失败边界,不等于真实设备写入测试。实机只读配置重采、历史运行表重放、合成测试分别记录来源与时间,不能相互替代。
@@ -0,0 +1,54 @@
1
+ # 证据契约与验收记录
2
+
3
+ 本轮从代码规范审查收紧到三条纵向链路:解析事实与完整性、失败与报告收尾、声明规则一致性。方案见 [实施计划](superpowers/plans/2026-10-19-evidence-contracts.md),约束见 [设计](superpowers/specs/2026-10-19-evidence-contracts.md)。已有 WIP 保留,未提交或发布。
4
+
5
+ ## 来源与预期
6
+
7
+ 新增样本和字面量预期见 `spec/fixtures/evidence/manifest.json`。每份样本带 SHA-256、命令、平台、转换说明及来源等级;预期不通过生产辅助方法生成。清单另记录 5 份历史 fixture 的哈希,来源统一标为 `historical_origin_unverified`,不能因测试名称包含 live 就当作已核实的实机样本。
8
+
9
+ BGP 样本从本机历史保存回显提取,清单原文 SHA-256 经独立审查在 17 份原始回显中唯一匹配。只去除已验证命令回显/提示符,替换 IPv4/AS 身份并规范化数据行空白,保留计数、时长与表边界;设备型号与版本未随来源记录,保持未知。
10
+
11
+ ## 契约矩阵
12
+
13
+ | 边界 | 不变量 | 原始依据/输入 | 长期验收 |
14
+ | --- | --- | --- | --- |
15
+ | BGP 统计 | 已展示类型之和不得超过总前缀;允许未展示类型 | 保存回显派生 BGP 主表与统计表,人工逐列字面量预期 | evidence_contract_spec.rb;上下界和 Type-12;upper-bound 变异 |
16
+ | 配置身份 | 等价主机/动态前缀共享冲突身份,VRF 分离,事实键保留首次原文 | 合成对抗配置;沿用原 store_unique_fact 与来源失效机制 | evidence_contract_spec.rb;canonical-neighbor-key 变异 |
17
+ | 摘要收尾 | 文本未发布或最终 JSON 未提交时不能声明整批完成 | 真实临时文件、rename/fsync 故障注入 | report_spec.rb、collect_spec.rb;checkpoint/recovery 变异 |
18
+ | 取消与重复收尾 | 首次异常/取消优先;未提交失败保留安全检查点;旧成功摘要不能冒充新状态 | 最终 rename 后 Interrupt、后续 ENOSPC、重复 finish;Queue/Thread.raise 独立演练 | report_spec.rb、collect_spec.rb、parallel_spec.rb |
19
+
20
+ ## 报告发布规则与能力边界
21
+
22
+ 先原子发布 `incomplete`(或 `interrupted`)检查点,再发布人类可读文本,最后发布最终 JSON。文本显示证据状态并指向 JSON;JSON 为批次状态来源。检查点使用安全代码 `report_finalization_unconfirmed`,设备文件及已获取事实保持独立。
23
+
24
+ 最终写入尚未替换时保留原检查点,避免多余恢复 I/O 反而破坏它。已经替换后同步失败或发生取消时,尽力恢复检查点;新一次 finish 若无法建立检查点,旧 complete 摘要尽力失效。恢复与删除均失败时 `Report#recovery_failed?` 为真,CLI 输出明确诊断,仍保留原始异常/退出码(持久化失败 2、取消 130),不重放设备查询。
25
+
26
+ **此协议不承诺存储拒绝所有恢复/删除时的绝对一致性。** 此时盘上旧 complete 仍可能存在,不能忽略本次非零退出码及恢复未确认诊断。删除也未增加目录同步保证,不能据此推断崩溃后的持久状态。两独立 gem 保留同构实现,未为去重引入新的共享依赖。
27
+
28
+ ## 可复现验证
29
+
30
+ ```sh
31
+ # 测试、静态检查、离线范例
32
+ bundle exec rake
33
+ # 临时副本定向植入错误,原工作树不受修改
34
+ bundle exec ruby script/verify_contracts.rb
35
+ ```
36
+
37
+ 变异运行先验证同一临时副本的基线通过,再要求植入错误后出现实际断言失败;语法/加载异常及零测试不算捕获。输出每个变异的检测结果与失败数。每个失败用例还检查异常类型,要求 RSpec 断言失败且没有非断言异常;各工具自带 NoMethodError 负向控制,确认它不会算作成功捕获。这是定向契约验证,不是全仓变异覆盖率。
38
+
39
+ ```sh
40
+ # 只读回放本机已有完整回执,输出哈希和状态,不输出私有正文/设备路径
41
+ bundle exec ruby script/replay_evidence.rb /path/to/saved-captures bgp_neighbors
42
+ # 对比另一源码快照;输出含实际 library_root,脚本校验加载来源
43
+ EVIDENCE_LIBRARY=/path/to/baseline/lib bundle exec ruby script/replay_evidence.rb /path/to/saved-captures bgp_neighbors
44
+ ```
45
+
46
+ 本轮回放 17 份历史保存回显(17 complete)。原文包含命令回显和提示符,只有首行精确匹配已声明命令、末行符合单行提示符边界时才提取正文;原文/正文哈希分别记录。重构前后所有记录摘要、状态和诊断 **0 差异**。原始输入集合哈希:`0908195283f4ded37fef529396b007d74dc30590c78081de22c560daa290f07f`。私有原文及逐份结果仅保留本机临时目录,未进入仓库或安装包。
47
+
48
+ ## 独立性与未验证范围
49
+
50
+ 独立审查比较本轮起始源码快照与候选实现、重新验证样本预期,并额外复现真实线程二次取消及极端存储故障。新增别名仅为测试演练,不增加业务平台。没有新增设备采集;历史回放和官方样例不等于当前设备固件、SSH、AP 登录或生产部署验收。
51
+
52
+ ## 本轮结果
53
+
54
+ Ruby 4.0.7:`bundle exec rake` 为 286 examples、0 failures,RuboCop 75 文件通过;4 个正式变异全部被断言捕获,1 个非断言异常负向控制正确排除。严格回放与起始快照 0 差异;独立审查的生产实现与验收工具问题均已复现并关闭。安装包已通过隔离安装、脱离源码加载、CLI/离线入口及打包文件清单验证。
@@ -0,0 +1,84 @@
1
+ # VXLAN 修复建议
2
+
3
+ 采集 `collect` 默认保存逐设备诊断与只读核查命令。只有指定 `--scripts` 才导出候选配置、回退草稿和受支持的类型化执行计划;诊断/导出均不连接额外设备、不修改已有报告:
4
+
5
+ ```sh
6
+ bundle exec ruby bin/vxlan review --batch /absolute/path/to/batch --scripts
7
+ # 可指定独立的私有输出根目录
8
+ bundle exec ruby bin/vxlan review --batch /absolute/path/to/batch --output /private/reviews
9
+ ```
10
+
11
+ 默认输出到 `<batch>/reviews/<UTC时间>/`。退出码 0 表示建议文件生成成功,不表示网络健康或故障已修复;2 表示参数、输入结构或发布错误。
12
+
13
+ 输出采用与 net-connector topology 一致的批次分工(`summary.json` 的 `layout_version: 3`),不生成 Markdown 报告:
14
+
15
+ ```text
16
+ <批次>/
17
+ summary.txt 总览、设备入口、Fabric 差异
18
+ summary.json 完成状态、计数、来源与产物索引
19
+ plan.json 所有设备诊断、Fabric 证据、按 ID 索引的单项增量
20
+ plan.json.sha256 聚合计划校验
21
+ events.jsonl 本次审查事件,明确 executed: false
22
+ devices/<设备>-<IP>.txt 每台一份诊断、前提、影响、回退和验收步骤
23
+ evidence/<设备>-<IP>.json 采集证据,仅供程序回放和审计
24
+ scripts/<设备>-<IP>.cfg 仅 --scripts 且有候选命令时生成
25
+ ```
26
+
27
+ 先读总览,再定位设备,最后审阅配置建议并选择计划项。没有建议的设备也保留一份简短诊断,避免“未命中”与“未审查”混淆;不会生成空配置文件。离线审查没有设备会话,因此不伪造 `logs/`。在线采集的原始结构化快照继续保存在 `evidence/*.json`,审查通过来源哈希引用它们。
28
+
29
+ `devices/` 只放用户阅读的 TXT;机器证据集中到 `evidence/`。开发阶段统一使用新结构,离线 `review` 只读取 `evidence/*.json`,不支持旧目录回退。
30
+
31
+ 编排顺序:输入校验 → 单设备诊断和 Fabric 比较 → 合并建议 → 设备文本与候选脚本 → 聚合计划/哈希/事件 → 最后确认摘要完成。在线收尾将审查摘要嵌入采集摘要的 `review` 字段,保留采集完整性状态。计划中的 `audits` 保存完整建议,`fabric` 保存共同业务差异及覆盖,`changes` 只包含受支持的单项增量。
32
+
33
+ 候选 cfg 保留设备命令;条件回退以注释保存。cfg 用于审阅,不是 apply 的输入。自动化读取 summary.json 和 plan.json,不再依赖旧版 recommendations/data/plans 目录。下发只接受带校验文件的聚合计划及明确的计划 ID,不接受独立单项文件。
34
+
35
+ `candidate` 是有本机证据支持、仍需确认业务意图的候选;`blocked` 缺少关键参数或有冲突;`investigate` 是定位、补采或核对设计的任务。空响应和部分配置不会推导“配置不存在”。所有目录 0700,文件 0600,可能包含内部设备及终端信息。
36
+
37
+ 应用候选前重新采集并核对证据、版本、拓扑和审批窗口;原报告 SHA256 只用于定位本次证据,不能证明设备当前状态。分项验证效果;若命令超时或效果不明,先回读,不能自动重放。回退只在确认本次增量已生效且无并行修改时使用,业务通断须另行验收。只有独立 `apply` 命令可以下发受支持的类型化计划,且必须通过下述交互确认;不会自动保存 running-config。
38
+
39
+ 支持配置规则:VLAN/NVE/EVPN/VRF 关联缺失及层次冲突。只有完整配置、唯一 VLAN、明确 L2 角色、本机一致的 BGP 复制和 auto RD/RT 策略满足时,生成条件性的增量候选;缺 VLAN、混合 RT、未知 VRF 等保留待补参数。存在 VLAN 映射但缺少 NVE/EVPN 时一起补齐候选,回退只删除新增子节点。
40
+
41
+ 运行规则覆盖 NVE VNI、NVE peer、BGP 未建立状态。当前不提供完整 underlay/vPC 健康审计,也不根据主机名或默认 fabric_key 推断跨设备一致性。
42
+
43
+ 命令语法参考:[Cisco NX-OS VXLAN BGP EVPN](https://www.cisco.com/c/en/us/td/docs/dcn/nx-os/nexus9000/103x/configuration/vxlan/cisco-nexus-9000-series-nx-os-vxlan-configuration-guide-release-103x/m_configuring_vxlan_bgp_evpn.html)。现场软件版本及业务设计仍须核对。
44
+
45
+ ## 交互式下发
46
+
47
+ ```sh
48
+ bundle exec ruby bin/vxlan apply --plan /path/to/batch/plan.json --item <设备报告中的计划ID> --env-file /path/to/.env
49
+ ```
50
+
51
+ 必须使用真实终端;不存在 `--yes`,管道输入不能确认。完整展示设备、前提、影响、配置与回退后,需准确输入 `APPLY <IP> <计划SHA256前12位> <计划ID>` 才连接设备。SSH 严格校验已知主机密钥,凭据沿用 NC_DEVICE_* / 平台 NC_*;使用统一目录顺序加载 `.env`,`--env-file` 覆盖所发现的文件,进程环境变量始终优先。
52
+
53
+ 确认后先重读完整配置并核对已解析配置事实的指纹和动作前提;已解析事实变化、部分证据或未经支持的动作均拒绝写入。指纹不覆盖解析器尚未建模的配置行,不能替代全量配置审查。文件中的命令会由类型化动作重新渲染核对,不能编辑为任意脚本。每条命令前持久化意图,执行后保存回执状态。失败或中断立即停止并标记 uncertain,不自动重试、重连或回退;先人工回读确定实际效果。
54
+
55
+ 成功只表示目标配置回读符合计划,仍需业务流量验收。执行日志位于 `vxlan-executions/<UTC>/execution.json`,包含计划摘要和步骤状态、不含密码或原始回显。回退草稿只供审阅,不提供自动执行入口;计划也不执行保存配置。
56
+
57
+ 回读还会比较执行前后的已建模业务上下文:只有所选动作涉及的字段允许变化。若补齐 VLAN/VNI 的同时既有 ACL、Anycast MAC 或其他配置变化,即使命令回执成功、目标关联出现,也保留 uncertain。新建目录的父目录同步失败时,在连接设备前停止。
58
+
59
+ 聚合计划必须用 `--item` 明确选择一项;无选择或未知 ID 都不会连接设备,确认文本同时绑定整个文件哈希、目标和所选项。先核对同目录 `plan.json.sha256`,文件改变会拒绝执行。每次仅执行单设备单项增量。应用一项后同设备其他旧计划会因配置指纹变化而过期,应重新采集/审查生成新计划,不能连续盲目运行旧计划。跨 Leaf 的参考事实来自报告批次;本入口只重新验证目标设备,参考设备、版本支持和业务意图仍由确认人核对。
60
+
61
+ ## Fabric 业务一致性
62
+
63
+ ```yaml
64
+ fabrics:
65
+ example:
66
+ leaves: [192.0.2.11, 192.0.2.12]
67
+ borders: [192.0.2.21, 192.0.2.22]
68
+ spines: [192.0.2.31, 192.0.2.32]
69
+ ```
70
+
71
+ ```sh
72
+ bundle exec ruby bin/vxlan review --batch /path/to/batch --fabric-policy /path/to/fabrics.yml --scripts
73
+ bundle exec ruby bin/vxlan collect --config /path/to/vxlan.yml --fabric-policy /path/to/fabrics.yml --scripts
74
+ ```
75
+
76
+ 配置 YAML 可声明 `fabric_policy: fabrics.yml`,路径相对配置文件。策略明确列出 Leaf、Border、Spine,未使用的角色可以省略;地址不能重复或跨 Fabric/角色。任何成员配置不完整均阻止该 Fabric 的跨设备计划,未归属设备和缺少证据的成员在总览中显式列出。框架不把主机名或默认 fabric_key 当成权威边界。
77
+
78
+ Leaf 和 Border 分别比较已部署相同 VNI 的 VLAN/SVI、IPv4 网关、VRF、Anycast 模式/MAC、MTU、启停和 ACL 方向、定义、有序规则;Spine 出现 L2 业务承载时提示角色冲突,停止其候选生成。业务目录联合 VLAN、NVE、EVPN 识别已开始部署的业务,区分完整、不完整与未部署,不要求所有 VLAN 铺满所有 Leaf。复制方式(包括继承的全局组播)、EVPN RT 和租户路由声明也参与一致性检查;这些约束冲突时不再叠加网关或 ACL 变更。`summary.txt` 汇总业务问题,`plan.json` 保留完整对比事实,逐设备方案位于 devices/。ACL 序号重排、备注不当作转发语义差异;规则顺序保留,协议/端口别名未做等价求解。
79
+
80
+ 当前可交互执行的 Fabric 增量:补挂内容一致的 IPv4 SVI ACL、补建缺失 ACL 后挂载、补齐无网段冲突的单个网关地址,以及为已有 VLAN 补齐缺失的 VNI 关联。关联补齐要求同业务其他成员全部完整且一致、本机只有一个符合网关/VRF/Anycast/ACL 的未映射 VLAN、已有 NVE/EVPN 匹配,并通过整个 Fabric 的跨 VNI 网段重叠检查;不会根据 VNI 数字猜测 VLAN,也不创建 VLAN。不覆盖已有 ACL、修改 VRF 或迁移网关。少数节点已有 ACL 并不证明其业务意图正确:候选明确要求确认统一策略;同名 ACL 内容冲突时全部保留待决,不散播任一版本。
81
+
82
+ 现场策略 `bin/fabric-policy.yml` 覆盖 CKG3、SHA2、SZX8、SZX9 的 83 台设备:67 台 Leaf、8 台 Border、8 台 Spine;部署范围按用户确认保留。业务边界、部署目录、关联推导和有限变更分别由 `Fabric::Scope`、`Service::Catalog`、`Service::Mapping`、`ChangePlan` 承担,`Fabric::Review` 编排规则,报告层只呈现结果。EVPN/NVE 候选仍只导出审阅草稿,不自动转换成可执行计划。
83
+
84
+ 命令依据:[Cisco NX-OS IPv4 ACL](https://www.cisco.com/c/en/us/td/docs/dcn/nx-os/nexus9000/103x/configuration/security/cisco-nexus-9000-nx-os-security-configuration-guide-103x/m-configuring-ip-acls.html)。现场版本、TCAM/资源支持与业务允许/拒绝流量须在维护窗口验证。
@@ -0,0 +1,31 @@
1
+ # VXLAN 代码审查与优化(2026-10-19)
2
+
3
+ 范围包括公开解析入口、Profile 命令声明、NX-OS 配置与运行解析、不可变观测、采集生命周期、CLI 配置/并发/报告、注释和 gem 打包。以下结论来自当前源码、可复现的离线输入和回归测试。
4
+
5
+ ## 已修复问题
6
+
7
+ | 问题 | 原行为 | 当前行为 | 回归位置 |
8
+ | --- | --- | --- | --- |
9
+ | 公开配置输出缺少设备预检 | `devices.password` 可随 `--show-config` 输出 | 初始化、展示及采集共用 Options 的设备校验,拒绝未知字段及重复地址 | `spec/cli/collect_spec.rb` |
10
+ | CLI 实例复用残留状态 | 第二批混入第一批结果;后续参数失败可能重写旧摘要 | 每次 run 在解析参数前重新建立批次状态 | `spec/cli/collect_spec.rb` |
11
+ | 非法 false 筛选值被吞掉 | `names: false` 被当作空列表,可能扩大选中范围 | 用 fetch 区分缺失与非法值,类型错误提前拒绝 | `spec/cli/collect_spec.rb` |
12
+ | BGP 等价 IPv6 身份未归一化 | 同一个 peer 的两种写法绕过重复检测,统计表也可能无法关联 | 主表与统计表复用 Values 地址归一化,歧义身份整体隔离 | `spec/cisco_nxos/show_bgp_l2vpn_evpn_summary_spec.rb` |
13
+ | BGP 叶子作用域不完整 | 进程或 VRF 下的 send-community 等被当作完整事实 | 合并重复协议守卫,要求对应叶子位于 BGP 地址族作用域 | `spec/cisco_nxos/routing_context_spec.rb` |
14
+ | 邻居身份未校验 | 非法名字/IP/前缀可成为配置邻居 | 复用 ip_address/network_prefix,仅排除坏邻居并保留合法兄弟 | `spec/cisco_nxos/routing_context_spec.rb` |
15
+
16
+ ## Ruby 与工程取舍
17
+
18
+ - 继续使用 Data 与 Immutable 表达不可变证据;解析过程中的可变状态保留在 ConfigurationState,避免给临时构建对象强加值对象语义。
19
+ - 设备字段和身份预检集中在 Options,Collect 负责流程编排;SSH 默认值统一声明,减少初始化与运行路径的规则漂移。
20
+ - 报告汇总用 Hash 索引已完成地址,pending 计算由逐项线性扫描改为 O(完成数 + 请求数),保持原顺序和输出结构。
21
+ - 保留公开入口、记录字段与配置邻居键的原始拼写。已有 IPv4/IPv6 主机及动态前缀支持继续保留;未建模接口邻居语法保持部分证据。
22
+ - 保留独立 gem 的边界;跨厂商值转换继续复用 ctx_parser,传输回执复用 ctx_driver。线程取消回收、原子报告和目录同步保留现有所有权语义。
23
+ - 方法注释说明用途与证据边界,补充报告错误的发布阶段/提交状态说明。
24
+
25
+ ## 验证
26
+
27
+ Ruby 4.0.7 执行 `bundle exec rake`:268 examples,0 failures;RuboCop 71 文件通过,离线范例和帮助入口通过。新增缺陷回归均先复现失败再通过修复。
28
+
29
+ 验证限于离线解析、合成会话及本地工程检查;不代表真实设备固件、SSH 或运行网络验收。没有提交、发布或设备配置变更。
30
+
31
+ 构建产物已通过 `script/verify_package.rb` 的隔离安装验证,包括脱离源码加载、CLI 帮助、初始化及离线入口;配置和凭据未进入安装包。
@@ -0,0 +1,69 @@
1
+ # VXLAN CLI Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement task-by-task.
4
+
5
+ **Goal:** 将现有脚本实现迁入 lib,提供可安装 bin/vxlan,并清理旧文件。
6
+ **Architecture:** Vxlan::CLI 延迟分发 collect/parse;五个实现直接迁移,无代理兼容层。examples 为薄入口。
7
+ **Tech Stack:** Ruby >=4.0.6、RSpec、OptionParser、现有 Collector/net-connector。
8
+ **Spec:** docs/superpowers/specs/2026-10-19-command-line-design.md
9
+
10
+ ## Global Constraints
11
+ - 保留当前全部 WIP,不提交、不发布、不连接设备。
12
+ - 依赖选择未收到回复,本次维持 net-connector/dotenv 可选安装约定;CLI 不强制加载连接器。
13
+ - 本会话直接执行;使用完整 WIP 隔离副本,结束前检查源文件哈希后回传。
14
+ - 退出码 0/1/2/130、报告及线程回收语义保持。
15
+
16
+ ## Review Focus
17
+ - 外部 cwd:安装入口默认文件在用户目录。
18
+ - 自定义 YAML:相对路径按 YAML 所在目录。
19
+ - 源码脚本:保留项目根路径约定。
20
+ - 只加载 CLI/解析:不加载连接器、不读取凭据。
21
+ - 安装包:模板完整、真实可执行入口可用、初始化不覆盖。
22
+
23
+ ### Task 1: 正式入口与迁移
24
+ Files: lib/vxlan/cli.rb、lib/vxlan/cli/*.rb、examples/*.rb、spec/cli/*。
25
+ Interface: Vxlan::CLI.run(argv, env:, out:, error:, input:, **collect_options) -> Integer。
26
+ - [x] 新增 spec/cli_spec.rb,验证帮助/版本/未知命令/离线解析/无提前加载;运行观察失败。
27
+ - [x] 迁移五个实现,Collection 改 Collect,迁移测试至 spec/cli,删除旧路径。
28
+ - [x] 实现 CLI.run 与 bin/vxlan;薄示例调用同一入口,保留 require 无执行。
29
+ - [x] 新旧用例通过;不提交。
30
+
31
+ ### Task 2: 路径、模板与打包
32
+ Files: cli/options.rb、cli/templates/*、vxlan.gemspec、script/verify_package.rb、spec/cli_spec.rb。
33
+ Interface: Options/Collect 接受 config:, env_file:, directory:, base:, command: 可选关键字;base 默认 nil 表示 YAML 目录。
34
+ - [x] 新增外部 cwd 初始化、YAML 相对路径与源码路径测试;观察失败。
35
+ - [x] 模板单一来源;安装默认 cwd,源码显式旧默认,帮助显示实际入口。
36
+ - [x] gemspec 登记 bin/vxlan、模板及直接使用的标准库;保留可选网络依赖。
37
+ - [x] 构建、隔离安装,在 GEM_HOME/bin/vxlan 验证帮助/版本/parse/初始化/静态清单。
38
+
39
+ ### Task 3: 文档与完整验证
40
+ Files: README*.md、examples/README.md、CHANGELOG.md、设计状态。
41
+ - [x] 文档改为正式 CLI 与薄示例职责、清楚说明两种路径默认及可选依赖。
42
+ - [x] 完整 rake、gem build、隔离安装、独立审查;修复重要问题后重复相关检查。
43
+ - [x] 哈希保护回传所有新增/修改/删除文件;源目录再次 rake、残留引用检查。
44
+
45
+ ## Ledger
46
+ Ruling: 用户继续完善视为执行授权,沿用本会话直接实施方式,不重复询问方案审批。
47
+ Ruling: 保留可选依赖,不以未回复问题阻塞可独立完成的目录和入口重组。
48
+ Pre-flight: Task 2 consumes Task 1 Collect keyword interface; 同步迁移调用与测试,默认 base:nil。
49
+
50
+ Task 1: complete — baseline 248/0;入口 RED 3/3 failed,迁移后全部通过。原支持类测试迁入 spec/cli,parallel/report 主体仅命名空间调整。
51
+ Task 2: complete — 路径 RED 5 failed;正式入口、模板、标准库依赖与 package 检查已实现。macOS /var→/private/var 的 cwd 实路径在测试中按 File.realpath 比较。
52
+ Task 3: complete — 255/0、70 lint clean;构建及隔离 GEM_HOME 安装成功,正式入口及源码示例通过;原始 RubyGems connector 0.14.1 下 49/0。
53
+ Review: fresh-context reviewer independently ran 49/0,没有实现重要问题;发现源码 bundle exec vxlan 文档无法找到命令,已实际验证并改用 bundle exec bin/vxlan。
54
+ Ruling: 使用完整 WIP 隔离 clone 而非干净 HEAD worktree,确保未提交入口与测试一并保留;无提交/重置/暂存。
55
+
56
+ Ruling: .gitignore 同时覆盖正式入口在仓库启动时生成的 /vxlan.yml 与 /vxlans/,避免新默认路径留下未忽略的现场产物。
57
+
58
+ Final: 38 个新增/修改/删除文件已按基线哈希校验回传;未涉及的原 WIP 哈希完全保留。源仓库 rake 255/0、70 files lint clean;git diff --check 通过。只读安装目录下的正式命令验证成功;未提交、未发布、未连接真实设备。
59
+
60
+ ## Follow-up: bin 与参考 examples 的操作体验
61
+
62
+ 用户明确选择统一 vxlan collect/parse、启动目录默认配置/.env/报告,已有 bin/.env 与 bin/vxlan.yml 保留。
63
+ - 完成 -h/--help-all/--examples、--plan/--inventory-only、--no-progress/--quiet、强制交互终端检查与初始化退出提示;启动进度显示实际配置路径。
64
+ - 对齐空白 VXLAN_CONFIG 的默认回退(进程与 .env 均覆盖);回归先失败再修复。
65
+ - 正式使用说明集中 bin/README.md,examples 只说明薄示例;模板仍单一来源,包文件白名单只允许 bin/vxlan 与 bin/README.md。
66
+ - bin 现场配置和报告忽略;既有现场文件内容哈希保持一致。
67
+ - 验证:259 examples/0 failures,70 files lint clean,构建与只读安装目录下正式命令 smoke 通过。RubyGems 安装后的 gemspec 不保留完整 files,因此包清单由 Gem::Package.spec 检查,安装后使用实际文件存在检查。
68
+
69
+ Independent follow-up review: CLI/文档未发现阻断问题;发现并修复 package verifier 环境隔离与 installed spec.files 断言问题。对照测试:旧脚本在受控 VXLAN_CONFIG 外部临时路径写入且 exit1;修复后清理 VXLAN_*、NC_PARALLEL,带污染环境完整隔离安装 exit0,外部临时配置/报告均未创建。最终 rake 259/0、70 lint clean、diff check clean,现场文件哈希不变。
@@ -0,0 +1,83 @@
1
+ # VXLAN Connector Integration Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans task by task. Track completed checks here; do not commit existing WIP.
4
+
5
+ **Goal:** Harden the existing VXLAN host integration without new wrappers or business layers in net-connector.
6
+
7
+ **Architecture:** NativeConnector owns the original NX-OS connection and operation lease. Collector/ctx_driver retain parsing and evidence responsibilities. Existing host parallel and report helpers handle cancellation and persistence explicitly.
8
+
9
+ **Tech Stack:** Ruby >=4.0.6, RSpec, local PTY, stdlib filesystem/threads; optional net-connector ~>0.14.1.
10
+
11
+ **Spec:** ../specs/2026-10-19-connector-integration-design.md
12
+
13
+ ## Global Constraints
14
+
15
+ - net-connector keeps Ruby >=3.2 and no vxlan/ctx_driver runtime dependency; vxlan keeps Ruby >=4.0.6.
16
+ - No new public wrapper, CLI, dependency, result model, parser, or automatic command replay.
17
+ - Preserve existing API/CLI/path semantics, WIP, and published connector compatibility.
18
+ - Work in an isolated copy of the complete current WIP, then transfer only owned changes after checking source fingerprints. No commits/push/publish or real devices.
19
+ - User's “继续” authorizes execution of the reviewed design; implement inline with one independent final review.
20
+
21
+ ## Review Focus
22
+
23
+ - Lease finalization failure must retain completed observations (Task 1).
24
+ - Thread.exit/kill without an exception must not produce successful nil slots (Task 2).
25
+ - Cleanup failures must not replace the first cancellation/error (Task 2).
26
+ - JSON committed but TXT/fsync failed must remain distinguishable from unsaved output (Task 3).
27
+ - Cancellation plus failed summary must preserve exit130 and safe diagnostics (Task 3).
28
+
29
+ ### Task 1: Original-session operation lease
30
+
31
+ **Files:** examples/support/collection.rb; spec/example_native_connector_spec.rb; spec/collector_spec.rb.
32
+ **Interfaces:** consume Net::Connector.open/with_operation and Collector#collect; produce unchanged Snapshot.
33
+
34
+ - [x] Extend native PTY tests to assert the yielded session is native and the entire callback owns an operation lease; reproduce missing lease.
35
+ - [x] Run `bundle exec rspec spec/example_native_connector_spec.rb spec/collector_spec.rb`; expect targeted new assertion FAIL.
36
+ - [x] Yield native within with_operation(:vxlan), removing redundant Session wrapper. Add evidence tests for connection failure, disconnect suppression, close/lease finalization failure and borrowed-session ownership; modify Collector only if reproduced.
37
+ - [x] Run the same command; expect all PASS.
38
+
39
+ ### Task 2: Worker completion and cancellation
40
+
41
+ **Files:** examples/support/parallel.rb; spec/example_parallel_spec.rb.
42
+ **Interfaces:** map(items, parallel:) continues returning ordered block values or propagating the first failure after joining owned workers.
43
+
44
+ - [x] Add Queue-synchronized tests for worker Thread.exit/kill, interrupt with blocked sibling, and cleanup exception preserving original error; assert every worker stopped.
45
+ - [x] Run `bundle exec rspec spec/example_parallel_spec.rb`; expect early-exit/cleanup failures.
46
+ - [x] Track exhausted workers; register notifications outside interruptible setup; retain primary failure during cleanup. Keep bounded pool and resource preflight local and small.
47
+ - [x] Run the same command; expect all PASS, including partial-creation gate regression.
48
+
49
+ ### Task 3: Report receipts, completed evidence and cancellation
50
+
51
+ **Files:** examples/support/collection.rb; examples/support/report.rb; spec/example_collection_spec.rb; new spec/example_report_spec.rb.
52
+ **Interfaces:** Report#write/#finish retain existing signatures; host-internal Report::Error safely identifies relative path, publication phase and committed state; no raw exception message.
53
+
54
+ - [x] Test Thread-safe result registration before write, JSON-success/TXT-failure, Interrupt with failed finish, ENOSPC, directory-fsync after rename, root symlinks/wide permissions and sensitive error text. Expect no device replay and pending excludes acquired targets.
55
+ - [x] Run `bundle exec rspec spec/example_collection_spec.rb spec/example_report_spec.rb`; expect missing error receipts/unsafe-root acceptance/cancellation propagation failures.
56
+ - [x] Implement scoped publication diagnostics, private-root preflight and directory sync; record collected result before persistence, report saved state separately, and handle report failure while building terminal summary. Keep cancellation precedence130 and ordinary persistence error2; only safe diagnostic text.
57
+ - [x] Run the same command; expect all PASS. Run full `bundle exec rake`; expect specs/lint/offline examples PASS.
58
+
59
+ ### Task 4: Documentation, installed-package and independent review
60
+
61
+ **Files:** examples/README.md; README.md; README-zh.md; CHANGELOG.md; script/verify_package.rb only if required.
62
+ **Interfaces:** existing source scripts and gem allowlist remain unchanged.
63
+
64
+ - [x] Document operation ownership, safe borrowed-result retention, private roots, persisted-versus-acquired status, cancellation and unchanged module boundaries.
65
+ - [x] Run `bundle exec rake`, `bundle exec rake build`, and `ruby script/verify_package.rb pkg/vxlan-0.2.3.gem`; expect PASS and loaded source/package paths recorded.
66
+ - [x] Test native integration with original published net-connector0.14.1 separately from current connector checkout; record exact loaded paths/version. If connector source changes, run its affected tests plus Ruby3.2/full CI.
67
+ - [x] Independent final review against this plan/spec; reproduce and fix important findings with tests. Compare original file fingerprints and transfer only these task-owned files. No local commit.
68
+
69
+ ## Execution ledger
70
+
71
+ Ruling: isolated full-WIP copy rather than clean HEAD worktree — examples under review are untracked WIP and must participate in implementation and baseline. No source credentials or captures are copied. Inline execution follows user's continuation instruction without another approval round.
72
+
73
+ Pre-flight: Tasks 1 and 3 share collection.rb; Task 3 preserves Task 1's open lease. Task 2 propagates unhandled report errors to Task 3; Task 3 must finalize only after the pool joins all workers.
74
+
75
+ Task 1: complete — task1-red reproduced missing operation lease/native boundary; native+collector14 cases passed, expanded finalization cases also pass. Collector product code unchanged.
76
+ Task 2: complete — task2-red reproduced silent Thread.exit success and killed-worker hang; task2-green5 cases passed.
77
+ Task 3: complete — task3-red reproduced seven report/cancellation failures; full-green242 cases, lint68 files and offline examples passed. Pending-target success additionally reproduced and fixed.
78
+ Ruling: report failure can now publish a truthful incomplete summary — update the old test that forbade any summary path; preserve acquired-versus-saved facts instead.
79
+ Ruling: existing worker helper remains local for published connector compatibility; do not import newer net-connector internals.
80
+ Task 4: in progress — build passed; package verification, independent review and connector source/published matrix pending.
81
+
82
+ Task 4: complete — full rake242 examples/0 failures,68 lint files clean, offline examples pass; build and isolated package verification exit0. Published0.14.1 and current connector checkout each44 integration examples/0 failures with loaded paths recorded. Independent reviewer44 examples/0 failures and no important findings. No connector product changes, real device IO, commits or publishing.
83
+ Final transfer: original full-WIP fingerprints checked before transfer; copy only the12 changed implementation/test/doc files and this plan/design. Re-run canonical rake in original checkout to verify transferred result. Logs/candidate remain in the isolated temporary directory for review.
@@ -0,0 +1,64 @@
1
+ # vxlan Evidence Contracts Implementation Plan
2
+
3
+ > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [x]`) syntax for tracking.
4
+
5
+ **Goal:** 沿已有解析和采集链路建立可追溯验收,修复已复现的证据缺口并集中规则。
6
+ **Architecture:** 保留 Profile/Registry 与现有 Collector/CLI 职责;仅对证据、身份和发布边界做局部重构。测试样本与预期独立于生产实现。
7
+ **Tech Stack:** Ruby、RSpec、RuboCop、JSON/YAML、隔离 gem 安装。
8
+ **Spec:** ../specs/2026-10-19-evidence-contracts.md
9
+
10
+ ## Global Constraints
11
+
12
+ - Ruby >= 4.0.6;本机验证使用 Homebrew Ruby 4.0.7。
13
+ - 保留现有 WIP、公开入口和独立 gem 边界;不提交、不发布、不连接设备。
14
+ - 私有原文仅在本机临时目录回放;仓库只保存脱敏/官方派生样本与来源说明。
15
+ - 用户已要求方案并执行,连续实施,不另设审批阶段。
16
+
17
+ ## Review Focus
18
+
19
+ - 来源未知样本不能当作实机完整性证明。
20
+ - 同一身份的不同文本表达必须遵循明确冲突策略。
21
+ - 声明了端口/统计表却没有其必需内容时,不能 complete。
22
+ - summary.txt 或 summary.json 失败时,CLI 退出码、stdout 与存盘结果不能声明假成功。
23
+ - 声明扩展演练只使用测试替身,不新增业务平台或命令。
24
+
25
+ ## Task 1: 解析契约与独立样本
26
+
27
+ **Files:** spec/fixtures/evidence/*、spec/evidence_contract_spec.rb;对应现有命令解析器/作用域文件;docs/evidence-contracts.md。
28
+ **Interfaces:** 继续使用现有 parse(..., complete:) 和 status/records/issues;输入样本及预期通过 manifest.json 绑定。
29
+ - BGP 原始主表/统计表及其 VRF 作用域,重点验证缺失/重复统计及等价 IPv6。
30
+ - 配置邻居原始名称与标准地址身份的关系,检查等价写法是否仍绕过配置冲突隔离。
31
+
32
+ - [x] 盘点历史 fixture 来源;建立 SHA-256、官方来源/派生转换及字面量预期清单。
33
+ - [x] 添加缺失证据、等价身份、作用域隔离回归,观察真实失败并记录。
34
+ - [x] 局部修复根因,复用已有地址/记录/命令机制;运行相关 RSpec 验证。
35
+ - [x] 对选定命令的历史保存回显及旧 fixtures 做修改前后差分,所有差异逐项解释。
36
+
37
+ ## Task 2: 批次报告失败契约
38
+
39
+ **Files:** lib/vxlan/cli/report.rb、lib/vxlan/cli/collect.rb、spec/cli/report_spec.rb、spec/cli/collect_spec.rb。
40
+ **Interfaces:** 保留 finish 返回 summary、现有 Error 安全诊断、退出码 2/130;新增发布状态字段若必要必须文档化。
41
+ - [x] 注入 summary.txt/summary.json 的 rename、fsync 故障,检查盘上 JSON、stdout、退出码及已保存设备事实。
42
+ - [x] 先观察失败,再调整发布顺序及安全恢复;不重放设备查询,不让恢复覆盖原始取消。
43
+ - [x] 运行真实线程池既有取消回归,补充必要的无 sleep 同步用例。
44
+
45
+ ## Task 3: 规则唯一性与验收
46
+
47
+ **Files:** 现有 parser_registry/CLI options 声明消费点;spec/evidence_contract_spec.rb;docs/evidence-contracts.md;CHANGELOG.md。
48
+ **Interfaces:** 规则变更通过既有声明和公共入口传播;不引入新共享 gem 或通用测试框架。
49
+ - [x] 用测试声明替身演练平台/维度/别名变化,发现并消除实际重复规则。
50
+ - [x] 在临时源码副本中种入关键错误(绕过完整性/身份/发布校验),定向测试必须检测到;记录补丁和结果。
51
+ - [x] bundle exec rake、build、script/verify_package.rb、git diff --check;记录运行版本及加载来源。
52
+ - [x] 新上下文独立审查后修复重要问题;填入证据矩阵及未验证边界。
53
+
54
+ ## Execution ledger
55
+
56
+ 开始前基线源码已复制到本机临时目录,供差分与变异比较;本文件随执行更新,不依赖提交范围追踪 WIP。
57
+
58
+ ### 进展与裁定
59
+
60
+ - Task 1: complete。新增独立预期样本回放成功;缺陷先红后绿;历史原文正确去除回执框架后差分 0。
61
+ - Task 2: complete。报告文本/最终 JSON/目录同步/持续 ENOSPC/取消/重复 finish 回归通过;独立审查补出的三类缺口均修复。
62
+ - Ruling: 最终写入未提交时不重复恢复安全检查点;已提交失败和取消才恢复。极端存储拒绝下仅 best effort,保留明确恢复未确认诊断,不能承诺绝对离线一致性。
63
+ - Ruling: 不新建通用共享层;别名通过现有 Registry 匹配,配置身份通过局部 canonical 索引复用原有冲突规则。
64
+ - Task 3: 全量验收 286 examples / 0 failures,RuboCop 75 文件通过;4 个正式变异被实际断言捕获,负向控制排除非断言异常。严格回放 0 差异。独立审查通过,安装包隔离安装、脱离源码加载、CLI/离线入口和文件清单核验通过;Task 3: complete。