kld-sdd 2.6.16 → 2.6.21
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.
- package/bin/kld-sdd-init.js +10 -0
- package/kld-sdd-guide.html +22 -0
- package/lib/device-auth-cli.js +130 -0
- package/lib/device-auth.js +345 -0
- package/lib/init-account-binding.js +108 -0
- package/lib/init.js +238 -55
- package/lib/skills-bundle.js +20 -1
- package/lib/tool-profiles.js +8 -0
- package/package.json +7 -3
- package/skywalk-sdd/apply-worktree-finish.cjs +2 -23
- package/skywalk-sdd/context-client.cjs +38 -87
- package/skywalk-sdd/index.cjs +860 -132
- package/skywalk-sdd/kb-sync-identity.cjs +780 -0
- package/skywalk-sdd/kb-upload.cjs +505 -0
- package/skywalk-sdd/lib/shared.cjs +811 -0
- package/skywalk-sdd/lib/usage-contract.cjs +276 -0
- package/skywalk-sdd/lib/usage-reporter.cjs +354 -0
- package/skywalk-sdd/lib/user-config.cjs +157 -0
- package/skywalk-sdd/metrics-v3.cjs +138 -8
- package/skywalk-sdd/ontology/archive-package.cjs +19 -34
- package/skywalk-sdd/ontology/change-lock.cjs +3 -7
- package/skywalk-sdd/ontology/external-key.cjs +18 -4
- package/skywalk-sdd/ontology/id.cjs +26 -5
- package/skywalk-sdd/ontology/identity-index.cjs +3 -7
- package/skywalk-sdd/ontology/resolve-spec-root.cjs +20 -6
- package/skywalk-sdd/ontology/runtime.cjs +16 -12
- package/skywalk-sdd/ontology/traceability-validator.cjs +7 -4
- package/skywalk-sdd/reporting/change-report-markdown.cjs +137 -19
- package/skywalk-sdd/reporting/change-report-model.cjs +993 -14
- package/skywalk-sdd/reporting/change-report-renderer.cjs +106 -41
- package/skywalk-sdd/reporting/change-report-view-model.cjs +272 -43
- package/skywalk-sdd/reporting/core-metric-definitions.cjs +192 -0
- package/skywalk-sdd/spec-root.cjs +31 -0
- package/templates/git-hooks/pre-commit-consistency-check.cjs +271 -116
- package/templates/git-hooks/pre-push-consistency-check.cjs +252 -123
- package/templates/hooks/codebuddy/hooks/hook-gate-core.cjs +327 -0
- package/templates/hooks/codebuddy/hooks/sdd-apply-test-gate.cjs +54 -9
- package/templates/hooks/codebuddy/hooks/sdd-mid-checkpoint.cjs +63 -6
- package/templates/hooks/codebuddy/hooks/sdd-tdd-rhythm-gate.cjs +113 -65
- package/templates/openspec/proposal.md +7 -3
- package/templates/openspec/spec.md +3 -3
- package/templates/skills/kld-sdd/opsx-apply/SKILL.md +8 -6
- package/templates/skills/kld-sdd/opsx-apply/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-apply/reference.md +29 -7
- package/templates/skills/kld-sdd/opsx-archive/SKILL.md +6 -5
- package/templates/skills/kld-sdd/opsx-check/SKILL.md +49 -17
- package/templates/skills/kld-sdd/opsx-check/checklist.md +4 -2
- package/templates/skills/kld-sdd/opsx-consistency-check/SKILL.md +187 -257
- package/templates/skills/kld-sdd/opsx-consistency-check/reference.md +129 -0
- package/templates/skills/kld-sdd/opsx-design/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-explore/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-kb-config/SKILL.md +185 -0
- package/templates/skills/kld-sdd/opsx-kb-config/reference.md +127 -0
- package/templates/skills/kld-sdd/opsx-kb-ingest/SKILL.md +218 -53
- package/templates/skills/kld-sdd/opsx-kb-ingest/reference.md +51 -9
- package/templates/skills/kld-sdd/opsx-ontology-query/SKILL.md +12 -50
- package/templates/skills/kld-sdd/opsx-ontology-query/phase-3-postchange.md +2 -2
- package/templates/skills/kld-sdd/opsx-ontology-query/reference.md +1 -1
- package/templates/skills/kld-sdd/opsx-propose/SKILL.md +35 -23
- package/templates/skills/kld-sdd/opsx-propose/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-propose/reference.md +22 -17
- package/templates/skills/kld-sdd/opsx-rules/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-spec/SKILL.md +19 -15
- package/templates/skills/kld-sdd/opsx-spec/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-task/SKILL.md +2 -4
- package/templates/skills/kld-sdd/opsx-test/SKILL.md +2 -2
- package/templates/skills/kld-sdd/tdd-core/reference.md +1 -1
- package/templates/skills/kld-sdd/tdd-rules/rules/test-skeleton-telemetry.md +1 -1
- package/templates/skills/kld-sdd/opsx-kb-ingest/state.example.json +0 -7
- package/templates/skills/kld-sdd/opsx-ontology-query/state.example.json +0 -7
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# 判定标准参考
|
|
2
|
+
|
|
3
|
+
## 一、问题分类
|
|
4
|
+
|
|
5
|
+
首先将每个差异归类为以下四种类型之一:
|
|
6
|
+
|
|
7
|
+
| 问题类型 | 说明 | 示例 |
|
|
8
|
+
|---------|------|------|
|
|
9
|
+
| **代码有 spec 没有(业务)** | 代码实现了业务功能但 spec 未描述 | 代码有 `/api/export` 接口但 spec 未记录 |
|
|
10
|
+
| **代码有 spec 没有(技术)** | 代码实现了纯技术支撑逻辑,不涉及业务契约 | 工具方法、防御性校验、日志打印、框架样板代码、DTO 转换 |
|
|
11
|
+
| **spec 有代码没有** | spec 定义了但代码未实现 | spec 定义了权限校验但代码未实现 |
|
|
12
|
+
| **不一致** | 代码和 spec 都有但不匹配 | spec 定义字段 `token`,代码返回 `accessToken` |
|
|
13
|
+
|
|
14
|
+
> **技术实现 vs 业务实现的区分标准**:
|
|
15
|
+
>
|
|
16
|
+
> 以下类别属于**纯技术实现**,不要求 spec 覆盖:
|
|
17
|
+
>
|
|
18
|
+
> | 类别 | 说明 | 示例 |
|
|
19
|
+
> |------|------|------|
|
|
20
|
+
> | 工具/基础设施代码 | 通用工具方法、辅助函数 | `DateUtils.format()`, `StringUtils.isBlank()` |
|
|
21
|
+
> | 防御性代码 | 空值检查、边界保护、异常兜底 | `if (param == null) throw ...` |
|
|
22
|
+
> | 日志/监控代码 | 日志打印、埋点、健康检查 | `log.info("request: {}", param)` |
|
|
23
|
+
> | 框架样板代码 | 框架要求的固定结构 | Spring `@Configuration`、序列化配置 |
|
|
24
|
+
> | DTO/VO 转换 | 对象拷贝、字段映射 | `BeanUtils.copyProperties()` |
|
|
25
|
+
> | 配置类 | 技术配置、环境配置 | 数据库连接池、线程池配置 |
|
|
26
|
+
>
|
|
27
|
+
> **判断原则**:若代码行为不影响外部可观测的业务契约(接口路径、请求/响应字段、业务规则、错误码),则视为纯技术实现。
|
|
28
|
+
|
|
29
|
+
## 二、置信度判定规则
|
|
30
|
+
|
|
31
|
+
按以下顺序依次判定(最终置信度取最严重的结果):
|
|
32
|
+
|
|
33
|
+
**步骤 1:判断 spec 相关的问题(spec 有代码没有 / 不一致)**
|
|
34
|
+
|
|
35
|
+
| 关键性 | 置信度 | 说明 |
|
|
36
|
+
|--------|--------|------|
|
|
37
|
+
| 关键 | **low** | 影响核心业务流程、安全、前端决策 |
|
|
38
|
+
| 非关键 | **medium** | 辅助功能、非核心字段、提示性信息 |
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
示例:
|
|
42
|
+
- spec 定义了核心接口 /api/orders 但代码未实现 → low(关键)
|
|
43
|
+
- spec 定义了权限校验但代码未实现 → low(关键)
|
|
44
|
+
- 缺少提示性错误码 → medium(非关键)
|
|
45
|
+
- 前端非核心字段名与后端不一致 → medium(非关键)
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**步骤 2:判断代码多出来的内容(代码有 spec 没有)→ 分级兜底规则**
|
|
49
|
+
|
|
50
|
+
根据代码多出来的内容性质,分级处理:
|
|
51
|
+
|
|
52
|
+
| 代码多出的内容 | 置信度 | 说明 |
|
|
53
|
+
|--------------|--------|------|
|
|
54
|
+
| **业务功能**(接口、业务逻辑、业务错误码) | **low** | 核心业务行为必须有 spec 记录 |
|
|
55
|
+
| **辅助业务功能**(导出、审计、非核心扩展) | **medium** | 辅助功能建议记录但不强制 |
|
|
56
|
+
| **纯技术实现**(工具方法、防御性代码、日志、框架样板、DTO 转换、配置类) | **不降级** | 技术支撑代码不要求 spec 覆盖 |
|
|
57
|
+
|
|
58
|
+
此步骤用于确保业务代码实现都有对应的 spec 记录,同时避免对纯技术细节的过度管控。如果步骤 1 已判定为 low,此步骤结果也是 low,最终结果不变。如果步骤 1 是 medium,此步骤发现代码有**业务功能** spec 没有,则升级为 low。
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
示例:
|
|
62
|
+
- 代码有业务接口 /api/export 但 spec 未记录 → low(业务功能)
|
|
63
|
+
- 代码有权限校验逻辑但 spec 未记录 → low(业务功能)
|
|
64
|
+
- 代码有错误码 400 但 spec 未记录 → low(业务功能)
|
|
65
|
+
- 代码有 DateUtils.format() 工具方法但 spec 未记录 → 不降级(纯技术实现)
|
|
66
|
+
- 代码有 if (param == null) throw 防御性校验但 spec 未记录 → 不降级(纯技术实现)
|
|
67
|
+
- 代码有 log.info() 日志打印但 spec 未记录 → 不降级(纯技术实现)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**最终置信度**:取步骤 1 和步骤 2 中最严重的结果(low > medium > high)。
|
|
71
|
+
|
|
72
|
+
## 三、关键性判断标准
|
|
73
|
+
|
|
74
|
+
步骤 1 中需要判断差异是否"关键",按以下标准执行(满足任一即为关键):
|
|
75
|
+
|
|
76
|
+
**关键(→ low):**
|
|
77
|
+
|
|
78
|
+
| 类别 | 说明 | 示例 |
|
|
79
|
+
|------|------|------|
|
|
80
|
+
| 核心业务流程 | 影响主流程的接口/逻辑 | 登录、注册、下单、支付、审批 |
|
|
81
|
+
| 数据写入操作 | POST / PUT / DELETE / PATCH 操作 | 创建、编辑、删除接口 |
|
|
82
|
+
| 认证与授权 | 决定用户身份和权限的逻辑 | 401→登录页、403→权限页、角色校验 |
|
|
83
|
+
| 安全相关 | 防注入、防越权、敏感数据处理 | 密码加密、SQL 注入防护、数据脱敏 |
|
|
84
|
+
| 前端核心决策字段 | 决定页面跳转、功能开关的字段 | token、userId、status、role |
|
|
85
|
+
| 核心展示字段 | 用户可见的主要数据 | 订单金额、用户名、商品名称 |
|
|
86
|
+
|
|
87
|
+
**非关键(→ medium):**
|
|
88
|
+
|
|
89
|
+
同时满足以下全部条件即为非关键:
|
|
90
|
+
|
|
91
|
+
| 条件 | 说明 |
|
|
92
|
+
|------|------|
|
|
93
|
+
| 不影响核心业务流程 | 非主流程接口 |
|
|
94
|
+
| 不影响前端核心决策 | 不决定页面跳转或功能开关 |
|
|
95
|
+
| 非安全相关 | 不涉及认证、授权、数据校验 |
|
|
96
|
+
| 辅助功能 | 导出、日志、审计、健康检查、监控 |
|
|
97
|
+
|
|
98
|
+
**判断优先级**:当无法明确判断时,**默认视为关键**(宁可误报,不可漏报)。
|
|
99
|
+
|
|
100
|
+
## 四、维度判定参考
|
|
101
|
+
|
|
102
|
+
各维度的 pass/warning/fail 判定参考:
|
|
103
|
+
|
|
104
|
+
| 维度 | pass | warning(→ medium) | fail(→ low) |
|
|
105
|
+
|------|------|------------------|-------------------|
|
|
106
|
+
| **接口契约** | 所有检查项 ✅ | 辅助接口未记录 | 接口差异;代码有**业务接口**但 spec 未记录 |
|
|
107
|
+
| **业务规则** | 所有规则一致 | 非关键规则不一致 | 规则不一致;代码有**业务逻辑**但 spec 未记录 |
|
|
108
|
+
| **校验规则** | 所有约束一致 | 非关键约束不一致 | 必填字段无校验;代码有**业务校验逻辑**但 spec 未记录 |
|
|
109
|
+
| **错误码** | 所有错误码一致 | 非关键错误码缺失 | 错误码不一致;代码有**业务错误码**但 spec 未记录 |
|
|
110
|
+
| **前后端一致性** | 所有字段匹配 | 非核心字段不匹配 | 核心字段不匹配 |
|
|
111
|
+
|
|
112
|
+
> **注意**:纯技术实现(工具方法、防御性代码、日志、框架样板、DTO 转换、配置类)不影响维度判定,各维度均为 pass。
|
|
113
|
+
|
|
114
|
+
## 五、示例
|
|
115
|
+
|
|
116
|
+
| 场景 | 问题类型 | 关键性 | 置信度 |
|
|
117
|
+
|------|---------|--------|--------|
|
|
118
|
+
| 响应字段名错误(token → accessToken) | 不一致 | 关键 | **low** |
|
|
119
|
+
| 缺少密码复杂度校验 | spec 有代码没有 | 关键 | **low** |
|
|
120
|
+
| 代码有业务接口 /api/orders 但 spec 未记录 | 代码有 spec 没有(业务) | — | **low** |
|
|
121
|
+
| 代码有权限校验逻辑但 spec 未记录 | 代码有 spec 没有(业务) | — | **low** |
|
|
122
|
+
| 代码有辅助导出接口但 spec 未记录 | 代码有 spec 没有(业务) | 非关键 | **medium** |
|
|
123
|
+
| spec 定义了核心接口 /api/orders 但代码未实现 | spec 有代码没有 | 关键 | **low** |
|
|
124
|
+
| 缺少提示性错误码 | spec 有代码没有 | 非关键 | **medium** |
|
|
125
|
+
| 前端非核心字段名与后端不一致 | 不一致 | 非关键 | **medium** |
|
|
126
|
+
| 代码有 DateUtils 工具方法但 spec 未记录 | 代码有 spec 没有(技术) | — | **不降级** |
|
|
127
|
+
| 代码有防御性空值校验但 spec 未记录 | 代码有 spec 没有(技术) | — | **不降级** |
|
|
128
|
+
| 代码有日志打印但 spec 未记录 | 代码有 spec 没有(技术) | — | **不降级** |
|
|
129
|
+
| 所有维度完美匹配 | — | — | **high** |
|
|
@@ -47,8 +47,8 @@ allowed-tools:
|
|
|
47
47
|
|
|
48
48
|
> **🖥️ 跨平台执行规则**
|
|
49
49
|
> - **SDD 文档根** = `*-sdd-specs` 包裹包(含 `openspec/`、`modules.yaml`),不是 Git 根或工作区根。
|
|
50
|
-
> - `openspec`
|
|
51
|
-
> - Telemetry / ontology:`node
|
|
50
|
+
> - `openspec` 命令:`cd <spec-package> && openspec …`(先 cd 到包裹包即可)。路径不确定时用 `node <spec-package>/skywalk-sdd/spec-root.cjs` 验证。
|
|
51
|
+
> - Telemetry / ontology:`node <spec-package>/skywalk-sdd/log.cjs …`(直接在包裹包内执行);`--project=.` 指当前 spec 包裹包。
|
|
52
52
|
> - Telemetry 命令默认使用 `--project=.`,兼容 Windows、macOS、Linux。
|
|
53
53
|
> - ${SHELL_GUIDANCE}
|
|
54
54
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
@@ -17,8 +17,8 @@ allowed-tools:
|
|
|
17
17
|
|
|
18
18
|
> **🖥️ 跨平台执行规则**
|
|
19
19
|
> - **SDD 文档根** = `*-sdd-specs` 包裹包(含 `openspec/`、`modules.yaml`),不是 Git 根或工作区根。
|
|
20
|
-
> - `openspec`
|
|
21
|
-
> - Telemetry / ontology:`node
|
|
20
|
+
> - `openspec` 命令:`cd <spec-package> && openspec …`(先 cd 到包裹包即可)。路径不确定时用 `node <spec-package>/skywalk-sdd/spec-root.cjs` 验证。
|
|
21
|
+
> - Telemetry / ontology:`node <spec-package>/skywalk-sdd/log.cjs …`(直接在包裹包内执行);`--project=.` 指当前 spec 包裹包。
|
|
22
22
|
> - Telemetry 命令默认使用 `--project=.`,兼容 Windows、macOS、Linux。
|
|
23
23
|
> - ${SHELL_GUIDANCE}
|
|
24
24
|
> - 不要省略 `--source=opsx-command` 与 `--session-id=<会话ID>`。
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opsx-kb-config
|
|
3
|
+
description: >-
|
|
4
|
+
Configures Engineering KB access (API Key + Space/KB selection + project-identity).
|
|
5
|
+
Shared prerequisite for opsx-ontology-query, opsx-kb-ingest, and kb-upload.
|
|
6
|
+
Run once, all KB skills become available. Also supports changing KB spaces.
|
|
7
|
+
license: MIT
|
|
8
|
+
compatibility: Requires Engineering KB API (API Key with context:read + archive:ingest).
|
|
9
|
+
metadata:
|
|
10
|
+
author: sdd-team
|
|
11
|
+
version: "1.0"
|
|
12
|
+
source: "kb-sdd/skills/opsx-kb-config"
|
|
13
|
+
allowed-tools:
|
|
14
|
+
- Bash
|
|
15
|
+
- Read
|
|
16
|
+
- Write
|
|
17
|
+
- Edit
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
# 本体知识库 · 配置
|
|
21
|
+
|
|
22
|
+
只负责**配置**。一次配置,查询(opsx-ontology-query)、入库(opsx-kb-ingest)、文件夹上传(kb-upload)全部可用。
|
|
23
|
+
|
|
24
|
+
> **📡 共享状态**:配置写入 `kb-state.json`(位于 spec 仓根目录),所有 KB 技能共用。任一技能配置后,其他技能自动可用,无需重复输入。
|
|
25
|
+
|
|
26
|
+
> **🖥️ 跨平台执行规则**(Windows 用户必读):
|
|
27
|
+
> - KB 配置涉及 HTTP 请求和 JSON 文件读写,**禁止**在 PowerShell 中使用 `curl`(被别名为 Invoke-WebRequest)→ 用 `Invoke-RestMethod` 或 Node.js 脚本
|
|
28
|
+
> - **禁止**用 PowerShell `Get-Content` / `Out-File` 读写 JSON(默认写 BOM 导致 JSON.parse 失败)→ 用 write_to_file 工具或 Node.js `fs` 模块
|
|
29
|
+
> - **禁止** `| cat` 管道(PowerShell 将 cat 解释为 Get-Content 不接受管道输入)→ 直接执行命令
|
|
30
|
+
> - **禁止**用 `node -e "..."` 内联脚本(PowerShell 对 `||`/`{}`/`()` 有特殊解析,导致 JS 语法被破坏)→ 用 `write_to_file` 创建临时 `.cjs` 脚本执行后删除
|
|
31
|
+
> - **⚠️ PowerShell CLIXML**:直接执行 `node xxx.cjs` 时 stdout 可能被包装为 CLIXML `<Objs>` 格式导致 JSON 解析失败。`lib/shared.cjs` 已内置 `stripCliXml()` 剥离函数;临时脚本中可用 `require('./lib/shared.cjs').stripCliXml(output)` 处理
|
|
32
|
+
> - **推荐**用 `write_to_file` 创建临时 `.cjs` 脚本执行所有 Node.js 逻辑,执行完后 `delete_file` 清理
|
|
33
|
+
|
|
34
|
+
## 能做什么
|
|
35
|
+
|
|
36
|
+
| 场景 | 说明 |
|
|
37
|
+
|------|------|
|
|
38
|
+
| 首次配置 | 输入 API Key → 绑定监控项目(可留空)→ 选择 Space/KB → 创建 project-identity.json |
|
|
39
|
+
| 更换 API Key | 清空 apiKey,重新输入;随后需重新校验监控项目绑定 |
|
|
40
|
+
| 更换知识库 | 清空 targets,重新选择 Space/KB |
|
|
41
|
+
| 绑定/更换监控项目 | 写入或清除 `projectName`(Step 2.5) |
|
|
42
|
+
| 查看当前配置 | 展示已配置的 Space/KB 列表与项目绑定 |
|
|
43
|
+
| 校验配置 | 探活 API + 校验 project_id 与 spaceKey 一致 |
|
|
44
|
+
|
|
45
|
+
## 配置步骤
|
|
46
|
+
|
|
47
|
+
### 1. 读取共享状态
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# 读取 spec 包裹包路径
|
|
51
|
+
SPEC_ROOT=$(node <spec-package>/skywalk-sdd/spec-root.cjs)
|
|
52
|
+
|
|
53
|
+
# 读取共享 KB 配置(用 write_to_file 创建临时脚本,勿用 node -e)
|
|
54
|
+
# 临时脚本内容:
|
|
55
|
+
# const fs = require('fs');
|
|
56
|
+
# try { console.log(fs.readFileSync(process.argv[1], 'utf8')); }
|
|
57
|
+
# catch { console.log('{}'); }
|
|
58
|
+
# 执行:node _tmp-read-state.cjs "$SPEC_ROOT/kb-state.json"
|
|
59
|
+
# 或直接用 read_file 工具读取该文件
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### 2. API Key
|
|
63
|
+
|
|
64
|
+
若 `state.apiKey` 为空或用户要求换密钥:
|
|
65
|
+
|
|
66
|
+
1. 请用户提供 API Key(控制台「API 密钥」创建,scope 建议同时勾选 `context:read` + `archive:ingest`,使查询与入库都能复用)。
|
|
67
|
+
2. 可选:请用户确认 `api`(默认 `http://10.29.213.80:8080/api`)与 `tenantKey`(默认 `default`)。
|
|
68
|
+
3. 写入 `kb-state.json`(spec 仓根目录,已 gitignore)。
|
|
69
|
+
4. 用 `GET $API/health` 探活;再用 `GET $API/v1/spaces?tenantKey=…` + Bearer 校验 key。
|
|
70
|
+
|
|
71
|
+
**安全规则**:
|
|
72
|
+
- 完整 apiKey 只写共享 state 文件;聊天里最多显示前缀(如 `sk_sdd_****`)。
|
|
73
|
+
- 401/403 → 清掉 apiKey 请用户重贴,勿循环重试。
|
|
74
|
+
- **不要** `POST /auth/login`。
|
|
75
|
+
|
|
76
|
+
### 2.5. 监控项目绑定(`projectName`,可留空)
|
|
77
|
+
|
|
78
|
+
实时监控按"用户 / 项目"维度展示 Run:上传事件时服务端会根据 API 密钥解析上传用户,并按此处绑定的项目名称写入投影(服务端校验该用户必须是项目成员,否则项目留空、不阻断上传)。
|
|
79
|
+
|
|
80
|
+
1. 询问用户项目名称;**留空** → 写 `projectName: null`(不绑定),跳到 Step 3。
|
|
81
|
+
2. 非空 → 用共享库做成员预校验(Bearer = 当前 apiKey):
|
|
82
|
+
```js
|
|
83
|
+
// 临时 .cjs 脚本(遵循本文件头部跨平台规则):
|
|
84
|
+
const shared = require('<SPEC_ROOT>/skywalk-sdd/lib/shared.cjs');
|
|
85
|
+
const r = await shared.verifyProjectMembershipViaServer(SPEC_ROOT, '<项目名称>');
|
|
86
|
+
```
|
|
87
|
+
- `member === true` → `shared.setKbProjectName(SPEC_ROOT, '<项目名称>')` 写入,提示绑定生效。
|
|
88
|
+
- `member === false` → 提示"绑定不会生效,上传记录的项目将留空",让用户选择**重填**或**留空**(`setKbProjectName(SPEC_ROOT, null)`);不要直接保存非成员名称。
|
|
89
|
+
- `ok === false`(`reason: 'endpoint_unavailable'`,服务端未上线该端点或不可达)→ 软警告"平台暂不支持项目成员校验,绑定将在上传时由服务端裁决",允许用户选择保存或留空。
|
|
90
|
+
3. 换密钥后原 `projectName` 可能对新密钥用户失效 → 换密钥流程完成后重走本步校验。
|
|
91
|
+
|
|
92
|
+
> 写入位置:`kb-state.json` 的 `projectName` 键(与 api/apiKey 同文件,已 gitignore)。同步代理每次上报批次时重读该配置,改绑/解绑后新事件即按新配置上报,无需重启或迁移。
|
|
93
|
+
|
|
94
|
+
### 3. 选择空间与知识库(支持多选)
|
|
95
|
+
|
|
96
|
+
若 `state.targets` 为空,或用户要求重新选择:
|
|
97
|
+
|
|
98
|
+
1. `GET $API/v1/spaces?tenantKey=$TENANT_KEY`
|
|
99
|
+
2. 对每个相关 space:`GET $API/v1/spaces/{spaceId}/knowledge-bases`
|
|
100
|
+
3. 向用户展示「空间名 / spaceId → KB 名 / kbId」清单,**允许多选**。
|
|
101
|
+
4. 写入 `targets: [{ spaceId, spaceName, spaceKey, kbId, kbName }, …]`。
|
|
102
|
+
|
|
103
|
+
> **API 返回字段说明**(临时脚本中注意字段名):
|
|
104
|
+
> - Space 列表返回 `spaceId`(camelCase),不是 `id`。临时脚本中使用 `s.spaceId || s.id` 兼容。
|
|
105
|
+
> - Space 列表返回 `spaceKey`(项目标识,非 UUID),用于 `project-identity.json` 的 `project_id`。
|
|
106
|
+
> - KB 列表返回 `kbId`(camelCase),不是 `id`。
|
|
107
|
+
|
|
108
|
+
### 4. 写入项目身份文件(首次配置 Space 后必做)
|
|
109
|
+
|
|
110
|
+
> `project-identity.json` 是 spec 仓 Git 中的**团队共享**文件,记录 `project_id`(= KB Space 的 `spaceKey`)。Archive 阶段 `archive-docs` 读取此文件生成 `archive-manifest.json`,kb-ingest / kb-upload 上传时 KB 校验 `project_id === spaceKey`。
|
|
111
|
+
|
|
112
|
+
选择 Space 完成后(Step 3 写入 `targets` 后),执行以下逻辑:
|
|
113
|
+
|
|
114
|
+
1. 读取 spec 包裹包路径:
|
|
115
|
+
```bash
|
|
116
|
+
SPEC_ROOT=$(node <spec-package>/skywalk-sdd/spec-root.cjs)
|
|
117
|
+
```
|
|
118
|
+
2. 检查 `$SPEC_ROOT/skywalk-sdd/project-identity.json` 是否已存在
|
|
119
|
+
3. **不存在** → 创建(取 `targets[0].spaceKey` 作为 `project_id`):
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"schema_version": "kld-sdd-project-identity/v1",
|
|
123
|
+
"project_id": "<targets[0].spaceKey>",
|
|
124
|
+
"created_at": "<ISO timestamp>",
|
|
125
|
+
"kb_space_id": "<targets[0].spaceId>",
|
|
126
|
+
"kb_space_name": "<targets[0].spaceName>"
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
输出:`✓ 已创建 skywalk-sdd/project-identity.json(project_id: <spaceKey>),请提交到 spec 仓 Git 以便团队共享`
|
|
130
|
+
4. **已存在但 `project_id` 与 `targets[0].spaceKey` 不一致** → 用 AskUserQuestion 询问:
|
|
131
|
+
> "project-identity.json 中的 project_id 与当前选择的 KB Space spaceKey 不一致:
|
|
132
|
+
> - 文件中:`<existing project_id>`
|
|
133
|
+
> - 当前 Space:`<spaceKey>`
|
|
134
|
+
> 是否更新?"
|
|
135
|
+
- 用户确认 → 更新 `project_id` + `kb_space_id` + `kb_space_name`
|
|
136
|
+
- 用户拒绝 → 保留原值(可能入库时报 `PROJECT_SPACE_MISMATCH`)
|
|
137
|
+
5. **已存在且一致** → 跳过,不输出
|
|
138
|
+
|
|
139
|
+
> state.json 字段 schema、鉴权细节、列表接口 → [reference.md](reference.md)。
|
|
140
|
+
|
|
141
|
+
## 更换知识库
|
|
142
|
+
|
|
143
|
+
当用户说「换知识库 / 换 Space / 重新选择」时:
|
|
144
|
+
|
|
145
|
+
1. **保留 apiKey**(不需要重新输入密钥)
|
|
146
|
+
2. 清空 `state.targets`
|
|
147
|
+
3. 重走 Step 3(选择空间与知识库)
|
|
148
|
+
4. 重走 Step 4(更新 project-identity.json)
|
|
149
|
+
|
|
150
|
+
> ⚠️ 更换 Space 后,`project_id` 会随之变化。之前上传到旧 Space 的归档包不受影响,但新上传将写入新 Space。
|
|
151
|
+
|
|
152
|
+
## 查看当前配置
|
|
153
|
+
|
|
154
|
+
读取 `kb-state.json` 并展示:
|
|
155
|
+
|
|
156
|
+
```markdown
|
|
157
|
+
### 当前 KB 配置
|
|
158
|
+
- API 地址:{api}
|
|
159
|
+
- 租户:{tenantKey}
|
|
160
|
+
- API Key:{前缀}****(已配置 / 未配置)
|
|
161
|
+
- 项目绑定:{projectName 或 未绑定}
|
|
162
|
+
- 目标 Space/KB:
|
|
163
|
+
1. {spaceName}(spaceKey: {spaceKey})→ {kbName}
|
|
164
|
+
2. ...
|
|
165
|
+
- project-identity.json:{已存在 / 不存在}(project_id: {值})
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## 用户口令
|
|
169
|
+
|
|
170
|
+
| 用户说 | Agent 做 |
|
|
171
|
+
|--------|----------|
|
|
172
|
+
| 配置知识库 / 首次使用 | 走完 Step 1→2→2.5→3→4 |
|
|
173
|
+
| 换密钥 / 重置 API Key | 清 apiKey,重走 Step 2,再重走 Step 2.5 校验项目绑定 |
|
|
174
|
+
| 换项目 / 重新绑定项目 / 解绑项目 | 重走 Step 2.5(保留 apiKey 与 targets) |
|
|
175
|
+
| 换空间 / 换知识库 / 重新选择 | 清 targets,重走 Step 3→4 |
|
|
176
|
+
| 看配置 / 当前配置 | 读取 kb-state.json + project-identity.json 并展示 |
|
|
177
|
+
| 校验配置 | 探活 + 校验 project_id === spaceKey |
|
|
178
|
+
|
|
179
|
+
## 硬规则
|
|
180
|
+
|
|
181
|
+
- 无 `apiKey` 不得猜密钥、不得改走 login。
|
|
182
|
+
- 无 `targets` 不得臆造 spaceId/kbId。
|
|
183
|
+
- 完整 apiKey 只写共享 state 文件(`kb-state.json`,spec 仓根目录);聊天里最多显示前缀。
|
|
184
|
+
- 401/403 时清掉 `apiKey`,请用户重贴;勿循环重试。
|
|
185
|
+
- **共享状态**:state 文件与 `opsx-ontology-query`、`opsx-kb-ingest`、`kb-upload` 共用。配置一次,全部生效。
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# 本体知识库配置 · 参考
|
|
2
|
+
|
|
3
|
+
需要鉴权细节、state 字段或 API 示例时再读。
|
|
4
|
+
|
|
5
|
+
## `kb-state.json`
|
|
6
|
+
|
|
7
|
+
路径:`<spec-root>/kb-state.json`(已 gitignore)。
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"api": "http://10.29.213.80:8080/api",
|
|
12
|
+
"tenantKey": "default",
|
|
13
|
+
"apiKey": "sk_sdd_…",
|
|
14
|
+
"projectName": "支付网关重构",
|
|
15
|
+
"updatedAt": "2026-07-19T12:00:00Z",
|
|
16
|
+
"targets": [
|
|
17
|
+
{
|
|
18
|
+
"spaceId": "uuid",
|
|
19
|
+
"spaceKey": "demo",
|
|
20
|
+
"spaceName": "演示空间",
|
|
21
|
+
"kbId": "uuid",
|
|
22
|
+
"kbName": "默认知识库"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
| 字段 | 必填 | 说明 |
|
|
29
|
+
|------|------|------|
|
|
30
|
+
| `api` | 是 | API 根,含 `/api` |
|
|
31
|
+
| `tenantKey` | 是 | 列空间用;默认 `default` |
|
|
32
|
+
| `apiKey` | 是 | 控制台创建的 `sk_sdd_…`,scope 建议 `context:read` + `archive:ingest` |
|
|
33
|
+
| `projectName` | 否 | 监控项目绑定名;`null`/缺失/空白 = 未绑定,上传批次不携带 `project_name` |
|
|
34
|
+
| `scopes` | 建议 | API Client scope 列表 |
|
|
35
|
+
| `targets` | 操作前必填 | 多选;可为空仅当尚未完成选择 |
|
|
36
|
+
| `updatedAt` | 建议 | ISO-8601 |
|
|
37
|
+
|
|
38
|
+
## 监控项目绑定与上传
|
|
39
|
+
|
|
40
|
+
- 配置期预校验:`GET {api}/v1/sdd-runs/dimensions`(Bearer),返回当前密钥用户可见的 `projects[]`;条目名称匹配即视为成员。端点 404/不可达表示服务端尚未上线该能力 → 软警告后可保存,服务端在上传时做权威裁决(非成员项目置空、不阻断)。
|
|
41
|
+
- 客户端辅助函数:`verifyProjectMembershipViaServer(specRoot, projectName)`(预校验,软返回)、`setKbProjectName(specRoot, projectName|null)`(原子写入/清除),均在 `skywalk-sdd/lib/shared.cjs`。
|
|
42
|
+
- 上传行为:同步代理每次组 batch 时重读 `kb-state.json`;`projectName` 非空 → batch 请求体顶层附带可选 `project_name` 字段(`sdd-progress-batch-v1.schema.json`,1-128 字符);未配置 → 请求体与历史版本完全一致。
|
|
43
|
+
- 环境变量兜底:`ENGINEERING_KB_PROJECT_NAME`(kb-state 无 `projectName` 时生效)。
|
|
44
|
+
|
|
45
|
+
## `project-identity.json`
|
|
46
|
+
|
|
47
|
+
路径:`<spec-root>/skywalk-sdd/project-identity.json`(**提交到 Git,团队共享**)。
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"schema_version": "kld-sdd-project-identity/v1",
|
|
52
|
+
"project_id": "<KB Space 的 spaceKey>",
|
|
53
|
+
"created_at": "<ISO timestamp>",
|
|
54
|
+
"kb_space_id": "<Space UUID>",
|
|
55
|
+
"kb_space_name": "<Space 名称>"
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| 字段 | 必填 | 说明 |
|
|
60
|
+
|------|------|------|
|
|
61
|
+
| `schema_version` | 是 | 固定 `kld-sdd-project-identity/v1` |
|
|
62
|
+
| `project_id` | 是 | = 目标 Space 的 `spaceKey`,KB 入库时校验一致性 |
|
|
63
|
+
| `created_at` | 是 | ISO-8601 |
|
|
64
|
+
| `kb_space_id` | 建议 | Space UUID |
|
|
65
|
+
| `kb_space_name` | 建议 | Space 名称 |
|
|
66
|
+
|
|
67
|
+
## 鉴权
|
|
68
|
+
|
|
69
|
+
```http
|
|
70
|
+
Authorization: Bearer sk_sdd_…
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
- **不要** `POST /auth/login`。
|
|
74
|
+
- Key 在控制台「API 密钥」创建;创建时建议勾选 **读取上下文 / context:read** + **入库 / archive:ingest**(查询与入库都需要)。
|
|
75
|
+
- 如需查看 API Client 当前 scopes,可调用 `GET {api}/v1/spaces/{spaceId}/api-clients/me`,响应字段:`data.name`、`data.scopes`(string[])。
|
|
76
|
+
- 401/403:清掉 state 里的 `apiKey`,请用户重贴;勿循环重试。
|
|
77
|
+
|
|
78
|
+
探活与校验(PowerShell 用 `Invoke-RestMethod`,**禁止** `curl`):
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
# 探活
|
|
82
|
+
Invoke-RestMethod -Uri "$API/health"
|
|
83
|
+
|
|
84
|
+
# 校验 API Key + 列空间
|
|
85
|
+
$headers = @{ Authorization = "Bearer $API_KEY" }
|
|
86
|
+
Invoke-RestMethod -Uri "$API/v1/spaces?tenantKey=$TENANT_KEY" -Headers $headers
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## 列表接口(选择用)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# 空间
|
|
93
|
+
GET $API/v1/spaces?tenantKey=$TENANT_KEY
|
|
94
|
+
|
|
95
|
+
# 某空间下 KB
|
|
96
|
+
GET $API/v1/spaces/{spaceId}/knowledge-bases
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
API Key 一般为租户范围;`apiKeySpaceId` 为空时可列出租户下多空间,便于多选。
|
|
100
|
+
|
|
101
|
+
### 响应字段映射(重要)
|
|
102
|
+
|
|
103
|
+
KB API 返回的 JSON 字段名(Java record 序列化)与 `kb-state.json` 的字段名**不完全一致**,必须做映射:
|
|
104
|
+
|
|
105
|
+
#### Space 列表 → `kb-state.json targets[]`
|
|
106
|
+
|
|
107
|
+
| API 响应字段 (`ProjectSpaceDto`) | `kb-state.json` 字段 | 映射 |
|
|
108
|
+
|------|------|------|
|
|
109
|
+
| `spaceId` | `spaceId` | 直接使用 |
|
|
110
|
+
| `spaceKey` | `spaceKey` | 直接使用 |
|
|
111
|
+
| `name` | `spaceName` | **需映射** `name → spaceName` |
|
|
112
|
+
|
|
113
|
+
#### KB 列表 → `kb-state.json targets[]`
|
|
114
|
+
|
|
115
|
+
| API 响应字段 (`KnowledgeBaseDto`) | `kb-state.json` 字段 | 映射 |
|
|
116
|
+
|------|------|------|
|
|
117
|
+
| `knowledgeBaseId` | `kbId` | **需映射** `knowledgeBaseId → kbId` |
|
|
118
|
+
| `name` | `kbName` | **需映射** `name → kbName` |
|
|
119
|
+
|
|
120
|
+
#### Resolve 响应 → `semantic-identity` 参数
|
|
121
|
+
|
|
122
|
+
| API 响应字段 (`ResolveCandidate`) | `semantic-identity` 参数 | 注意 |
|
|
123
|
+
|------|------|------|
|
|
124
|
+
| `entityId` | `--entity-id` | KB 返回完整 UUID(36字符),`semantic-identity` 的 `id.cjs` 会自动归一化为 8-hex 短格式 |
|
|
125
|
+
| `entityVersionId` | `--previous-version-id` | 同上,自动归一化 |
|
|
126
|
+
|
|
127
|
+
> ⚠️ **常见错误**:直接用 `k.kbId` / `k.kbName` 读取 KB API 响应 → 返回空值。正确写法:`k.knowledgeBaseId` / `k.name`,然后映射到 `kb-state.json` 的 `kbId` / `kbName`。
|