kld-sdd 2.6.3 → 2.6.5
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/lib/skills-bundle.js +5 -0
- package/package.json +2 -2
- package/skywalk-sdd/context-client.cjs +54 -14
- package/skywalk-sdd/ontology/archive-package.cjs +35 -4
- package/skywalk-sdd/ontology/artifact-parser.cjs +119 -5
- package/skywalk-sdd/ontology/identity-index.cjs +11 -0
- package/skywalk-sdd/ontology/normalizer.cjs +11 -0
- package/skywalk-sdd/ontology/runtime.cjs +5 -0
- package/skywalk-sdd/ontology/schema.cjs +5 -0
- package/skywalk-sdd/ontology/traceability-validator.cjs +156 -0
- package/templates/openspec/continuity-resolution.example.json +32 -0
- package/templates/openspec/proposal.md +18 -0
- package/templates/openspec/spec.md +3 -0
- package/templates/skills/kld-sdd/opsx-archive/SKILL.md +11 -2
- package/templates/skills/kld-sdd/opsx-check/SKILL.md +10 -0
- package/templates/skills/kld-sdd/opsx-kb-ingest/SKILL.md +190 -0
- package/templates/skills/kld-sdd/opsx-kb-ingest/reference.md +196 -0
- package/templates/skills/kld-sdd/opsx-kb-ingest/state.example.json +7 -0
- package/templates/skills/kld-sdd/opsx-ontology-query/SKILL.md +180 -0
- package/templates/skills/kld-sdd/opsx-ontology-query/reference.md +157 -0
- package/templates/skills/kld-sdd/opsx-ontology-query/state.example.json +7 -0
- package/templates/skills/kld-sdd/opsx-propose/SKILL.md +26 -1
- package/templates/skills/kld-sdd/opsx-spec/SKILL.md +26 -12
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# 本体入库 · 参考
|
|
2
|
+
|
|
3
|
+
需要鉴权细节、state 字段或 Archive Package 规格时再读。
|
|
4
|
+
|
|
5
|
+
## `.local/state.json`
|
|
6
|
+
|
|
7
|
+
路径:`skills/opsx-kb-ingest/.local/state.json`(已 gitignore)。
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"api": "http://localhost:8090/api",
|
|
12
|
+
"tenantKey": "default",
|
|
13
|
+
"apiKey": "sk_sdd_…",
|
|
14
|
+
"updatedAt": "2026-07-19T12:00:00Z",
|
|
15
|
+
"targets": [
|
|
16
|
+
{
|
|
17
|
+
"spaceId": "uuid",
|
|
18
|
+
"spaceKey": "demo",
|
|
19
|
+
"spaceName": "演示空间",
|
|
20
|
+
"kbId": "uuid",
|
|
21
|
+
"kbName": "默认知识库"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| 字段 | 必填 | 说明 |
|
|
28
|
+
|------|------|------|
|
|
29
|
+
| `api` | 是 | API 根,含 `/api` |
|
|
30
|
+
| `tenantKey` | 是 | 列空间用;默认 `default` |
|
|
31
|
+
| `apiKey` | 是 | 控制台创建的 `sk_sdd_…`,scope 至少 `archive:ingest` |
|
|
32
|
+
| `targets` | 操作前必填 | 多选;可为空仅当尚未完成选择 |
|
|
33
|
+
| `updatedAt` | 建议 | ISO-8601 |
|
|
34
|
+
|
|
35
|
+
示例(无密钥)见 [state.example.json](state.example.json)。
|
|
36
|
+
|
|
37
|
+
## 鉴权
|
|
38
|
+
|
|
39
|
+
```http
|
|
40
|
+
Authorization: Bearer sk_sdd_…
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **不要** `POST /auth/login`。
|
|
44
|
+
- Key 在控制台「API 密钥」创建;创建时勾选 **入库 / archive:ingest**(写入需要)。
|
|
45
|
+
- 401/403:清掉 state 里的 `apiKey`,请用户重贴;勿循环重试。
|
|
46
|
+
|
|
47
|
+
探活与校验:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -sf "$API/health"
|
|
51
|
+
curl -sS -H "Authorization: Bearer $API_KEY" \
|
|
52
|
+
"$API/v1/spaces?tenantKey=$TENANT_KEY"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 列表接口(选择用)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# 空间
|
|
59
|
+
GET $API/v1/spaces?tenantKey=$TENANT_KEY
|
|
60
|
+
|
|
61
|
+
# 某空间下 KB
|
|
62
|
+
GET $API/v1/spaces/{spaceId}/knowledge-bases
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
API Key 一般为租户范围;`apiKeySpaceId` 为空时可列出租户下多空间,便于多选。
|
|
66
|
+
|
|
67
|
+
## 入库接口
|
|
68
|
+
|
|
69
|
+
路径前缀:`/api/v1/spaces/{spaceId}/knowledge-bases/{kbId}/ingestions`
|
|
70
|
+
|
|
71
|
+
### 上传 zip 包
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
POST {base}/ingestions
|
|
75
|
+
Content-Type: multipart/form-data
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
curl -sS -X POST "$API/v1/spaces/$SPACE_ID/knowledge-bases/$KB_ID/ingestions" \
|
|
80
|
+
-H "Authorization: Bearer $API_KEY" \
|
|
81
|
+
-F "package=@/path/to/archive.zip;type=application/zip"
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 列出入库任务
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
GET {base}/ingestions
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
返回最近 100 条入库任务,按 `created_at DESC` 排序。
|
|
91
|
+
|
|
92
|
+
### 查看任务状态
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
GET {base}/ingestions/{jobId}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 重试失败任务
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
POST {base}/ingestions/{jobId}/retry
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
仅 `status=failed` 的任务可重试;后端会重新解析原始上传的 zip 包。
|
|
105
|
+
|
|
106
|
+
## IngestionJobDto 响应字段
|
|
107
|
+
|
|
108
|
+
| 字段 | 类型 | 说明 |
|
|
109
|
+
|------|------|------|
|
|
110
|
+
| `jobId` | UUID | 任务 ID |
|
|
111
|
+
| `spaceId` | UUID | 空间 ID |
|
|
112
|
+
| `archiveId` | String | 归档 ID(来自 manifest) |
|
|
113
|
+
| `contentHash` | String | 内容哈希 `sha256:…` |
|
|
114
|
+
| `packageName` | String | 上传的文件名 |
|
|
115
|
+
| `packageHash` | String | 包哈希 `sha256:…` |
|
|
116
|
+
| `status` | String | `running` / `succeeded` / `failed` |
|
|
117
|
+
| `stage` | String | `validating` / `canonical-store` / `committed` / `failed` |
|
|
118
|
+
| `idempotentHit` | boolean | 是否命中幂等(同 archive_id + content_hash) |
|
|
119
|
+
| `relationStatus` | String | `pending` / `committed` / `rolled_back` / `not_required` |
|
|
120
|
+
| `projectionStatus` | String | `pending` / `not_started` / … |
|
|
121
|
+
| `errorCode` | String | 失败错误码(见下表) |
|
|
122
|
+
| `errorMessage` | String | 失败错误描述 |
|
|
123
|
+
| `report` | JsonNode | 入库报告(成功含 `externalRefsWritten`;冲突失败含 `details`) |
|
|
124
|
+
| `attempts` | int | 尝试次数 |
|
|
125
|
+
| `createdBy` | String | 创建者标识 |
|
|
126
|
+
| `createdAt` | Instant | 创建时间 |
|
|
127
|
+
| `updatedAt` | Instant | 更新时间 |
|
|
128
|
+
| `finishedAt` | Instant | 完成时间 |
|
|
129
|
+
|
|
130
|
+
## 常见错误码
|
|
131
|
+
|
|
132
|
+
| errorCode | 含义 |
|
|
133
|
+
|-----------|------|
|
|
134
|
+
| `INGEST_FAILED` | 通用入库失败 |
|
|
135
|
+
| `PROJECT_SPACE_MISMATCH` | manifest 中 project_id 与目标 Space spaceKey 不一致 |
|
|
136
|
+
| `ARCHIVE_IMMUTABILITY_VIOLATION` | 同一 archive_id 已存在不同 content_hash |
|
|
137
|
+
| `MANIFEST_MISSING` | 缺少必需的 manifest 文件 |
|
|
138
|
+
| `INVALID_FILE_TYPE` | 包含不允许的文件类型 |
|
|
139
|
+
| `SIZE_LIMIT_EXCEEDED` | 超过包/文件/条目大小限制 |
|
|
140
|
+
| `HASH_MISMATCH` | 文件 SHA-256 校验不通过 |
|
|
141
|
+
| `EXTERNAL_REF_CONFLICT` | 同外部键+同锚点已绑不同 entity_id;整包回滚;见 `report.details` |
|
|
142
|
+
| `EXTERNAL_REFERENCE_TYPE_MISMATCH` | 包内 object_type 与实体类型不匹配 |
|
|
143
|
+
| `EXTERNAL_REFERENCE_DUPLICATE_IN_PACKAGE` | 包内重复 `(external key, entity_id)` |
|
|
144
|
+
| `FACTS_SCHEMA_UNSUPPORTED` | canonical-facts schema 非 v1/v2 |
|
|
145
|
+
|
|
146
|
+
### `EXTERNAL_REF_CONFLICT` 的 report.details
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"externalRef": { "system": "requirement-mgmt", "objectType": "requirement", "externalId": "REQ-…" },
|
|
151
|
+
"anchor": "CAP-ORDER-CANCEL",
|
|
152
|
+
"existingEntityId": "<uuid>",
|
|
153
|
+
"existingCurrentVersionId": "<uuid>",
|
|
154
|
+
"incomingEntityId": "<uuid>",
|
|
155
|
+
"remediation": ["reuse-existing-identity", "assign-new-anchor"]
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
修正必须回到 kld-sdd(复用历史身份或换新锚点),重新 check → 归档 → 入库;禁止在 KB 改绑。
|
|
160
|
+
|
|
161
|
+
## Archive Package 规格
|
|
162
|
+
|
|
163
|
+
### 必需文件
|
|
164
|
+
|
|
165
|
+
| 文件 | 说明 |
|
|
166
|
+
|------|------|
|
|
167
|
+
| `archive-manifest.json` | 归档清单,含 archive_id、project_id、content_hash、files 列表 |
|
|
168
|
+
| `canonical-facts.json` | 规范化事实:`kld-sdd-canonical-facts/v1` 或 **`v2`**(v2 可选实体级 `external_refs`) |
|
|
169
|
+
| `conversion-report.json` | 转换报告(`target_schema` 可为 v1 或 v2) |
|
|
170
|
+
|
|
171
|
+
### 文件类型白名单
|
|
172
|
+
|
|
173
|
+
`.md`、`.json`、`.jsonl`、`.yaml`、`.yml`
|
|
174
|
+
|
|
175
|
+
### 大小限制
|
|
176
|
+
|
|
177
|
+
| 限制项 | 默认值 |
|
|
178
|
+
|--------|--------|
|
|
179
|
+
| 包大小 | 50 MB |
|
|
180
|
+
| 条目数 | 2000 |
|
|
181
|
+
| 单文件大小 | 10 MB |
|
|
182
|
+
| 解压后总大小 | 200 MB |
|
|
183
|
+
|
|
184
|
+
### manifest 关键字段
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"archive_id": "2026-07-18-user-center",
|
|
189
|
+
"project_id": "<必须与目标 Space spaceKey 一致>",
|
|
190
|
+
"content_hash": "sha256:<canonical-facts.json 的哈希>",
|
|
191
|
+
"files": [
|
|
192
|
+
{ "path": "canonical-facts.json", "content_hash": "sha256:…" },
|
|
193
|
+
{ "path": "conversion-report.json", "content_hash": "sha256:…" }
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opsx-ontology-query
|
|
3
|
+
description: >-
|
|
4
|
+
Queries the Engineering KB ontology via API Key (context search, match-requirement,
|
|
5
|
+
entity/impact/ontology-view). Prompts for API key and multi-selects spaces/KBs into
|
|
6
|
+
local skill state. Use when looking up Spec/design facts, Spec reuse, impact, or
|
|
7
|
+
citation-backed answers from the ontology KB.
|
|
8
|
+
argument-hint: "[query or continuity intent]"
|
|
9
|
+
license: MIT
|
|
10
|
+
compatibility: Requires Engineering KB API (API Key with context:read).
|
|
11
|
+
metadata:
|
|
12
|
+
author: sdd-team
|
|
13
|
+
version: "1.0"
|
|
14
|
+
source: "kb-sdd/skills/opsx-ontology-query"
|
|
15
|
+
allowed-tools:
|
|
16
|
+
- Bash
|
|
17
|
+
- Read
|
|
18
|
+
- Write
|
|
19
|
+
- Edit
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# 本体知识库 · 查询
|
|
23
|
+
|
|
24
|
+
> **部署说明**:本技能随 `kld-sdd-init` 安装到项目 skills 目录。权威源在工程知识库仓 `skills/opsx-ontology-query`;`opsx-propose` / `opsx-spec` 等流程技能**硬依赖**本技能,缺失时不得用本地 archive 兜底。
|
|
25
|
+
|
|
26
|
+
只负责**查**。鉴权只用 **API Key**(`Authorization: Bearer sk_sdd_…`),**禁止**走手机号登录。
|
|
27
|
+
|
|
28
|
+
> 控制台知识库页另有浮动 Ontology Agent(会话登录 + SSE);本 Skill 仍走 API Key,二者分开。
|
|
29
|
+
>
|
|
30
|
+
> **Agent 角色(V1)**:控制台 Agent 是 **单一 ReActAgent + 角色人格切换**(架构师 / 业务分析师 / 数据分析师),
|
|
31
|
+
> 不是三个独立 JVM agent。共享工具集,仅 sysPrompt 与工具偏好不同——Studio 仍单 run、延迟更低,后续需要再拆。
|
|
32
|
+
> 交互硬规则:自然语言优先,不向用户索要 UUID;多实体时用 `ask_user` Generative UI 卡片(`type=choice`,options.label=名称)。
|
|
33
|
+
>
|
|
34
|
+
> **Skills 激活**:控制台 Agent 通过 AgentScope `FileSystemSkillRepository`(`skillsRoot`,见
|
|
35
|
+
> `classpath:agent/agent.yml`)挂载本目录;运行时用内置工具 `load_skill_through_path`
|
|
36
|
+
> (skillId=`opsx-ontology-query`,path=`SKILL.md` / `reference.md`)按需加载,不把全文塞进 system prompt。
|
|
37
|
+
>
|
|
38
|
+
> **记忆**:会话短期用 AgentScope `InMemoryAgentStateStore`;本体事实仍走 KB(pgvector/SQL)。
|
|
39
|
+
> **不需要 mem0**,除非以后要跨会话个人偏好记忆。
|
|
40
|
+
|
|
41
|
+
本地状态文件(含密钥,勿提交):
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
skills/opsx-ontology-query/.local/state.json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
字段说明 → [reference.md](reference.md)。
|
|
48
|
+
|
|
49
|
+
## Session 启动(每次用本 Skill 必做)
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Task Progress:
|
|
53
|
+
- [ ] 1. 读 .local/state.json(没有则当空)
|
|
54
|
+
- [ ] 2. 无 apiKey → 向用户索取并写入 state(勿把完整 key 打进聊天摘要)
|
|
55
|
+
- [ ] 3. 无 targets 或用户要重置 → 拉空间/KB 列表,让用户多选后写入
|
|
56
|
+
- [ ] 4. 按意图查询(可对多个 KB 逐个查询)
|
|
57
|
+
- [ ] 5. 按模板输出;无命中不编造
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 1–2. API Key
|
|
61
|
+
|
|
62
|
+
若 `state.apiKey` 为空或无效(401/403):
|
|
63
|
+
|
|
64
|
+
1. 请用户提供 API Key(控制台「API 密钥」创建,至少含 `context:read`)。
|
|
65
|
+
2. 可选:请用户确认 `api`(默认 `http://localhost:8090/api`)与 `tenantKey`(默认 `default`)。
|
|
66
|
+
3. 写入 `.local/state.json`(创建目录若不存在)。
|
|
67
|
+
4. 用 `GET $API/health` 探活;再用 `GET $API/v1/spaces?tenantKey=…` + Bearer 校验 key。
|
|
68
|
+
|
|
69
|
+
用户说「换密钥 / 重置 API Key」→ 清空 `apiKey`(可保留 targets),回到本步。
|
|
70
|
+
|
|
71
|
+
### 3. 选择空间与知识库(支持多选)
|
|
72
|
+
|
|
73
|
+
若 `state.targets` 为空,或用户说「重新选择 / 重置空间 / 重置知识库」:
|
|
74
|
+
|
|
75
|
+
1. `GET $API/v1/spaces?tenantKey=$TENANT_KEY`
|
|
76
|
+
2. 对每个相关 space:`GET $API/v1/spaces/{spaceId}/knowledge-bases`
|
|
77
|
+
3. 向用户展示「空间名 / spaceId → KB 名 / kbId」清单,**允许多选**。
|
|
78
|
+
4. 写入 `targets: [{ spaceId, spaceName, spaceKey, kbId, kbName }, …]`。
|
|
79
|
+
5. 仅清空 targets、保留 apiKey 即完成「重置空间和知识库」。
|
|
80
|
+
|
|
81
|
+
查询时:对 `targets` **逐个**调用同一查询,结果按 KB 分组展示。用户若指定「只用某某 KB」,则仅查对应子集。
|
|
82
|
+
|
|
83
|
+
### 4. 查询
|
|
84
|
+
|
|
85
|
+
路径前缀:`/api/v1/spaces/{spaceId}/knowledge-bases/{kbId}`
|
|
86
|
+
所有请求:`-H "Authorization: Bearer $API_KEY"`
|
|
87
|
+
|
|
88
|
+
| 意图 | 调用 |
|
|
89
|
+
|------|------|
|
|
90
|
+
| 开放问题 / 相似事实 | `POST …/context/search` |
|
|
91
|
+
| Continuity / 按外部需求号定位身份 | `POST …/entities/resolve`(带 `externalSystem` / `externalObjectType` / `externalId`;可选 `entityType`) |
|
|
92
|
+
| Spec 复用 / 转换 | `POST …/context/match-requirement`(可带外部三元组与/或 `entityId`) |
|
|
93
|
+
| 对象详情 | `GET …/entities/{id}/current-version` |
|
|
94
|
+
| 一跳结构 | `GET …/entities/{id}/ontology-view` |
|
|
95
|
+
| 多跳影响 | `GET …/entities/{id}/impact` |
|
|
96
|
+
| 原文 | `POST …/context/disclosures`(见 reference) |
|
|
97
|
+
|
|
98
|
+
**机器意图(SDD 流程 Agent)**
|
|
99
|
+
|
|
100
|
+
- Continuity(只要身份、不要 reuseBundles)→ 优先 `POST …/entities/resolve`
|
|
101
|
+
- Spec 复用 → `POST …/context/match-requirement`,带 external 与/或 `entityId`
|
|
102
|
+
- **禁止**扫描消费方本地 `archive/` 目录当跨迭代继承源;历史有效规格以 KB current 为准
|
|
103
|
+
|
|
104
|
+
**search**
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
curl -sS -X POST "$API/v1/spaces/$SPACE_ID/knowledge-bases/$KB_ID/context/search" \
|
|
108
|
+
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
|
|
109
|
+
-d '{"query":"用户登录与会话","entityTypes":[],"limit":15}'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**entities/resolve(外部需求号)**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
curl -sS -X POST "$API/v1/spaces/$SPACE_ID/knowledge-bases/$KB_ID/entities/resolve" \
|
|
116
|
+
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
|
|
117
|
+
-d '{
|
|
118
|
+
"externalSystem":"requirement-mgmt",
|
|
119
|
+
"externalObjectType":"requirement",
|
|
120
|
+
"externalId":"REQ-FI-2024-001",
|
|
121
|
+
"entityType":"Capability"
|
|
122
|
+
}'
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
命中时关注:`resolution=LINK_EXISTING` 且 `inheritanceAllowed=true`(可继承 n);`removedBindingCount`(已失效绑定 m);`matchType=HISTORICAL_ONLY` 表示仅有失效绑定,不可继承。
|
|
126
|
+
|
|
127
|
+
**match-requirement**
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
curl -sS -X POST "$API/v1/spaces/$SPACE_ID/knowledge-bases/$KB_ID/context/match-requirement" \
|
|
131
|
+
-H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
|
|
132
|
+
-d '{
|
|
133
|
+
"query":"用户登录与会话",
|
|
134
|
+
"targetStage":"spec",
|
|
135
|
+
"entityId":"<capability-entity-uuid>",
|
|
136
|
+
"externalSystem":"requirement-mgmt",
|
|
137
|
+
"externalObjectType":"requirement",
|
|
138
|
+
"externalId":"REQ-FI-2024-001"
|
|
139
|
+
}'
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
检索通道:精确/结构 + 全文 + 向量(就绪时)→ RRF →(可选)图谱扩展。看 `degraded` / `degradationReasons`。
|
|
143
|
+
|
|
144
|
+
### 5. 输出模板
|
|
145
|
+
|
|
146
|
+
```markdown
|
|
147
|
+
### 本体查询结论
|
|
148
|
+
- 目标 KB:{spaceName}/{kbName}(可多行)
|
|
149
|
+
- 意图:{复用 | 事实检索 | 影响}
|
|
150
|
+
- 可信度:{高 | 中(降级) | 无命中}
|
|
151
|
+
- 降级:{reasons 或 无}
|
|
152
|
+
|
|
153
|
+
### 命中
|
|
154
|
+
1. **{displayName}**({entityType})@ {kbName}
|
|
155
|
+
- id / version / matchType / externalRefs …
|
|
156
|
+
- 若外部键命中:可继承 n / 已失效绑定 m
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**硬规则**
|
|
160
|
+
|
|
161
|
+
- 无 `apiKey` 不得猜密钥、不得改走 login。
|
|
162
|
+
- 无 `targets` 不得臆造 spaceId/kbId。
|
|
163
|
+
- 无命中 → 写明「无当前依据」,禁止编造条款。
|
|
164
|
+
- 完整 apiKey 只写 state 文件;聊天里最多显示前缀(如 `sk_sdd_****`)。
|
|
165
|
+
|
|
166
|
+
## 用户口令
|
|
167
|
+
|
|
168
|
+
| 用户说 | Agent 做 |
|
|
169
|
+
|--------|----------|
|
|
170
|
+
| (首次使用) | 要 key → 选 KB(多选)→ 再查 |
|
|
171
|
+
| 换密钥 / 重置 API Key | 清 apiKey,重走第 2 步 |
|
|
172
|
+
| 重新选择 / 重置空间或知识库 | 清 targets,重走第 3 步 |
|
|
173
|
+
| 查 / Spec 复用 / 影响… | 用当前 targets 查询 |
|
|
174
|
+
|
|
175
|
+
## 心智模型(简述)
|
|
176
|
+
|
|
177
|
+
- 本体真相在 PG(entity + relation);控制台地图/对象用 SQL 遍历。
|
|
178
|
+
- **外部需求号是确定性身份**;自然语言只产生 REFERENCE 候选,不能自动 sameAs。
|
|
179
|
+
- `context/search` 才是语义检索主通道(+ 可选 AGE 扩邻);跨迭代 Continuity 走 `entities/resolve`。
|
|
180
|
+
- 细节与 state schema → [reference.md](reference.md)。
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# 本体查询 · 参考
|
|
2
|
+
|
|
3
|
+
需要鉴权细节、state 字段或响应字段时再读。
|
|
4
|
+
|
|
5
|
+
## `.local/state.json`
|
|
6
|
+
|
|
7
|
+
路径:`skills/opsx-ontology-query/.local/state.json`(已 gitignore)。
|
|
8
|
+
|
|
9
|
+
```json
|
|
10
|
+
{
|
|
11
|
+
"api": "http://localhost:8090/api",
|
|
12
|
+
"tenantKey": "default",
|
|
13
|
+
"apiKey": "sk_sdd_…",
|
|
14
|
+
"updatedAt": "2026-07-19T12:00:00Z",
|
|
15
|
+
"targets": [
|
|
16
|
+
{
|
|
17
|
+
"spaceId": "uuid",
|
|
18
|
+
"spaceKey": "demo",
|
|
19
|
+
"spaceName": "演示空间",
|
|
20
|
+
"kbId": "uuid",
|
|
21
|
+
"kbName": "默认知识库"
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| 字段 | 必填 | 说明 |
|
|
28
|
+
|------|------|------|
|
|
29
|
+
| `api` | 是 | API 根,含 `/api` |
|
|
30
|
+
| `tenantKey` | 是 | 列空间用;默认 `default` |
|
|
31
|
+
| `apiKey` | 是 | 控制台创建的 `sk_sdd_…`,scope 至少 `context:read` |
|
|
32
|
+
| `targets` | 查询前必填 | 多选;可为空仅当尚未完成选择 |
|
|
33
|
+
| `updatedAt` | 建议 | ISO-8601 |
|
|
34
|
+
|
|
35
|
+
示例(无密钥)见 [state.example.json](state.example.json)。
|
|
36
|
+
|
|
37
|
+
## 鉴权
|
|
38
|
+
|
|
39
|
+
```http
|
|
40
|
+
Authorization: Bearer sk_sdd_…
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
- **不要** `POST /auth/login`。
|
|
44
|
+
- Key 在控制台「API 密钥」创建;创建时勾选 **读取上下文 / context:read**(查询够用)。
|
|
45
|
+
- 401/403:清掉 state 里的 `apiKey`,请用户重贴;勿循环重试。
|
|
46
|
+
|
|
47
|
+
探活与校验:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
curl -sf "$API/health"
|
|
51
|
+
curl -sS -H "Authorization: Bearer $API_KEY" \
|
|
52
|
+
"$API/v1/spaces?tenantKey=$TENANT_KEY"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## 列表接口(选择用)
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# 空间
|
|
59
|
+
GET $API/v1/spaces?tenantKey=$TENANT_KEY
|
|
60
|
+
|
|
61
|
+
# 某空间下 KB
|
|
62
|
+
GET $API/v1/spaces/{spaceId}/knowledge-bases
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
API Key 一般为租户范围;`apiKeySpaceId` 为空时可列出租户下多空间,便于多选。
|
|
66
|
+
|
|
67
|
+
## context/search
|
|
68
|
+
|
|
69
|
+
`POST {base}/context/search`
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{ "query": "string", "entityTypes": [], "limit": 15 }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
| 字段 | 含义 |
|
|
76
|
+
|------|------|
|
|
77
|
+
| `degraded` / `degradationReasons` | 向量/AGE/rerank 等降级 |
|
|
78
|
+
| `results[].matchType` | exact / structural / fulltext / vector / graph … |
|
|
79
|
+
| `results[].entityId` / `entityVersionId` | 溯源 |
|
|
80
|
+
| `results[].scoreExplanation` | RRF channel ranks 等 |
|
|
81
|
+
|
|
82
|
+
## entities/resolve(Continuity / 外部需求号)
|
|
83
|
+
|
|
84
|
+
`POST {base}/entities/resolve`
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"externalSystem": "requirement-mgmt",
|
|
89
|
+
"externalObjectType": "requirement",
|
|
90
|
+
"externalId": "REQ-FI-2024-001",
|
|
91
|
+
"entityType": "Capability"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
也可传 `entityId` / `previousVersionId` / `canonicalKey` / `query`。
|
|
96
|
+
|
|
97
|
+
| 结果 | 含义 |
|
|
98
|
+
|------|------|
|
|
99
|
+
| `resolution=LINK_EXISTING` + `inheritanceAllowed=true` | ≥1 可继承绑定;`candidates` 仅存活实体;`removedBindingCount` 为失效绑定数 |
|
|
100
|
+
| `matchType=HISTORICAL_ONLY` | 有绑定但全部无 current / removed;`inheritanceAllowed=false`,不得当迭代继承 |
|
|
101
|
+
| `NEEDS_CONFIRM` / `SIMILAR_REQUIREMENT` | 名称/结构相似,仅候选 |
|
|
102
|
+
| `NEW_REQUIREMENT` | 无命中 |
|
|
103
|
+
|
|
104
|
+
**禁止**用本地 `archive/` 目录当跨迭代继承源。
|
|
105
|
+
|
|
106
|
+
## context/match-requirement
|
|
107
|
+
|
|
108
|
+
`POST {base}/context/match-requirement`
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"query": "string",
|
|
113
|
+
"targetStage": "spec",
|
|
114
|
+
"limit": 20,
|
|
115
|
+
"entityId": "<uuid>",
|
|
116
|
+
"externalSystem": "requirement-mgmt",
|
|
117
|
+
"externalObjectType": "requirement",
|
|
118
|
+
"externalId": "REQ-…"
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`entityId` / `previousVersionId` / 外部三元组齐全时走 resolve;仅当可继承(非 `HISTORICAL_ONLY`)时组装 `reuseMode=INHERIT` bundles。实体与 statement/AC 上可带 `externalRefs`。
|
|
123
|
+
|
|
124
|
+
| matchType | 含义 |
|
|
125
|
+
|-----------|------|
|
|
126
|
+
| `SAME_ITERATION` | 已对齐同一实体 |
|
|
127
|
+
| `HISTORICAL_ONLY` | 外部键仅有失效绑定,不可继承 |
|
|
128
|
+
| `SIMILAR_REQUIREMENT` | 可作复用候选 |
|
|
129
|
+
| `NEEDS_CONFIRM` | 需人确认 |
|
|
130
|
+
| `NEW_REQUIREMENT` | 无可信复用 |
|
|
131
|
+
|
|
132
|
+
## 对象读
|
|
133
|
+
|
|
134
|
+
| 方法 | 路径 |
|
|
135
|
+
|------|------|
|
|
136
|
+
| GET | `/entities?type=&q=&page=&size=` |
|
|
137
|
+
| GET | `/entities/{id}/current-version` |
|
|
138
|
+
| GET | `/entities/{id}/lineage` |
|
|
139
|
+
| GET | `/entities/{id}/ontology-view` |
|
|
140
|
+
| GET | `/entities/{id}/impact` |
|
|
141
|
+
|
|
142
|
+
`impact` / `ontology-view` 走 PG 关系;与 `context/search` 不同链路。
|
|
143
|
+
|
|
144
|
+
## disclosures
|
|
145
|
+
|
|
146
|
+
`POST {base}/context/disclosures`
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"anchorId": "STMT-…",
|
|
151
|
+
"entityId": null,
|
|
152
|
+
"entityVersionId": null,
|
|
153
|
+
"level": "preview"
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`level`:`preview` | `section` | `document`。
|
|
@@ -3,10 +3,11 @@ name: opsx-propose
|
|
|
3
3
|
description: "业务意图文档技能 - 引导创建 proposal.md,定义变更的 Why 和上下文总览"
|
|
4
4
|
argument-hint: "[change-name] [上下文文件...]"
|
|
5
5
|
license: MIT
|
|
6
|
-
compatibility: Requires openspec CLI.
|
|
6
|
+
compatibility: Requires openspec CLI; depends on opsx-ontology-query.
|
|
7
7
|
metadata:
|
|
8
8
|
author: sdd-team
|
|
9
9
|
version: "3.0"
|
|
10
|
+
depends-on: opsx-ontology-query
|
|
10
11
|
allowed-tools:
|
|
11
12
|
- Bash
|
|
12
13
|
- Read
|
|
@@ -16,6 +17,8 @@ allowed-tools:
|
|
|
16
17
|
|
|
17
18
|
你是一个 SDD(Specification-Driven Development)业务意图文档专家。激活本技能后,你将引导用户创建符合质量红线标准的 **proposal.md** 文档。
|
|
18
19
|
|
|
20
|
+
> **硬依赖**:本技能 Continuity 步骤依赖同级已部署的 **`opsx-ontology-query`**。启动 Continuity 前必须先 `Read` 该技能的 `SKILL.md`,并按其中流程准备 `.local/state.json`(API Key + targets)。若项目 skills 目录中不存在 `opsx-ontology-query/`,停止 Continuity,提示用户重新执行 `kld-sdd-init`;**禁止**用本地 `archive/` 冒充查询。
|
|
21
|
+
|
|
19
22
|
> **⚠️ 阶段边界约束**
|
|
20
23
|
>
|
|
21
24
|
> 当前处于 **Propose(规划)阶段**:
|
|
@@ -159,6 +162,28 @@ openspec instructions proposal --change "<name>" --json
|
|
|
159
162
|
|
|
160
163
|
> 完整性检查(问题描述/目标/模块/约束 4 项)与缺失补充机制见 `./checklist.md`「§6 需求完整性检查」。发现缺失时主动询问用户补充。
|
|
161
164
|
|
|
165
|
+
### 6.5 【Continuity】需求 / Capability 身份(只到 CAP,不做场景)
|
|
166
|
+
|
|
167
|
+
在创建变更目录之后、写 proposal 能力列表之前(或紧接 CAP 编号分配前):
|
|
168
|
+
|
|
169
|
+
1. 提取 / 询问外部需求号 `REQ-*`(没有则问一次)。
|
|
170
|
+
2. **先加载依赖技能**:确认 `${AGENT_SKILL_DIR}/opsx-ontology-query/SKILL.md`(或当前编辑器等价 skills 路径)存在并 Read;按该技能完成 API Key / 空间与 KB 选择(写入其 `.local/state.json`)。未安装则停止本步。
|
|
171
|
+
3. 调用知识库 **`opsx-ontology-query`**(权威);可用薄封装,但契约以该技能为准:
|
|
172
|
+
```bash
|
|
173
|
+
node skywalk-sdd/context-client.cjs --mode=resolve \
|
|
174
|
+
--external-system=requirement-mgmt \
|
|
175
|
+
--external-object-type=requirement \
|
|
176
|
+
--external-id="<REQ-...>" \
|
|
177
|
+
--entity-type=Capability \
|
|
178
|
+
--space-id="$ENGINEERING_KB_SPACE_ID" \
|
|
179
|
+
--kb-id="$ENGINEERING_KB_KB_ID"
|
|
180
|
+
```
|
|
181
|
+
4. 按 KB 结果确认 Continuity:`iteration` / `similar-reference` / `new`;勾选本次涉及的 CAP。
|
|
182
|
+
5. 写入 proposal frontmatter:`requirement-refs` + `continuity`(字段来自 KB:`kb-space-id` / `kb-id` / `base-capabilities[].entity-id` / `current-version-id`)。**禁止**写本地 archive 文件夹名作为 `base-archive`。
|
|
183
|
+
6. CAP 级「同 key + 同锚点、不同 entity_id」当场问 A/B/C;决议写入 `openspec/changes/<name>/continuity-resolution.json` 的 `capabilities[]`。
|
|
184
|
+
7. KB 不可用 → `degraded` 继续,**禁止**扫本地 `archive/` 抄 UUID。预期:恢复后同锚点入库可能触发 `EXTERNAL_REF_CONFLICT`。
|
|
185
|
+
8. **不得**在本阶段生成 STMT/AC/场景或裁决场景身份。
|
|
186
|
+
|
|
162
187
|
### 7. 【交互引导】文档拆分模式选择
|
|
163
188
|
|
|
164
189
|
**❗ 必须主动询问用户,不得默认选择**。Full / Simple / Auto 三种模式的目录结构、适用场景与 AskUserQuestion 文案见 `./reference.md`「§7 文档拆分模式选择」。根据用户选择设置 `mode: full | simple`(Auto 按能力域数量判断),记录到 proposal.md 的 YAML frontmatter。
|
|
@@ -3,10 +3,11 @@ name: opsx-spec
|
|
|
3
3
|
description: "技术契约文档技能 - 为每个能力创建 spec.md,定义业务场景与技术规范"
|
|
4
4
|
argument-hint: "[change-name] [上下文文件...]"
|
|
5
5
|
license: MIT
|
|
6
|
-
compatibility: Requires openspec CLI.
|
|
6
|
+
compatibility: Requires openspec CLI; depends on opsx-ontology-query.
|
|
7
7
|
metadata:
|
|
8
8
|
author: sdd-team
|
|
9
9
|
version: "3.0"
|
|
10
|
+
depends-on: opsx-ontology-query
|
|
10
11
|
allowed-tools:
|
|
11
12
|
- Bash
|
|
12
13
|
- Read
|
|
@@ -16,6 +17,8 @@ allowed-tools:
|
|
|
16
17
|
|
|
17
18
|
你是一个 SDD(Specification-Driven Development)技术契约专家。激活本技能后,你将引导用户为每个 Capability 创建 **spec.md** 文档。
|
|
18
19
|
|
|
20
|
+
> **硬依赖**:场景身份 / Spec 复用依赖同级已部署的 **`opsx-ontology-query`**。进入知识库上下文步骤前必须先 `Read` 该技能的 `SKILL.md` 并完成其 Session 启动(API Key + targets)。缺失则停止复用查询,提示重新 `kld-sdd-init`;**禁止**从本地 `archive/` 抄 UUID。
|
|
21
|
+
|
|
19
22
|
> **⚠️ 阶段边界约束**
|
|
20
23
|
>
|
|
21
24
|
> 当前处于 **Spec(契约)阶段**:
|
|
@@ -107,21 +110,32 @@ openspec list
|
|
|
107
110
|
|
|
108
111
|
> 上下文类型(需求文档 / 代码文件 / API 文档)与用途见 `./reference.md`「§3 上下文类型与用途」。
|
|
109
112
|
|
|
110
|
-
**【默认尝试】工程 Spec
|
|
113
|
+
**【默认尝试】工程 Spec 知识库上下文(场景身份主战场)**:
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
1. **先加载依赖技能**:确认 `${AGENT_SKILL_DIR}/opsx-ontology-query/SKILL.md` 存在并 Read;按该技能完成 API Key / targets(`.local/state.json`)。未安装则停止本步。
|
|
116
|
+
2. 读取 proposal Continuity。对**当前 Capability** 各调一次(「全部」= 循环 N 次,不是一次大查询)——优先走 **`opsx-ontology-query`** 的 `match-requirement`;薄封装仅作参数拼装:
|
|
113
117
|
|
|
114
118
|
```bash
|
|
115
|
-
node skywalk-sdd/context-client.cjs
|
|
119
|
+
node skywalk-sdd/context-client.cjs \
|
|
120
|
+
--query="<当前 Capability 的自然语言需求>" \
|
|
121
|
+
--target-stage=spec \
|
|
122
|
+
--entity-id="<该 CAP 的 entity_id>" \
|
|
123
|
+
--external-system=requirement-mgmt \
|
|
124
|
+
--external-object-type=requirement \
|
|
125
|
+
--external-id="<REQ-...>" \
|
|
126
|
+
--space-id="$ENGINEERING_KB_SPACE_ID" \
|
|
127
|
+
--kb-id="$ENGINEERING_KB_KB_ID"
|
|
116
128
|
```
|
|
117
129
|
|
|
118
|
-
- 配置项:`ENGINEERING_KB_API`、`ENGINEERING_KB_SPACE_ID`、可选 `ENGINEERING_KB_TOKEN
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
- `
|
|
122
|
-
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
130
|
+
- 配置项:`ENGINEERING_KB_API`、`ENGINEERING_KB_SPACE_ID`、`ENGINEERING_KB_KB_ID`、可选 `ENGINEERING_KB_TOKEN`。查询权威技能是 **`opsx-ontology-query`**;本脚本只是薄封装。
|
|
131
|
+
- Continuity=`iteration` 时**必须**带 `--entity-id` + external。
|
|
132
|
+
- **禁止**从本地 `archive/` 抄 UUID 当跨迭代继承源;跨迭代只认 KB current。
|
|
133
|
+
- 若返回 `available=false` / `degraded=true`,记录降级并继续,不得扫本地 archive 兜底。
|
|
134
|
+
- `INHERIT`:unchanged 写继承引用;modified 复用 entity-id + predecessor。`REFERENCE`:只参考,新开身份。
|
|
135
|
+
- reuseBundle / 实体上的 `externalRefs` 写入场景 `external-ref`(`requirement-mgmt:scenario:REQ-…:SCN-…`)。
|
|
136
|
+
- 场景级「同 SCN key + 同锚点、不同 entity_id」在写完该 CAP identity 后、确认文档前**当场问** A/B/C;未决不得进入下一 CAP / design。决议追加到 `continuity-resolution.json` 的 `scenarios[]`。
|
|
137
|
+
- 优先消费 `reuseBundles[].statements`;`designElements` 只作理解上下文,不能写成 Spec 的 How。
|
|
138
|
+
- 所有知识库内容均为 advisory;与用户确认 / proposal 冲突时以当前确认与 proposal 为准。
|
|
125
139
|
|
|
126
140
|
**【可选】业务知识库检索**:
|
|
127
141
|
术语含义不清且可能影响 spec 准确性时,可调用 **opsx-knowledge** skill。
|
|
@@ -203,7 +217,7 @@ node skywalk-sdd/context-client.cjs --query="<当前 Capability 的自然语言
|
|
|
203
217
|
- 新需求、场景和约束分别使用 `STMT-*`、`AC-*`、`CON-*`;分配规则是同前缀同 Capability 当前最大序号 + 1。
|
|
204
218
|
- 修改已有实体必须复用原 ID;删除实体只写 removal 语义,不得把编号分配给新实体。
|
|
205
219
|
- `added` 必须调用 `semantic-identity --delta-state=added` 生成新的实体 UUID 和版本 UUID;禁止通过复制另一需求的 UUID 创建新实体。
|
|
206
|
-
- `modified/removed` 必须从
|
|
220
|
+
- `modified/removed` 必须从 **KB**(match-requirement / resolve)取得历史 `entity-id` 和直接前序 `version-id`,调用 `semantic-identity --delta-state=<modified|removed> --entity-id=<UUID> --predecessor-version=<UUID>`;实体 UUID 复用,版本 UUID 新建。禁止把本地 archive 目录当跨迭代继承权威。
|
|
207
221
|
- AC 必须嵌套在所属 STMT 下;CON 必须通过 `**constrains**` 显式引用 STMT。
|
|
208
222
|
- 对 `reuseMode=REFERENCE` 的历史候选必须创建新的实体身份;禁止因为内容相似而复用历史 `entity-id`。
|
|
209
223
|
- 对 `reuseMode=INHERIT` 的历史事实,必须使用返回的实体与版本来源完成 unchanged/modified 身份参数校验。
|