archgraph-argo 0.26.2 → 0.27.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.
@@ -1,254 +1,261 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const {
5
- getArgoRoot,
6
- getWorkspaceRoot,
7
- } = require('./argo-paths.js');
8
-
9
- const repoRoot = getWorkspaceRoot();
10
- const graphRelativePath = path.join('design', 'KG', 'SystemArchitecture.json');
11
- const graphPath = path.join(repoRoot, graphRelativePath);
12
- const schemaPathCandidates = [
13
- path.join(getArgoRoot(), 'schema', 'SystemArchitecture.schema.json'),
14
- path.join(repoRoot, '.argo', 'schema', 'SystemArchitecture.schema.json'),
15
- ];
16
-
17
- const {
18
- validateGraphSemantics,
19
- validateArchiMateEndpointMatrix,
20
- validateViewElementLimits,
21
- } = require('./graph-semantics.js');
22
-
23
- function main() {
24
- const schemaPath = schemaPathCandidates.find(candidate => fs.existsSync(candidate));
25
- if (!schemaPath) {
26
- fail(`Schema file is missing. Checked: ${schemaPathCandidates.map(candidate => path.relative(repoRoot, candidate)).join(', ')}`);
27
- }
28
-
29
- if (!fs.existsSync(graphPath)) {
30
- fail('System architecture file is missing at design/KG/SystemArchitecture.json');
31
- }
32
-
33
- const schema = parseJson(schemaPath, path.relative(repoRoot, schemaPath));
34
- const document = parseJson(graphPath, 'design/KG/SystemArchitecture.json');
35
- const errors = [];
36
-
37
- validateAgainstSchema(document, schema, '#', errors, schema);
38
- validateGraphSemantics(document, errors);
39
- validateArchiMateEndpointMatrix(document, errors);
40
- validateViewElementLimits(document, errors);
41
-
42
- if (errors.length > 0) {
43
- console.error('SystemArchitecture validation failed:');
44
- for (const error of errors) {
45
- console.error(`- ${error}`);
46
- }
47
- process.exit(1);
48
- }
49
-
50
- console.log('SystemArchitecture validation passed for: design/KG/SystemArchitecture.json');
51
- }
52
-
53
- function parseJson(filePath, label) {
54
- try {
55
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
56
- } catch (error) {
57
- fail(`Failed to parse ${label}: ${String(error)}`);
58
- }
59
- }
60
-
61
- function validateAgainstSchema(value, schemaNode, pointer, errors, rootSchema) {
62
- if (!schemaNode || typeof schemaNode !== 'object') {
63
- return;
64
- }
65
-
66
- const resolvedSchema = schemaNode.$ref ? resolveRef(schemaNode.$ref, rootSchema, errors, pointer) : schemaNode;
67
- if (!resolvedSchema) {
68
- return;
69
- }
70
-
71
- if (resolvedSchema.const !== undefined && !isDeepStrictEqual(value, resolvedSchema.const)) {
72
- errors.push(`${pointer} must equal ${JSON.stringify(resolvedSchema.const)}`);
73
- return;
74
- }
75
-
76
- if (resolvedSchema.enum && !resolvedSchema.enum.some(option => isDeepStrictEqual(option, value))) {
77
- errors.push(`${pointer} must be one of: ${resolvedSchema.enum.map(option => JSON.stringify(option)).join(', ')}`);
78
- return;
79
- }
80
-
81
- if (resolvedSchema.type !== undefined) {
82
- validateType(value, resolvedSchema.type, pointer, errors);
83
- if (!typeMatches(value, resolvedSchema.type)) {
84
- return;
85
- }
86
- }
87
-
88
- if (typeof resolvedSchema.minLength === 'number') {
89
- if (typeof value !== 'string' || value.length < resolvedSchema.minLength) {
90
- errors.push(`${pointer} must be at least ${resolvedSchema.minLength} character(s) long`);
91
- }
92
- }
93
-
94
- if (typeof resolvedSchema.maxLength === 'number') {
95
- if (typeof value !== 'string' || value.length > resolvedSchema.maxLength) {
96
- errors.push(`${pointer} must be at most ${resolvedSchema.maxLength} character(s) long`);
97
- }
98
- }
99
-
100
- if (resolvedSchema.pattern) {
101
- const matcher = new RegExp(resolvedSchema.pattern);
102
- if (typeof value !== 'string' || !matcher.test(value)) {
103
- errors.push(`${pointer} must match pattern ${JSON.stringify(resolvedSchema.pattern)}`);
104
- }
105
- }
106
-
107
- if (typeof resolvedSchema.minimum === 'number') {
108
- if (typeof value !== 'number' || value < resolvedSchema.minimum) {
109
- errors.push(`${pointer} must be >= ${resolvedSchema.minimum}`);
110
- }
111
- }
112
-
113
- if (typeof resolvedSchema.maximum === 'number') {
114
- if (typeof value !== 'number' || value > resolvedSchema.maximum) {
115
- errors.push(`${pointer} must be <= ${resolvedSchema.maximum}`);
116
- }
117
- }
118
-
119
- if (typeof resolvedSchema.minItems === 'number') {
120
- if (!Array.isArray(value) || value.length < resolvedSchema.minItems) {
121
- errors.push(`${pointer} must contain at least ${resolvedSchema.minItems} item(s)`);
122
- }
123
- }
124
-
125
- if (typeof resolvedSchema.maxItems === 'number') {
126
- if (!Array.isArray(value) || value.length > resolvedSchema.maxItems) {
127
- errors.push(`${pointer} must contain at most ${resolvedSchema.maxItems} item(s)`);
128
- }
129
- }
130
-
131
- if (resolvedSchema.uniqueItems === true && Array.isArray(value)) {
132
- const seen = new Set();
133
- value.forEach((entry, index) => {
134
- const serialized = JSON.stringify(entry);
135
- if (seen.has(serialized)) {
136
- errors.push(`${pointer}[${index}] must be unique within ${pointer}`);
137
- } else {
138
- seen.add(serialized);
139
- }
140
- });
141
- }
142
-
143
- if (resolvedSchema.type === 'object') {
144
- validateObject(value, resolvedSchema, pointer, errors, rootSchema);
145
- return;
146
- }
147
-
148
- if (resolvedSchema.type === 'array') {
149
- validateArray(value, resolvedSchema, pointer, errors, rootSchema);
150
- }
151
- }
152
-
153
- function validateObject(value, schemaNode, pointer, errors, rootSchema) {
154
- if (!value || typeof value !== 'object' || Array.isArray(value)) {
155
- return;
156
- }
157
-
158
- const properties = schemaNode.properties || {};
159
- const required = Array.isArray(schemaNode.required) ? schemaNode.required : [];
160
-
161
- for (const key of required) {
162
- if (!(key in value)) {
163
- errors.push(`${pointer} is missing required property '${key}'`);
164
- }
165
- }
166
-
167
- if (schemaNode.additionalProperties === false) {
168
- for (const key of Object.keys(value)) {
169
- if (!(key in properties)) {
170
- errors.push(`${pointer} contains unsupported property '${key}'`);
171
- }
172
- }
173
- }
174
-
175
- for (const [key, propertySchema] of Object.entries(properties)) {
176
- if (key in value) {
177
- validateAgainstSchema(value[key], propertySchema, `${pointer}.${key}`, errors, rootSchema);
178
- }
179
- }
180
- }
181
-
182
- function validateArray(value, schemaNode, pointer, errors, rootSchema) {
183
- if (!Array.isArray(value)) {
184
- return;
185
- }
186
-
187
- if (schemaNode.items) {
188
- value.forEach((entry, index) => {
189
- validateAgainstSchema(entry, schemaNode.items, `${pointer}[${index}]`, errors, rootSchema);
190
- });
191
- }
192
- }
193
-
194
- function validateType(value, expectedType, pointer, errors) {
195
- if (!typeMatches(value, expectedType)) {
196
- const printableType = Array.isArray(expectedType) ? expectedType.join(' or ') : expectedType;
197
- errors.push(`${pointer} must be of type ${printableType}`);
198
- }
199
- }
200
-
201
- function typeMatches(value, expectedType) {
202
- if (Array.isArray(expectedType)) {
203
- return expectedType.some(candidate => typeMatches(value, candidate));
204
- }
205
-
206
- switch (expectedType) {
207
- case 'object':
208
- return value !== null && typeof value === 'object' && !Array.isArray(value);
209
- case 'array':
210
- return Array.isArray(value);
211
- case 'string':
212
- return typeof value === 'string';
213
- case 'number':
214
- return typeof value === 'number' && Number.isFinite(value);
215
- case 'integer':
216
- return typeof value === 'number' && Number.isInteger(value);
217
- case 'boolean':
218
- return typeof value === 'boolean';
219
- case 'null':
220
- return value === null;
221
- default:
222
- return true;
223
- }
224
- }
225
-
226
- function resolveRef(ref, rootSchema, errors, pointer) {
227
- if (!ref.startsWith('#/')) {
228
- errors.push(`${pointer} uses unsupported $ref '${ref}'`);
229
- return undefined;
230
- }
231
-
232
- const segments = ref.slice(2).split('/');
233
- let current = rootSchema;
234
- for (const segment of segments) {
235
- if (!current || typeof current !== 'object' || !(segment in current)) {
236
- errors.push(`${pointer} references missing schema path '${ref}'`);
237
- return undefined;
238
- }
239
- current = current[segment];
240
- }
241
-
242
- return current;
243
- }
244
-
245
- function isDeepStrictEqual(left, right) {
246
- return JSON.stringify(left) === JSON.stringify(right);
247
- }
248
-
249
- function fail(message) {
250
- console.error(`SystemArchitecture validation failed: ${message}`);
251
- process.exit(1);
252
- }
253
-
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const {
5
+ getWorkspaceRoot,
6
+ } = require('./argo-paths.js');
7
+
8
+ const {
9
+ loadSchemaBundleAndOntology,
10
+ } = require('./argob-schema.js');
11
+
12
+ const repoRoot = getWorkspaceRoot();
13
+ const graphRelativePath = path.join('design', 'KG', 'SystemArchitecture.json');
14
+ const graphPath = path.join(repoRoot, graphRelativePath);
15
+
16
+ const {
17
+ validateGraphSemantics,
18
+ validateArchiMateEndpointMatrix,
19
+ validateViewElementLimits,
20
+ } = require('./graph-semantics.js');
21
+
22
+ function main() {
23
+ let bundle;
24
+ let ontology;
25
+ try {
26
+ ({ bundle, ontology } = loadSchemaBundleAndOntology(repoRoot));
27
+ } catch (error) {
28
+ fail(String(error && error.message ? error.message : error));
29
+ }
30
+ const schema = bundle.schemaDocument;
31
+
32
+ if (!fs.existsSync(graphPath)) {
33
+ fail('System architecture file is missing at design/KG/SystemArchitecture.json');
34
+ }
35
+
36
+ const document = parseJson(graphPath, 'design/KG/SystemArchitecture.json');
37
+ const errors = [];
38
+
39
+ if (ontology.bundleValidation && ontology.bundleValidation.status === 'failed') {
40
+ for (const error of ontology.bundleValidation.errors) {
41
+ errors.push(`schema bundle: ${error}`);
42
+ }
43
+ }
44
+ validateAgainstSchema(document, schema, '#', errors, schema);
45
+ validateGraphSemantics(document, errors, ontology);
46
+ validateArchiMateEndpointMatrix(document, errors, { ontology });
47
+ validateViewElementLimits(document, errors, { ontology });
48
+
49
+ if (errors.length > 0) {
50
+ console.error(`SystemArchitecture validation failed [schema: ${bundle.kind} / ${ontology.language}]:`);
51
+ for (const error of errors) {
52
+ console.error(`- ${error}`);
53
+ }
54
+ process.exit(1);
55
+ }
56
+
57
+ console.log(`SystemArchitecture validation passed for: design/KG/SystemArchitecture.json [schema: ${bundle.kind} / ${ontology.language}]`);
58
+ }
59
+
60
+ function parseJson(filePath, label) {
61
+ try {
62
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
63
+ } catch (error) {
64
+ fail(`Failed to parse ${label}: ${String(error)}`);
65
+ }
66
+ }
67
+
68
+ function validateAgainstSchema(value, schemaNode, pointer, errors, rootSchema) {
69
+ if (!schemaNode || typeof schemaNode !== 'object') {
70
+ return;
71
+ }
72
+
73
+ const resolvedSchema = schemaNode.$ref ? resolveRef(schemaNode.$ref, rootSchema, errors, pointer) : schemaNode;
74
+ if (!resolvedSchema) {
75
+ return;
76
+ }
77
+
78
+ if (resolvedSchema.const !== undefined && !isDeepStrictEqual(value, resolvedSchema.const)) {
79
+ errors.push(`${pointer} must equal ${JSON.stringify(resolvedSchema.const)}`);
80
+ return;
81
+ }
82
+
83
+ if (resolvedSchema.enum && !resolvedSchema.enum.some(option => isDeepStrictEqual(option, value))) {
84
+ errors.push(`${pointer} must be one of: ${resolvedSchema.enum.map(option => JSON.stringify(option)).join(', ')}`);
85
+ return;
86
+ }
87
+
88
+ if (resolvedSchema.type !== undefined) {
89
+ validateType(value, resolvedSchema.type, pointer, errors);
90
+ if (!typeMatches(value, resolvedSchema.type)) {
91
+ return;
92
+ }
93
+ }
94
+
95
+ if (typeof resolvedSchema.minLength === 'number') {
96
+ if (typeof value !== 'string' || value.length < resolvedSchema.minLength) {
97
+ errors.push(`${pointer} must be at least ${resolvedSchema.minLength} character(s) long`);
98
+ }
99
+ }
100
+
101
+ if (typeof resolvedSchema.maxLength === 'number') {
102
+ if (typeof value !== 'string' || value.length > resolvedSchema.maxLength) {
103
+ errors.push(`${pointer} must be at most ${resolvedSchema.maxLength} character(s) long`);
104
+ }
105
+ }
106
+
107
+ if (resolvedSchema.pattern) {
108
+ const matcher = new RegExp(resolvedSchema.pattern);
109
+ if (typeof value !== 'string' || !matcher.test(value)) {
110
+ errors.push(`${pointer} must match pattern ${JSON.stringify(resolvedSchema.pattern)}`);
111
+ }
112
+ }
113
+
114
+ if (typeof resolvedSchema.minimum === 'number') {
115
+ if (typeof value !== 'number' || value < resolvedSchema.minimum) {
116
+ errors.push(`${pointer} must be >= ${resolvedSchema.minimum}`);
117
+ }
118
+ }
119
+
120
+ if (typeof resolvedSchema.maximum === 'number') {
121
+ if (typeof value !== 'number' || value > resolvedSchema.maximum) {
122
+ errors.push(`${pointer} must be <= ${resolvedSchema.maximum}`);
123
+ }
124
+ }
125
+
126
+ if (typeof resolvedSchema.minItems === 'number') {
127
+ if (!Array.isArray(value) || value.length < resolvedSchema.minItems) {
128
+ errors.push(`${pointer} must contain at least ${resolvedSchema.minItems} item(s)`);
129
+ }
130
+ }
131
+
132
+ if (typeof resolvedSchema.maxItems === 'number') {
133
+ if (!Array.isArray(value) || value.length > resolvedSchema.maxItems) {
134
+ errors.push(`${pointer} must contain at most ${resolvedSchema.maxItems} item(s)`);
135
+ }
136
+ }
137
+
138
+ if (resolvedSchema.uniqueItems === true && Array.isArray(value)) {
139
+ const seen = new Set();
140
+ value.forEach((entry, index) => {
141
+ const serialized = JSON.stringify(entry);
142
+ if (seen.has(serialized)) {
143
+ errors.push(`${pointer}[${index}] must be unique within ${pointer}`);
144
+ } else {
145
+ seen.add(serialized);
146
+ }
147
+ });
148
+ }
149
+
150
+ if (resolvedSchema.type === 'object') {
151
+ validateObject(value, resolvedSchema, pointer, errors, rootSchema);
152
+ return;
153
+ }
154
+
155
+ if (resolvedSchema.type === 'array') {
156
+ validateArray(value, resolvedSchema, pointer, errors, rootSchema);
157
+ }
158
+ }
159
+
160
+ function validateObject(value, schemaNode, pointer, errors, rootSchema) {
161
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
162
+ return;
163
+ }
164
+
165
+ const properties = schemaNode.properties || {};
166
+ const required = Array.isArray(schemaNode.required) ? schemaNode.required : [];
167
+
168
+ for (const key of required) {
169
+ if (!(key in value)) {
170
+ errors.push(`${pointer} is missing required property '${key}'`);
171
+ }
172
+ }
173
+
174
+ if (schemaNode.additionalProperties === false) {
175
+ for (const key of Object.keys(value)) {
176
+ if (!(key in properties)) {
177
+ errors.push(`${pointer} contains unsupported property '${key}'`);
178
+ }
179
+ }
180
+ }
181
+
182
+ for (const [key, propertySchema] of Object.entries(properties)) {
183
+ if (key in value) {
184
+ validateAgainstSchema(value[key], propertySchema, `${pointer}.${key}`, errors, rootSchema);
185
+ }
186
+ }
187
+ }
188
+
189
+ function validateArray(value, schemaNode, pointer, errors, rootSchema) {
190
+ if (!Array.isArray(value)) {
191
+ return;
192
+ }
193
+
194
+ if (schemaNode.items) {
195
+ value.forEach((entry, index) => {
196
+ validateAgainstSchema(entry, schemaNode.items, `${pointer}[${index}]`, errors, rootSchema);
197
+ });
198
+ }
199
+ }
200
+
201
+ function validateType(value, expectedType, pointer, errors) {
202
+ if (!typeMatches(value, expectedType)) {
203
+ const printableType = Array.isArray(expectedType) ? expectedType.join(' or ') : expectedType;
204
+ errors.push(`${pointer} must be of type ${printableType}`);
205
+ }
206
+ }
207
+
208
+ function typeMatches(value, expectedType) {
209
+ if (Array.isArray(expectedType)) {
210
+ return expectedType.some(candidate => typeMatches(value, candidate));
211
+ }
212
+
213
+ switch (expectedType) {
214
+ case 'object':
215
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
216
+ case 'array':
217
+ return Array.isArray(value);
218
+ case 'string':
219
+ return typeof value === 'string';
220
+ case 'number':
221
+ return typeof value === 'number' && Number.isFinite(value);
222
+ case 'integer':
223
+ return typeof value === 'number' && Number.isInteger(value);
224
+ case 'boolean':
225
+ return typeof value === 'boolean';
226
+ case 'null':
227
+ return value === null;
228
+ default:
229
+ return true;
230
+ }
231
+ }
232
+
233
+ function resolveRef(ref, rootSchema, errors, pointer) {
234
+ if (!ref.startsWith('#/')) {
235
+ errors.push(`${pointer} uses unsupported $ref '${ref}'`);
236
+ return undefined;
237
+ }
238
+
239
+ const segments = ref.slice(2).split('/');
240
+ let current = rootSchema;
241
+ for (const segment of segments) {
242
+ if (!current || typeof current !== 'object' || !(segment in current)) {
243
+ errors.push(`${pointer} references missing schema path '${ref}'`);
244
+ return undefined;
245
+ }
246
+ current = current[segment];
247
+ }
248
+
249
+ return current;
250
+ }
251
+
252
+ function isDeepStrictEqual(left, right) {
253
+ return JSON.stringify(left) === JSON.stringify(right);
254
+ }
255
+
256
+ function fail(message) {
257
+ console.error(`SystemArchitecture validation failed: ${message}`);
258
+ process.exit(1);
259
+ }
260
+
254
261
  main();
@@ -26,7 +26,7 @@ const SCRIPT_CANDIDATES = {
26
26
  const TOOLS = [
27
27
  {
28
28
  name: 'validateSystemArchitecture',
29
- description: 'Validate design/KG/SystemArchitecture.json against .argo/schema/SystemArchitecture.schema.json and Argo graph rules.',
29
+ description: 'Validate design/KG/SystemArchitecture.json against the workspace-resolved schema bundle (the default ArgoBument schema, or the repository\'s own .argo/schema) and Argo graph rules.',
30
30
  inputSchema: {
31
31
  type: 'object',
32
32
  properties: {},
@@ -17,10 +17,12 @@ disable-model-invocation: true
17
17
  ## Rules
18
18
 
19
19
  - **MUST** 调用 ARGO MCP 工具 `initializeWorkspace`(传当前工作区根)执行确定性初始化,并以其返回报告为最终判断依据。
20
+ - **MUST** 报告当前 schema:`initializeWorkspace` 返回的 `schema`(或 harness 的 `schemaBundle`)中的 `kind`(default=内置 ArgoBument / workspace=仓内自定义 / override)、`language`(名称)、`actorElementType`、`dir`、`guide`;输出形如 `schema: default / ArchiMate 3.2`。
20
21
  - **MUST** 报告 `mcp` / `systemArchitecture` / `neo4j` / `qeaFullProjection` / `semanticLifecycle` / `subdiagramViews` 与整体 `status`。
21
22
  - **MUST** 核验并报告:① `.qea` 投影是否成功(`qeaFullProjection.status`),且投影目标 `qeaFullProjection.qea` 是否为**本仓库自己的 .qea 文件**(解析自 `ARGO_EA_QEA` 或仓库根唯一 `*.qea`);目标不是本仓库文件或投影失败 → 报告为告警/失败,不得视为 init 成功。
22
23
  - **MUST** 核验并报告:Neo4j 投影目标数据库名(`neo4j.database`)是否**与本仓库名一致**(仓库 basename == 数据库名);不一致 → 报告为告警/失败。
23
- - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在、ACL 主体。
24
+ - **MUST NOT** 因 schema 是自定义的而跳过 `.qea` 投影:投影对任何 schema 都执行;只有确实没有 `.qea` 目标时才允许 `noop`。
25
+ - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在。
24
26
  - **MUST NOT** 通过 shell 手工执行 WORKSPACE 外的初始化脚本或一组无关命令来替代 `initializeWorkspace`(除非报告显示底层脚本自身失败需要排查)。
25
27
 
26
28
  ## Workflow
@@ -47,18 +49,13 @@ disable-model-invocation: true
47
49
 
48
50
  ### 3. Handle Secret File Blockers(仅当报告含 secret 相关失败)
49
51
 
50
- `semanticLifecycle` 或 `systemArchitecture` 失败可能源于 `.env` 安全预检。诊断(不打印 secret 值):
52
+ `semanticLifecycle` 或 `systemArchitecture` 失败可能源于 `.env` 预检。诊断(不打印 secret 值):
51
53
 
52
- ```powershell
53
- icacls "$env:USERPROFILE\.argo\.env"
54
- ```
54
+ 处理规则(env 文件不做 OS ACL / 权限加固;只保证不被提交):
55
55
 
56
- 处理规则:
57
-
58
- - `SECRET_FILE_ACL_UNSAFE`:收紧 Windows ACL,只保留当前用户、Administrators、SYSTEM。
59
56
  - `SECRET_FILE_REPARSE_PROHIBITED`:将 `.env` 替换为普通文件(去掉符号链接/重解析点)。
60
57
  - `SECRET_FILE_PATH_PROHIBITED`:修正 `ARGO_ENV_FILE` 与安装根 `.env` 不一致的路径。
61
- - git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`)只在 `.env` 位于 git 仓库内时出现;全局 `.env` 位于仓库外时天然不适用。
58
+ - git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`):把 `.env` 加入 `.gitignore` 并 `git rm --cached`;全局 `.env` 位于仓库外时天然不适用。
62
59
 
63
60
  修复后重跑 `initializeWorkspace`。
64
61
 
@@ -72,6 +69,7 @@ icacls "$env:USERPROFILE\.argo\.env"
72
69
 
73
70
  ### 1. Environment Status
74
71
  - overall status: ok / failed
72
+ - **解析到的 schema:kind(default/workspace/override)+ language(名称)+ actorElementType + dir/guide**(默认 ArgoBument 还是仓内自定义 schema)
75
73
  - whether mcp health passed
76
74
  - whether neo4j health passed
77
75
  - whether .qea full projection passed
@@ -15,7 +15,7 @@ Agent 的职责:结合全局分析 draft 中的每条提议、给出建议与
15
15
  - [ ] 工作区有 `design/KG/SystemArchitecture.json`(canonical 意图图)——分析全局的依据。
16
16
  - [ ] ARGO MCP 可用。关键查询手段:
17
17
  - 语义/上下文:`getSystemArchitecture`(带 query.purpose + query.intent)、`getIntentElementContext`(看单个元素/关系/视图的依赖与受影响对象)。
18
- - 结构/类型:`queryNeo4jGraph`(只读 Cypher,如 `MATCH (e:Element {graphKey: $graphKey, type:'Business Actor'}) ...`;先 `{schema:true}` 查投影 schema)。
18
+ - 结构/类型:`queryNeo4jGraph`(只读 Cypher,如 `MATCH (e:Element {graphKey: $graphKey, type:'<element type>'}) ...`)。先 `{schema:true}` 取当前工作区的语言与类型枚举,类型名一律取自该结果,勿硬编码。
19
19
  - 校验:`validateSystemArchitecture`;写图:`previewSystemArchitectureMutation` / `applySystemArchitectureMutation`。
20
20
 
21
21
  ## 原则
@@ -25,6 +25,7 @@ Agent 的职责:结合全局分析 draft 中的每条提议、给出建议与
25
25
  - **删除/破坏性提议单独把关**:对 `removeElement` / `removeRelationship` / `removeView`,必须指出 canonical 里谁引用它、删除会级联影响谁,并给出「保留 / 改挂 / 确认删除」的建议,交由人类确认。
26
26
  - **新增/更新提议**:核对 type / name / description / attributes 是否与全局命名与类型一致、是否与既有元素/关系重复冲突、应挂在哪个 parent / 视图下。
27
27
  - **视图提议**:核对成员是否落在正确层级(parent_element_id 是否合理)、删视图会否使相关 subdiagram_views 悬空。
28
+ - **类型以工作区 schema 为准**:分析前先 `queryNeo4jGraph {schema:true}` 取 `schemaLanguage` 与元素/关系类型枚举;按该枚举判定类型,**勿硬编码 ArchiMate 类型**。
28
29
  - **只读取、不泄露**:MUST NOT 读取/复述 `.env` 里的 secret 或推断敏感配置值。
29
30
 
30
31
  ## 目标
@@ -1,4 +1,4 @@
1
- // dsh-argo-wakeup - generated by install-argo.ps1 from
1
+ // dsh-argo-wakeup - generated by scripts/gen-dsh-plugins.js from
2
2
  // argo/rules/archgraph.instructions.md (single source of truth: the rule file;
3
3
  // this file is a deployment artifact, do not edit by hand).
4
4
  // DeepSeek Harness equivalent of the OpenCode hook argo/plugins/argo-wakeup.js:
@@ -7,7 +7,7 @@
7
7
  // through the argo MCP server before responding.
8
8
  export const name = 'dsh-argo-wakeup'
9
9
  export const inject = ['systemPrompt']
10
- const WAKEUP_GATE = "STEP 0 — UNCONDITIONAL STARTUP GATE. This applies to the very first message of every session, including greetings, casual chat, and questions; it may never be skipped, deferred, or treated as optional.\r\n1. Your very FIRST tool call in the session MUST be an ARGO MCP query that lists all `Business Actor`s (getSystemArchitecture with purpose \"audit\" and subject \"Business Actor\"). Identify which `Business Actor` you are. If you are not sure, consult your human partner to confirm your role before doing anything else.\r\n2. Restore your long-term memory: the SUBVIEW hierarchy mounted under that `Business Actor` element — the Views whose `parent_element_id` points to this Actor, plus the elements, relationships, and further nested sub-views inside them (NOT the View that merely includes the Actor in its `included_elements`) — and load it into session memory.\r\n3. If the `agent` attribute of the confirmed Actor differs from your current Agent type, switch to that Agent type, or delegate to an Agent of that type per `\u003cCoperationGuideline\u003e` item 2.\r\n4. If the ARGO MCP is unavailable or errors, state that explicitly to the user before doing anything else. Only after completing this gate may you respond to the user or take any other action."
10
+ const WAKEUP_GATE = "STEP 0 — UNCONDITIONAL STARTUP GATE. Applies to the very first message of every session, greetings and chat included; never skip, defer, or treat it as optional.\n1. Your first tool call MUST resolve the workspace schema and list its Actors: `queryNeo4jGraph` with `{schema:true}` → read `actorElementType` (`null` = no Actor concept, skip Actor identification), then query that element type. Confirm which Actor you are; if unsure, ask your human partner before anything else.\n2. Restore memory: load ONLY the T1 working-memory digest — your T1 summary, the most recent/active memory cards, and any session hooks (unfinished items from the last session). Do NOT bulk-load the T2 long-term memory or T3 archive; recall them on demand via `memory_search`, then read full content with `getIntentElementContext`. T2 is a recall target, not as a bulk context load.\n3. If the Actor's `agent` attribute differs from your type, switch to it or delegate per `<CoperationGuideline>` item 2.\n4. If the ARGO MCP is unavailable or errors, say so before doing anything else."
11
11
  export function apply(ctx) {
12
12
  ctx.effect(() => ctx.systemPrompt.section({
13
13
  name: 'argo:wakeup',
@@ -1,5 +1,6 @@
1
- // dsh-argo-workspace - generated by install-argo.ps1 (single source of truth:
2
- // the installer; this file is a deployment artifact, do not edit by hand).
1
+ // dsh-argo-workspace - single source of truth for the DSH workspace bridge.
2
+ // install-argo.ps1 copies this file verbatim into ~/.dsh/plugins, so the
3
+ // deployed plugin and this shipped bundle artifact are byte-identical.
3
4
  //
4
5
  // Direct MCP bridge to the argo server for DeepSeek Harness. Registers every
5
6
  // argo tool as mcp__argo__* and injects the current session's workspace