archgraph-argo 0.10.34 → 0.10.35

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.
@@ -15,13 +15,13 @@ This local contract refines `OVERALL_ARCHITECTURE.md`.
15
15
 
16
16
  `getSystemArchitecture` accepts:
17
17
 
18
- - no `query`: return exactly the legacy public envelope `{ status, graphPath, document }` with the complete canonical `document` and no query-mode metadata;
19
- - `query.purpose`: one of `intent-decision`, `implementation-design`, `coding-repair`, `audit`, or `graph-tidy`;
18
+ - `query`: REQUIRED. An omitted-query call is rejected with `QUERY_REQUIRED`; the legacy full-graph snapshot envelope is no longer exposed to agents.
19
+ - `query.purpose`: one of `general` or `audit` (`intent-decision`, `implementation-design`, `coding-repair`, and `graph-tidy` were removed from the agent-facing purpose enum; the runtime engine retains all of them as internal closure categories reachable only via the private journey/CLI, never the public tool — `general` binds to the internal `implementation-design` closure category);
20
20
  - `query.intent`: required non-empty natural-language intent for an explicit query;
21
21
  - `query.subject`: required non-empty audit subject when `purpose` is `audit`;
22
22
  - optional deterministic anchors may be added without changing no-argument behavior.
23
23
 
24
- All five purpose values remain legal contract inputs. `intent-decision`, `implementation-design`, `coding-repair`, and valid `audit` requests invoke the semantic retrieval boundary; `graph-tidy` never invokes it and reports `mode: "full-snapshot"` plus `semanticRetrieval: "bypassed"`.
24
+ Both purpose values remain legal agent-facing contract inputs. `general` (generic semantic/memory retrieval, loose threshold) and valid `audit` requests (strict proof-closure, subject required) invoke the semantic retrieval boundary. No agent-facing path reports `mode: "full-snapshot"` or `semanticRetrieval: "bypassed"`; the output contract mode is `semantic-query` or `error` only.
25
25
 
26
26
  For W6, semantic query results must remain traceable to the canonical graph version used by the same no-argument legacy read. Endpoint, View, and provenance completion are delegated inward to the Graph RAG boundary, but the query service must surface their evidence without silently dropping or rewriting `canonicalVersion`, policy, index, or alignment fields.
27
27
 
@@ -29,6 +29,7 @@ For BP-MCP-SEM-PAYLOAD and BP-MCP-SEM-ELEMENT, semantic result mapping is object
29
29
 
30
30
  Validation occurs before retrieval and returns these stable categories:
31
31
 
32
+ - missing `query`: `QUERY_REQUIRED`;
32
33
  - missing purpose: `QUERY_PURPOSE_REQUIRED`;
33
34
  - purpose outside the legal enum: `QUERY_PURPOSE_INVALID`;
34
35
  - missing or blank intent: `QUERY_INTENT_REQUIRED`;
@@ -8,9 +8,6 @@ const systemArchitectureMcp = require('./systemarchitecture-mcp-server.js');
8
8
  const {
9
9
  semanticOperatorErrorResult,
10
10
  } = require('./graph-rag/semanticOperatorError.js');
11
- const {
12
- runCanonicalSemanticInit,
13
- } = require('./graph-rag/semanticOperatorJourney.js');
14
11
  const {
15
12
  loadRepositoryArgoEnvironment,
16
13
  } = require('./repositoryArgoEnvironment.js');
@@ -45,8 +42,6 @@ const WINDOWS_RESERVED_NAMES = new Set([
45
42
 
46
43
  const VALIDATOR_TOOL_NAMES = new Set([
47
44
  'validateSystemArchitecture',
48
- 'validateStageHandoff',
49
- 'validateTraceProposal',
50
45
  'runArchitectureTests',
51
46
  ]);
52
47
  const SYSTEM_ARCHITECTURE_TOOL_NAMES = new Set([
@@ -64,7 +59,6 @@ const SYSTEM_ARCHITECTURE_TOOL_NAMES = new Set([
64
59
  'addArchitectureView',
65
60
  'updateArchitectureView',
66
61
  'removeArchitectureView',
67
- 'generateArchitectureDiffPlantuml',
68
62
  'queryNeo4jGraph',
69
63
  'memory_search',
70
64
  ]);
@@ -79,35 +73,6 @@ const TOOLS = [
79
73
  additionalProperties: false,
80
74
  },
81
75
  },
82
- {
83
- name: 'validateStageHandoff',
84
- description: 'Validate Argo stage handoff JSON. Use stage intent-to-implementation or implementation-to-coding, or omit to validate all supported stages.',
85
- inputSchema: {
86
- type: 'object',
87
- properties: {
88
- stage: {
89
- type: 'string',
90
- enum: ['intent-to-implementation', 'implementation-to-coding'],
91
- description: 'Optional handoff stage to validate.',
92
- },
93
- },
94
- additionalProperties: false,
95
- },
96
- },
97
- {
98
- name: 'validateTraceProposal',
99
- description: 'Validate ImplementationToIntentTraceProposal JSON against .argo/schema/ImplementationToIntentTraceProposal.schema.json and repository path references.',
100
- inputSchema: {
101
- type: 'object',
102
- properties: {
103
- proposalPath: {
104
- type: 'string',
105
- description: 'Optional proposal path relative to workspace root. Default: design/KG/ImplementationToIntentTraceProposal.json',
106
- },
107
- },
108
- additionalProperties: false,
109
- },
110
- },
111
76
  {
112
77
  name: 'runArchitectureTests',
113
78
  description: 'Execute explicit architecture testcases from the intent graph and refresh design/KG/test-failure-records.json. This MCP call can exceed client timeouts; if it times out, run the same test runner directly with: node .argo/scripts/runArchitectureTests.js',
@@ -122,39 +87,22 @@ const TOOLS = [
122
87
  additionalProperties: false,
123
88
  },
124
89
  },
125
- {
126
- name: 'generateArchitectureDiffPlantuml',
127
- description: 'Generate a timestamped PlantUML Markdown tree for current git diff changes in SystemArchitecture.json. The tool compares HEAD and working tree, extracts changed elements/relationships, and writes to .argo/temp/architecture_analysis/.',
128
- inputSchema: {
129
- type: 'object',
130
- properties: {
131
- architecturePath: {
132
- type: 'string',
133
- description: 'Optional architecture graph path relative to workspace root. Default: design/KG/SystemArchitecture.json',
134
- },
135
- outputDir: {
136
- type: 'string',
137
- description: 'Optional output directory relative to workspace root. Default: .argo/temp/architecture_analysis',
138
- },
139
- },
140
- additionalProperties: false,
141
- },
142
- },
143
90
  {
144
91
  name: 'getSystemArchitecture',
145
92
  description: 'Start here, but prefer an explicit semantic query instead of an omitted-query full graph read. Provide query.purpose and query.intent to get a compact business/architecture result, then use returned element ids with getIntentElementContext for focused dependency context. Omit query only when an exact full canonical snapshot is explicitly required.',
146
93
  inputSchema: {
147
94
  type: 'object',
95
+ required: ['query'],
148
96
  properties: {
149
97
  architecturePath: { type: 'string', description: 'Default: design/KG/SystemArchitecture.json' },
150
98
  query: {
151
99
  type: 'object',
152
- description: 'Preferred for ordinary agent reading. Use semantic query instead of full graph reads; combine the returned element ids with getIntentElementContext when deeper local context is needed.',
100
+ description: 'Required semantic query. Provide query.purpose + query.intent; combine the returned element ids with getIntentElementContext when deeper local context is needed.',
153
101
  properties: {
154
102
  purpose: {
155
103
  type: 'string',
156
- enum: ['intent-decision', 'implementation-design', 'coding-repair', 'audit', 'graph-tidy'],
157
- description: 'Declared reading purpose. Use intent-decision, implementation-design, coding-repair, or audit for semantic retrieval; graph-tidy intentionally bypasses semantic retrieval and may return a full snapshot.',
104
+ enum: ['general', 'audit'],
105
+ description: 'Declared reading purpose: general for generic semantic/memory retrieval, or audit for strict proof-closure reads (subject required).',
158
106
  },
159
107
  intent: { type: 'string', description: 'Natural-language intent for semantic retrieval, for example "summarize business features for high-risk audit".' },
160
108
  subject: { type: 'string', description: 'Required for audit; optional anchor/focus id for other semantic purposes.' },
@@ -416,19 +364,42 @@ async function callTool(name, args = {}, progressToken = null, dependencies = un
416
364
  loadRepositoryArgoEnvironment(resolveWorkspaceRoot(args));
417
365
  if (name === 'initializeWorkspace') {
418
366
  const workspace = await initializeWorkspace(resolveWorkspaceRoot(args));
419
- const composition = canonicalSemanticInitStorage.getStore()
420
- || systemArchitectureMcp.createDefaultCanonicalSemanticInitComposition({
421
- repositoryRoot: resolveWorkspaceRoot(args),
422
- });
423
- const semanticLifecycle = await runCanonicalSemanticInit(composition, {
424
- repositoryRoot: resolveWorkspaceRoot(args),
425
- workspace,
367
+ // Deterministic argo-init harness report (Neo4j structural sync, semantic
368
+ // lifecycle, canonical validation, subdiagram_views consistency), built
369
+ // in-process so the argo-init skill needs no workspace-external script.
370
+ // Lazy require avoids a circular dependency (ensureArgoHarnessEnvironment
371
+ // requires this module at its top).
372
+ const { buildHarnessReport } = require('./ensureArgoHarnessEnvironment.js');
373
+ const report = await buildHarnessReport({
374
+ checkOnly: false,
375
+ workspaceRoot: workspace.workspaceRoot,
376
+ includeBootstrap: false,
426
377
  });
427
378
  return toolResult({
428
- ...workspace,
429
- semanticState: semanticLifecycle.state,
430
- semanticLifecycle,
431
- alignment: semanticLifecycle.alignment,
379
+ status: report.status,
380
+ workspaceRoot: workspace.workspaceRoot,
381
+ targetFeapName: workspace.targetFeapName,
382
+ createdFiles: workspace.createdFiles,
383
+ updatedFiles: workspace.updatedFiles,
384
+ removedFiles: workspace.removedFiles,
385
+ skippedSteps: workspace.skippedSteps,
386
+ workspaceBootstrap: {
387
+ status: 'ok',
388
+ workspaceRoot: workspace.workspaceRoot,
389
+ targetFeapName: workspace.targetFeapName,
390
+ createdFiles: workspace.createdFiles,
391
+ updatedFiles: workspace.updatedFiles,
392
+ removedFiles: workspace.removedFiles,
393
+ skippedSteps: workspace.skippedSteps,
394
+ },
395
+ mcp: report.mcp,
396
+ systemArchitecture: report.systemArchitecture,
397
+ subdiagramViews: report.subdiagramViews,
398
+ neo4j: report.neo4j,
399
+ semanticLifecycle: report.semanticLifecycle,
400
+ semanticState: report.semanticLifecycle && report.semanticLifecycle.state,
401
+ alignment: report.semanticLifecycle && report.semanticLifecycle.alignment,
402
+ reportPath: report.reportPath,
432
403
  });
433
404
  }
434
405
  if (VALIDATOR_TOOL_NAMES.has(name)) {
@@ -685,7 +656,6 @@ async function handleRequest(request, dependencies = undefined) {
685
656
  && params.arguments
686
657
  && Object.prototype.hasOwnProperty.call(params.arguments, 'query')
687
658
  && params.arguments.query
688
- && params.arguments.query.purpose !== 'graph-tidy'
689
659
  ) {
690
660
  activeDependencies = {
691
661
  semanticOperatorJourney:
@@ -33,40 +33,38 @@ const REQUIRED_TOOL_NAMES = [
33
33
  'validateSystemArchitecture',
34
34
  ];
35
35
 
36
- async function main() {
37
- const options = parseArgs(process.argv.slice(2));
38
- const workspaceRoot = resolveWorkspaceRoot();
36
+ // Build the deterministic argo-init harness report (Neo4j structural sync,
37
+ // semantic lifecycle, canonical validation, subdiagram_views consistency).
38
+ // `includeBootstrap` is true for the standalone CLI (it calls initializeWorkspace
39
+ // to bootstrap the workspace); the initializeWorkspace MCP tool passes false
40
+ // because it already bootstrapped — avoids re-entrancy through ensureWorkspaceBootstrap.
41
+ async function buildHarnessReport({ checkOnly = false, workspaceRoot, includeBootstrap = true }) {
39
42
  const reportPath = path.join(workspaceRoot, '.argo', 'temp', 'argo-harness-init-report.json');
40
- const harnessEnvironment = loadRepositoryArgoEnvironment(workspaceRoot);
41
43
  const report = {
42
44
  status: 'ok',
43
45
  workspaceRoot,
44
46
  generatedAt: new Date().toISOString(),
45
- mode: options.checkOnly ? 'check-only' : 'prepare-and-check',
47
+ mode: checkOnly ? 'check-only' : 'prepare-and-check',
46
48
  reportPath: normalizeRelativePath(path.relative(workspaceRoot, reportPath)),
47
- harnessEnvironment,
48
49
  };
49
50
 
50
51
  try {
51
- report.workspaceBootstrap = await ensureWorkspaceBootstrap({
52
- checkOnly: options.checkOnly,
53
- workspaceRoot,
54
- });
52
+ report.harnessEnvironment = loadRepositoryArgoEnvironment(workspaceRoot);
53
+ if (includeBootstrap) {
54
+ report.workspaceBootstrap = await ensureWorkspaceBootstrap({ checkOnly, workspaceRoot });
55
+ }
55
56
  report.mcp = verifyArgoMcpServer({ workspaceRoot });
56
- report.systemArchitecture = await verifyCanonicalSystemArchitecture();
57
+ report.systemArchitecture = await verifyCanonicalSystemArchitecture({ workspaceRoot });
57
58
  report.subdiagramViews = report.systemArchitecture.status === 'ok'
58
- ? await ensureSubdiagramViewsConsistency({
59
- checkOnly: options.checkOnly,
60
- workspaceRoot,
61
- })
59
+ ? await ensureSubdiagramViewsConsistency({ checkOnly, workspaceRoot })
62
60
  : {
63
61
  status: 'skipped',
64
- mode: options.checkOnly ? 'check' : 'fix-direct',
62
+ mode: checkOnly ? 'check' : 'fix-direct',
65
63
  reason: 'system architecture invalid; subdiagram_views repair skipped',
66
64
  };
67
- report.neo4j = await ensureNeo4jProjection({ checkOnly: options.checkOnly });
65
+ report.neo4j = await ensureNeo4jProjection({ checkOnly });
68
66
  report.semanticLifecycle = await ensureCanonicalSemanticLifecycle({
69
- checkOnly: options.checkOnly,
67
+ checkOnly,
70
68
  workspaceRoot,
71
69
  neo4j: report.neo4j,
72
70
  });
@@ -75,25 +73,24 @@ async function main() {
75
73
  report.error = formatErrorForReport(error);
76
74
  }
77
75
 
78
- if (report.workspaceBootstrap && report.workspaceBootstrap.status === 'failed') {
79
- report.status = 'failed';
80
- }
81
- if (report.mcp && report.mcp.status === 'failed') {
82
- report.status = 'failed';
83
- }
84
- if (report.systemArchitecture && report.systemArchitecture.status === 'failed') {
85
- report.status = 'failed';
86
- }
87
- if (report.neo4j && report.neo4j.status === 'failed') {
88
- report.status = 'failed';
89
- }
90
- if (report.semanticLifecycle && report.semanticLifecycle.status === 'failed') {
91
- report.status = 'failed';
92
- }
93
- if (report.subdiagramViews && report.subdiagramViews.status === 'failed') {
94
- report.status = 'failed';
76
+ for (const section of ['workspaceBootstrap', 'mcp', 'systemArchitecture', 'neo4j', 'semanticLifecycle', 'subdiagramViews']) {
77
+ if (report[section] && report[section].status === 'failed') {
78
+ report.status = 'failed';
79
+ }
95
80
  }
96
81
 
82
+ return report;
83
+ }
84
+
85
+ async function main() {
86
+ const options = parseArgs(process.argv.slice(2));
87
+ const workspaceRoot = resolveWorkspaceRoot();
88
+ const report = await buildHarnessReport({
89
+ checkOnly: options.checkOnly,
90
+ workspaceRoot,
91
+ includeBootstrap: true,
92
+ });
93
+ const reportPath = path.join(workspaceRoot, '.argo', 'temp', 'argo-harness-init-report.json');
97
94
  writeJson(reportPath, report);
98
95
  console.log(JSON.stringify(report, null, 2));
99
96
 
@@ -102,6 +99,8 @@ async function main() {
102
99
  }
103
100
  }
104
101
 
102
+ module.exports = { buildHarnessReport, main };
103
+
105
104
  function parseArgs(argv) {
106
105
  const options = {
107
106
  checkOnly: false,
@@ -246,16 +245,16 @@ function verifyArgoMcpServer({ workspaceRoot }) {
246
245
  };
247
246
  }
248
247
 
249
- async function verifyCanonicalSystemArchitecture() {
250
- const getResponse = await argoMcp.callTool('getSystemArchitecture', {
251
- architecturePath: DEFAULT_GRAPH_PATH,
252
- });
253
- const getPayload = parseToolPayload(getResponse);
254
- if (getPayload.status !== 'passed') {
248
+ async function verifyCanonicalSystemArchitecture({ workspaceRoot } = {}) {
249
+ const graphPath = DEFAULT_GRAPH_PATH;
250
+ let document = null;
251
+ try {
252
+ const raw = fs.readFileSync(path.resolve(workspaceRoot, graphPath), 'utf8');
253
+ document = JSON.parse(raw);
254
+ } catch (error) {
255
255
  return {
256
256
  status: 'failed',
257
- error: `getSystemArchitecture failed for ${DEFAULT_GRAPH_PATH}`,
258
- payload: getPayload,
257
+ error: `failed to read canonical graph ${graphPath}: ${error.message}`,
259
258
  };
260
259
  }
261
260
 
@@ -264,7 +263,7 @@ async function verifyCanonicalSystemArchitecture() {
264
263
  if (validatePayload.status !== 'passed') {
265
264
  return {
266
265
  status: 'failed',
267
- graphPath: getPayload.graphPath,
266
+ graphPath,
268
267
  error: 'validateSystemArchitecture reported errors.',
269
268
  errors: validatePayload.errors || [],
270
269
  };
@@ -272,11 +271,11 @@ async function verifyCanonicalSystemArchitecture() {
272
271
 
273
272
  return {
274
273
  status: 'ok',
275
- graphPath: getPayload.graphPath,
276
- elementCount: Array.isArray(getPayload.document && getPayload.document.elements) ? getPayload.document.elements.length : 0,
277
- relationshipCount: Array.isArray(getPayload.document && getPayload.document.relationships) ? getPayload.document.relationships.length : 0,
278
- viewCount: Array.isArray(getPayload.document && getPayload.document.views) ? getPayload.document.views.length : 0,
279
- neo4jRecovery: getPayload.neo4jRecovery || null,
274
+ graphPath,
275
+ elementCount: Array.isArray(document.elements) ? document.elements.length : 0,
276
+ relationshipCount: Array.isArray(document.relationships) ? document.relationships.length : 0,
277
+ viewCount: Array.isArray(document.views) ? document.views.length : 0,
278
+ neo4jRecovery: null,
280
279
  };
281
280
  }
282
281
 
@@ -412,7 +411,9 @@ function formatErrorForReport(error) {
412
411
  return message;
413
412
  }
414
413
 
415
- main().catch(error => {
416
- console.error(formatErrorForReport(error));
417
- process.exit(1);
418
- });
414
+ if (require.main === module) {
415
+ main().catch(error => {
416
+ console.error(formatErrorForReport(error));
417
+ process.exit(1);
418
+ });
419
+ }
@@ -50,6 +50,14 @@ const PURPOSE_CATEGORIES = Object.freeze([
50
50
  'graph-tidy',
51
51
  ]);
52
52
 
53
+ // Agent-facing purpose alias: the generic memory/context read is exposed to
54
+ // agents as `general`; internally it binds to the implementation-design closure
55
+ // category (same loose-threshold retrieval, generic closure shape). The other
56
+ // categories stay internal-only (exercised by the W5 purpose-closure runners).
57
+ const AGENT_PURPOSE_TO_CATEGORY = Object.freeze({
58
+ general: 'implementation-design',
59
+ });
60
+
53
61
  const PURPOSE_POLICY_ANCHORS = Object.freeze({
54
62
  'intent-decision': 'grag-intent-decision-policy',
55
63
  'implementation-design': 'grag-implementation-policy',
@@ -617,7 +625,7 @@ function average(values) {
617
625
 
618
626
  async function closePurposePolicyScope(options) {
619
627
  const request = options.request || {};
620
- const category = request.purpose;
628
+ const category = AGENT_PURPOSE_TO_CATEGORY[request.purpose] || request.purpose;
621
629
  const template = PURPOSE_POLICY_TEMPLATES[category];
622
630
  const policyAnchorId = PURPOSE_POLICY_ANCHORS[category];
623
631
  if (!template || !policyAnchorId) {
@@ -1582,7 +1590,8 @@ function isLifecycleRequest(request = {}) {
1582
1590
  }
1583
1591
 
1584
1592
  function isPurposePolicyClosureRequest(request = {}) {
1585
- return PURPOSE_CATEGORIES.includes(request.purpose);
1593
+ const category = AGENT_PURPOSE_TO_CATEGORY[request.purpose] || request.purpose;
1594
+ return PURPOSE_CATEGORIES.includes(category);
1586
1595
  }
1587
1596
 
1588
1597
  function semanticIndexNotAligned(alignment) {
@@ -10,11 +10,8 @@ const {
10
10
 
11
11
  const DEFAULT_GRAPH_PATH = 'design/KG/SystemArchitecture.json';
12
12
  const LEGAL_QUERY_PURPOSES = new Set([
13
- 'intent-decision',
14
- 'implementation-design',
15
- 'coding-repair',
13
+ 'general',
16
14
  'audit',
17
- 'graph-tidy',
18
15
  ]);
19
16
  const FORBIDDEN_RESPONSE_SHAPE_CONTROL_FIELDS = Object.freeze([
20
17
  'responseProfile',
@@ -42,12 +39,12 @@ const GET_SYSTEM_ARCHITECTURE_OUTPUT_SCHEMA = {
42
39
  },
43
40
  mode: {
44
41
  type: 'string',
45
- enum: ['full-snapshot', 'semantic-query', 'error'],
42
+ enum: ['semantic-query', 'error'],
46
43
  description: 'Discriminator for the response variant.',
47
44
  },
48
45
  document: {
49
46
  type: ['object', 'null'],
50
- description: 'Canonical graph snapshot for full-snapshot responses; semantic business-summary responses may use result in the text payload and set this to null; null for errors.',
47
+ description: 'Canonical graph snapshot for semantic responses; semantic business-summary responses may use result in the text payload and set this to null; null for errors.',
51
48
  },
52
49
  query: {
53
50
  type: ['object', 'null'],
@@ -55,11 +52,11 @@ const GET_SYSTEM_ARCHITECTURE_OUTPUT_SCHEMA = {
55
52
  purpose: { type: 'string', enum: Array.from(LEGAL_QUERY_PURPOSES) },
56
53
  intent: { type: 'string' },
57
54
  subject: { type: 'string' },
58
- mode: { type: 'string', enum: ['full-snapshot', 'semantic-query'] },
59
- semanticRetrieval: { type: 'string', enum: ['bypassed', 'invoked'] },
55
+ mode: { type: 'string', enum: ['semantic-query'] },
56
+ semanticRetrieval: { type: 'string', enum: ['invoked'] },
60
57
  },
61
58
  additionalProperties: true,
62
- description: 'Normalized explicit query metadata; null for no-argument snapshots and errors.',
59
+ description: 'Normalized explicit query metadata; null for errors.',
63
60
  },
64
61
  error: {
65
62
  oneOf: [
@@ -87,14 +84,6 @@ const GET_SYSTEM_ARCHITECTURE_OUTPUT_SCHEMA = {
87
84
  },
88
85
  },
89
86
  oneOf: [
90
- {
91
- properties: {
92
- mode: { const: 'full-snapshot' },
93
- document: { type: 'object' },
94
- query: { type: ['object', 'null'] },
95
- error: { type: 'null' },
96
- },
97
- },
98
87
  {
99
88
  properties: {
100
89
  mode: { const: 'semantic-query' },
@@ -137,7 +126,6 @@ const {
137
126
  validateArchiMateEndpointMatrix,
138
127
  validateViewElementLimits,
139
128
  } = require('./graph-semantics.js');
140
- const architectureDiffPlantuml = require('./generateArchitectureDiffPlantuml.js');
141
129
  const {
142
130
  createProductionGraphRagRuntime,
143
131
  } = require('./graph-rag/productionGraphRagRuntime.js');
@@ -188,19 +176,20 @@ const HANDLED_MUTATION_TYPES = new Set([
188
176
  const TOOLS = [
189
177
  {
190
178
  name: 'getSystemArchitecture',
191
- description: 'Start here for read-only intent architecture access, but prefer an explicit semantic query instead of an omitted-query full graph read. Provide query.purpose and query.intent to get a compact business/architecture result, then use returned element ids with getIntentElementContext for focused dependency context. Omit query only when an exact full canonical snapshot is explicitly required.',
179
+ description: 'Read-only intent architecture access via explicit semantic query. Always provide query.purpose and query.intent to get a compact business/architecture result, then use returned element ids with getIntentElementContext for focused dependency context. Full-graph snapshot access is not exposed; query is required.',
192
180
  inputSchema: {
193
181
  type: 'object',
182
+ required: ['query'],
194
183
  properties: {
195
184
  architecturePath: { type: 'string', description: `Default: ${DEFAULT_GRAPH_PATH}` },
196
185
  query: {
197
186
  type: 'object',
198
- description: 'Preferred for ordinary agent reading. Use semantic query instead of full graph reads; combine the returned element ids with getIntentElementContext when deeper local context is needed.',
187
+ description: 'Required semantic query. Provide query.purpose + query.intent; combine the returned element ids with getIntentElementContext when deeper local context is needed.',
199
188
  properties: {
200
189
  purpose: {
201
190
  type: 'string',
202
191
  enum: Array.from(LEGAL_QUERY_PURPOSES),
203
- description: 'Declared reading purpose. Use intent-decision, implementation-design, coding-repair, or audit for semantic retrieval; graph-tidy intentionally bypasses semantic retrieval and may return a full snapshot.',
192
+ description: 'Declared reading purpose: general for generic semantic/memory retrieval, or audit for strict proof-closure reads (subject required).',
204
193
  },
205
194
  intent: { type: 'string', description: 'Natural-language intent for semantic retrieval, for example "summarize business features for high-risk audit".' },
206
195
  subject: { type: 'string', description: 'Required for audit; optional anchor/focus id for other semantic purposes.' },
@@ -232,24 +221,6 @@ const TOOLS = [
232
221
  description: 'read-only query that resolves one view by view_id into its complete membership: the view object, every member element (from included_elements), every member relationship (from included_relationships), the parent element, and optionally child sub-views declared by member elements. Resolves ids into full canonical objects instead of returning raw id lists.',
233
222
  inputSchema: viewContextInputSchema(),
234
223
  },
235
- {
236
- name: 'generateArchitectureDiffPlantuml',
237
- description: 'Generate a timestamped PlantUML Markdown tree for current git diff changes in SystemArchitecture.json. The tool compares HEAD and working tree, extracts changed elements/relationships, and writes to .argo/temp/architecture_analysis/.',
238
- inputSchema: {
239
- type: 'object',
240
- properties: {
241
- architecturePath: {
242
- type: 'string',
243
- description: `Optional architecture graph path relative to workspace root. Default: ${DEFAULT_GRAPH_PATH}`,
244
- },
245
- outputDir: {
246
- type: 'string',
247
- description: 'Optional output directory relative to workspace root. Default: .argo/temp/architecture_analysis',
248
- },
249
- },
250
- additionalProperties: false,
251
- },
252
- },
253
224
  {
254
225
  name: 'previewSystemArchitectureMutation',
255
226
  description: 'Use before apply for complex or risky changes. Performs a dry-run of one or more mutations, runs schema, graph, view, and ArchiMate 3.2 validation, and does not write the graph.',
@@ -1965,15 +1936,10 @@ function validateSemanticQueryResponseShapeControls(query) {
1965
1936
  return { status: 'passed' };
1966
1937
  }
1967
1938
 
1968
- function isPurposeClosureProbe(query) {
1969
- return Array.isArray(query && query.anchors) && query.anchors.length > 0;
1970
- }
1971
-
1972
1939
  function isOrdinarySemanticQuery(query) {
1973
1940
  return !!query
1974
1941
  && typeof query === 'object'
1975
- && !Array.isArray(query)
1976
- && query.purpose !== 'graph-tidy';
1942
+ && !Array.isArray(query);
1977
1943
  }
1978
1944
 
1979
1945
  function isCanonicalSubsetSemanticContract(query, options = {}) {
@@ -2059,7 +2025,7 @@ function getSystemArchitectureResult(payload) {
2059
2025
  const failed = payload.status === 'failed';
2060
2026
  return toolResult(payload, {
2061
2027
  version: '1.0',
2062
- mode: failed ? 'error' : ((payload.query && payload.query.mode) || 'full-snapshot'),
2028
+ mode: failed ? 'error' : 'semantic-query',
2063
2029
  document: failed ? null : (payload.document === undefined ? null : payload.document),
2064
2030
  query: failed ? null : (payload.query || null),
2065
2031
  error: failed ? payload.error : null,
@@ -2075,23 +2041,6 @@ async function callTool(name, args = {}, dependencies = undefined) {
2075
2041
  }
2076
2042
 
2077
2043
  const query = validation.query;
2078
- if (query.purpose === 'graph-tidy') {
2079
- const context = await loadContext(args);
2080
- const payload = {
2081
- status: 'passed',
2082
- graphPath: context.graphPath.relativePath,
2083
- document: context.document,
2084
- };
2085
- if (isPurposeClosureProbe(query) && !dependencies) {
2086
- return attachContextWarnings(payload, context);
2087
- }
2088
- payload.query = {
2089
- ...query,
2090
- mode: 'full-snapshot',
2091
- semanticRetrieval: 'bypassed',
2092
- };
2093
- return getSystemArchitectureResult(attachContextWarnings(payload, context));
2094
- }
2095
2044
  const context = await loadContext(args);
2096
2045
  const contractOptions = semanticContractOptions({
2097
2046
  ...args,
@@ -2108,12 +2057,10 @@ async function callTool(name, args = {}, dependencies = undefined) {
2108
2057
  return applySemanticResponseProfile(await journey.query(query), query, contractOptions);
2109
2058
  }
2110
2059
 
2111
- const context = await loadContext(args);
2112
- return getSystemArchitectureResult(attachContextWarnings({
2113
- status: 'passed',
2114
- graphPath: context.graphPath.relativePath,
2115
- document: context.document,
2116
- }, context));
2060
+ return getSystemArchitectureResult(queryError(
2061
+ 'QUERY_REQUIRED',
2062
+ 'getSystemArchitecture requires an explicit query (query.purpose + query.intent); full-graph snapshot access has been removed.',
2063
+ ));
2117
2064
  }
2118
2065
 
2119
2066
  if (name === 'getIntentElementContext') {
@@ -2126,14 +2073,6 @@ async function callTool(name, args = {}, dependencies = undefined) {
2126
2073
  return toolResult(attachContextWarnings(buildViewContext(context, args), context));
2127
2074
  }
2128
2075
 
2129
- if (name === 'generateArchitectureDiffPlantuml') {
2130
- return toolResult(architectureDiffPlantuml.generateArchitectureDiffPlantuml({
2131
- workspaceRoot: resolveWorkspaceRoot(args),
2132
- architecturePath: args.architecturePath,
2133
- outputDir: args.outputDir,
2134
- }));
2135
- }
2136
-
2137
2076
  if (name === 'previewSystemArchitectureMutation') {
2138
2077
  const context = await loadContext(args);
2139
2078
  return toolResult(attachContextWarnings(await buildMutationResult(context, args.mutations, false), context));
@@ -2209,12 +2148,11 @@ async function callTool(name, args = {}, dependencies = undefined) {
2209
2148
  throw new Error(`Unknown tool: ${name}`);
2210
2149
  }
2211
2150
 
2212
- // memory_search: natural-language semantic memory retrieval. Reuses the
2213
- // memory-retrieval purpose (implementation-design) of the semantic journey
2214
- // (same path as getSystemArchitecture, so readiness/closure behave identically)
2215
- // and reshapes the retrieved elements into a memory-oriented hit list with
2216
- // content + similarity score, so an agent can look up the user's memory in one
2217
- // call.
2151
+ // memory_search: natural-language semantic memory retrieval. Uses the
2152
+ // agent-facing 'general' purpose of the semantic journey (same path as
2153
+ // getSystemArchitecture, so readiness/closure behave identically) and reshapes
2154
+ // the retrieved elements into a memory-oriented hit list with content +
2155
+ // similarity score, so an agent can look up the user's memory in one call.
2218
2156
  async function memorySearchTool(args = {}, dependencies = undefined) {
2219
2157
  const query = typeof args.query === 'string' ? args.query.trim() : '';
2220
2158
  if (!query) {
@@ -2232,7 +2170,7 @@ async function memorySearchTool(args = {}, dependencies = undefined) {
2232
2170
  let retrieved;
2233
2171
  try {
2234
2172
  const journey = await resolveSemanticOperatorJourney(dependencies);
2235
- retrieved = await journey.query({ purpose: 'implementation-design', intent: query });
2173
+ retrieved = await journey.query({ purpose: 'general', intent: query });
2236
2174
  } catch (error) {
2237
2175
  return {
2238
2176
  status: 'failed',
@@ -3536,7 +3474,6 @@ async function handleRequest(request, dependencies = undefined) {
3536
3474
  && params.arguments
3537
3475
  && Object.prototype.hasOwnProperty.call(params.arguments, 'query')
3538
3476
  && params.arguments.query
3539
- && params.arguments.query.purpose !== 'graph-tidy'
3540
3477
  ) {
3541
3478
  activeDependencies = {
3542
3479
  semanticOperatorJourney: await createDefaultProductionSemanticOperatorJourney({
@@ -12,20 +12,12 @@ const {
12
12
  resolveCallWorkspaceRoot,
13
13
  } = require('./argo-paths.js');
14
14
 
15
- const HANDOFF_STAGES = ['intent-to-implementation', 'implementation-to-coding'];
16
- const DEFAULT_TRACE_PROPOSAL_PATH = 'design/KG/ImplementationToIntentTraceProposal.json';
17
15
  const DEFAULT_ARCHITECTURE_GRAPH_PATH = 'design/KG/SystemArchitecture.json';
18
16
 
19
17
  const SCRIPT_CANDIDATES = {
20
18
  validateSystemArchitecture: [
21
19
  'scripts/validateSystemArchitecture.js',
22
20
  ],
23
- validateStageHandoff: [
24
- 'scripts/validateStageHandoff.js',
25
- ],
26
- validateTraceProposal: [
27
- 'scripts/validateTraceProposal.js',
28
- ],
29
21
  runArchitectureTests: [
30
22
  'scripts/runArchitectureTests.js',
31
23
  ],
@@ -41,35 +33,6 @@ const TOOLS = [
41
33
  additionalProperties: false,
42
34
  },
43
35
  },
44
- {
45
- name: 'validateStageHandoff',
46
- description: 'Validate Argo stage handoff JSON. Use stage intent-to-implementation or implementation-to-coding, or omit to validate all supported stages.',
47
- inputSchema: {
48
- type: 'object',
49
- properties: {
50
- stage: {
51
- type: 'string',
52
- enum: HANDOFF_STAGES,
53
- description: 'Optional handoff stage to validate.',
54
- },
55
- },
56
- additionalProperties: false,
57
- },
58
- },
59
- {
60
- name: 'validateTraceProposal',
61
- description: 'Validate ImplementationToIntentTraceProposal JSON against .argo/schema/ImplementationToIntentTraceProposal.schema.json and repository path references.',
62
- inputSchema: {
63
- type: 'object',
64
- properties: {
65
- proposalPath: {
66
- type: 'string',
67
- description: `Optional proposal path relative to workspace root. Default: ${DEFAULT_TRACE_PROPOSAL_PATH}`,
68
- },
69
- },
70
- additionalProperties: false,
71
- },
72
- },
73
36
  {
74
37
  name: 'runArchitectureTests',
75
38
  description: 'Execute explicit architecture testcases from the intent graph and refresh design/KG/test-failure-records.json. This MCP call can exceed client timeouts; if it times out, run the same test runner directly with: node .argo/scripts/runArchitectureTests.js',
@@ -257,19 +220,6 @@ async function callTool(name, args, progressToken = null) {
257
220
  return toolResult(await runValidatorScript(workspaceRoot, 'validateSystemArchitecture'));
258
221
  }
259
222
 
260
- if (name === 'validateStageHandoff') {
261
- const stage = args && args.stage;
262
- if (stage && !HANDOFF_STAGES.includes(stage)) {
263
- throw new Error(`Unsupported handoff stage '${stage}'. Expected one of: ${HANDOFF_STAGES.join(', ')}`);
264
- }
265
- return toolResult(await runValidatorScript(workspaceRoot, 'validateStageHandoff', stage ? [stage] : []));
266
- }
267
-
268
- if (name === 'validateTraceProposal') {
269
- const proposalPath = (args && args.proposalPath) || DEFAULT_TRACE_PROPOSAL_PATH;
270
- return toolResult(await runValidatorScript(workspaceRoot, 'validateTraceProposal', [proposalPath]));
271
- }
272
-
273
223
  if (name === 'runArchitectureTests') {
274
224
  const architecturePath = (args && args.architecturePath) || DEFAULT_ARCHITECTURE_GRAPH_PATH;
275
225
  if (progressToken) {
@@ -1,65 +1,46 @@
1
1
  ---
2
2
  name: argo-init
3
- description: "检查全局 ARGO MCP 是否正常,并完成 NEO4J 初始同步与语义生命周期初始化。Use when the user asks to verify Argo MCP readiness and perform or verify the canonical JSON-to-Neo4j initial sync plus semantic lifecycle init. Keywords: ARGO INIT, harness init, MCP health check, Neo4j initial sync, semantic lifecycle."
3
+ description: "通过 ARGO MCP initializeWorkspace 接口完成工作区确定性的初始化(NEO4J 初始同步 + 语义生命周期 + canonical 校验 + subdiagram_views 一致性),无需执行 WORKSPACE 外脚本。Use when the user asks to verify Argo MCP readiness and perform or verify the canonical JSON-to-Neo4j initial sync plus semantic lifecycle init. Keywords: ARGO INIT, harness init, initializeWorkspace, Neo4j initial sync, semantic lifecycle."
4
4
  argument-hint: scope-or-mode
5
5
  disable-model-invocation: true
6
6
  ---
7
7
 
8
8
  # ARGO INIT
9
9
 
10
- `argo-init` 负责检查全局安装的 `argo` MCP 是否正常、完成或验证 canonical intent graph Neo4j 初始同步,并在非 `--check-only` 模式下执行 canonical semantic lifecycle init。它不再负责调用旧的工作区 bootstrap / `initializeWorkspace` 工具。
10
+ `argo-init` 通过 ARGO MCP 的 `initializeWorkspace` 接口完成确定性初始化:工作区 bootstrap(缺 `SystemArchitecture.json` / `.feap` 自动生成)+ Neo4j 结构投影同步 + 语义生命周期初始化 + canonical 校验 + subdiagram_views 一致性,并返回完整报告。**不需要也不应执行任何 WORKSPACE 外脚本**——所有确定性步骤都在 MCP 进程内完成,避免扩大访问面。
11
11
 
12
- - `argo` MCP 服务器(全局 `.argo` 安装)能正常初始化、列出关键工具并响应 `ping`。
13
- - `design/KG/SystemArchitecture.json` 可通过 `argo` MCP 正常读取和校验。
14
- - 工作区缺少 `design/KG/SystemArchitecture.json` 时,非 `--check-only` 模式会自动从部署的 `defaults` 拷贝默认模板;工作区没有 `.feap` 时,自动以当前项目名拷贝默认 `EA-model-template.feap`。
15
- - 本机 Neo4j 连接可用。
16
- - canonical intent graph 至少完成一次 JSON -> Neo4j 初始同步,并通过一致性校验。
17
- - 非 `--check-only` 模式会在结构同步后执行语义生命周期:双 gate 未开启时记录 pending/disabled;双 gate 开启时执行全量 embedding backfill 与 readiness 对齐。
12
+ - 工作区缺少 `design/KG/SystemArchitecture.json` 时自动从部署的 `defaults` 拷贝默认模板;缺 `.feap` 时以当前项目名拷贝默认模板。
13
+ - 本机 Neo4j 连接可用,canonical 意图图完成至少一次 JSON -> Neo4j 初始同步并通过一致性校验。
14
+ - 语义生命周期:双 gate 未开启时记录 skipped/disabled;开启时执行全量 embedding backfill readiness 对齐。
18
15
 
19
16
  ## Rules
20
17
 
21
- - **MUST** 优先运行全局 harness 原生命令(当前工作目录须为目标仓库根):`node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js"`。
22
- - **MUST** 将该命令返回的 JSON 结果作为最终判断依据,而不是凭主观描述报告环境状态。
23
- - **MUST** 报告 `argo` MCP 是否通过、Neo4j 是否通过、初始同步是否完成、以及 `semanticLifecycle` 当前状态。
24
- - **MUST** 在脚本失败时直接转述失败阶段、错误摘要和报告路径,不要改用含糊描述。
25
- - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在、文件是否位于 git 仓库内、以及 ACL 主体。
26
- - **MUST NOT** 绕开脚本分别手工执行一堆无关命令来替代初始化工作流,除非你是在排查脚本自身失败。
18
+ - **MUST** 调用 ARGO MCP 工具 `initializeWorkspace`(传当前工作区根)执行确定性初始化,并以其返回报告为最终判断依据。
19
+ - **MUST** 报告 `mcp` / `systemArchitecture` / `neo4j` / `semanticLifecycle` / `subdiagramViews` 与整体 `status`。
20
+ - **MUST NOT** 读取、打印或复述 `.env` 中的 secret 值;排查时只允许报告 key 是否存在、ACL 主体。
21
+ - **MUST NOT** 通过 shell 手工执行 WORKSPACE 外的初始化脚本或一组无关命令来替代 `initializeWorkspace`(除非报告显示底层脚本自身失败需要排查)。
27
22
 
28
23
  ## Workflow
29
24
 
30
- ### 1. Run ARGO HARNESS Init
25
+ ### 1. Run Deterministic Init via initializeWorkspace
31
26
 
32
- 在目标仓库根目录执行(harness 通过 `ARGO_REPO_ROOT` / `WORKSPACE_FOLDER` / `cwd` 解析工作区):
27
+ 调用 ARGO MCP 工具 `initializeWorkspace`(传入当前工作区根 `workspaceRoot`)。该接口在 MCP 进程内完成全部确定性步骤并返回报告:
33
28
 
34
- ```powershell
35
- $env:ARGO_REPO_ROOT = (Get-Location).Path
36
- node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js"
37
- ```
38
-
39
- 只读检查(不修改工作区、不执行初始同步):
40
-
41
- ```powershell
42
- $env:ARGO_REPO_ROOT = (Get-Location).Path
43
- node "$env:USERPROFILE\.argo\scripts\ensureArgoHarnessEnvironment.js" --check-only
44
- ```
45
-
46
- 若通过 `ARGO_ENV_FILE` 指定了秘密文件,请先设置该变量再运行。
29
+ - `workspaceBootstrap`:缺 `SystemArchitecture.json` / `.feap` 时自动生成(createdFiles / skippedSteps)
30
+ - `mcp`:ARGO MCP 健康(协议 / tools-list / ping)
31
+ - `systemArchitecture`:canonical 校验(元素/关系/视图计数)
32
+ - `subdiagramViews`:subdiagram_views 一致性检查/修复
33
+ - `neo4j`:Neo4j 连通 + 结构投影初始同步 + 一致性校验(initialSync / verification)
34
+ - `semanticLifecycle`:语义生命周期初始化(state / alignment / readiness;未开 gate 时 skipped/disabled)
47
35
 
48
36
  ### 2. Interpret The Report
49
37
 
50
- 读取脚本输出的 JSON,并关注 `mcp`、`systemArchitecture`、`neo4j`、`semanticLifecycle`、`reportPath`。
38
+ - 整体 `status=ok`:环境就绪。
39
+ - 任一 section `status=failed` → 整体 `status=failed`,指出失败阶段:`mcp` / `systemArchitecture` / `neo4j` / `semanticLifecycle` / `subdiagramViews`。
51
40
 
52
- - `status=ok`:环境已就绪或已确认健康。
53
- - `status=failed`:指出失败阶段:
54
- - Argo MCP protocol health
55
- - canonical SystemArchitecture validation
56
- - Neo4j connectivity
57
- - Neo4j initial sync / verification
58
- - semantic lifecycle init / readiness alignment
41
+ ### 3. Handle Secret File Blockers(仅当报告含 secret 相关失败)
59
42
 
60
- ### 3. Handle Secret File Blockers
61
-
62
- 全局 `.env` 默认位于 `$env:USERPROFILE\.argo\.env`(可用 `ARGO_ENV_FILE` 覆盖)。安全诊断(不打印 secret 值):
43
+ `semanticLifecycle` `systemArchitecture` 失败可能源于 `.env` 安全预检。诊断(不打印 secret 值):
63
44
 
64
45
  ```powershell
65
46
  icacls "$env:USERPROFILE\.argo\.env"
@@ -67,30 +48,16 @@ icacls "$env:USERPROFILE\.argo\.env"
67
48
 
68
49
  处理规则:
69
50
 
70
- - `SECRET_FILE_ACL_UNSAFE`: 收紧 Windows ACL,只保留当前用户、Administrators、SYSTEM。
71
- - `SECRET_FILE_REPARSE_PROHIBITED`: `.env` 替换为普通文件(去掉符号链接/重解析点)。
72
- - `SECRET_FILE_PATH_PROHIBITED`: 修正 `ARGO_ENV_FILE` 与安装根 `.env` 不一致的路径。
51
+ - `SECRET_FILE_ACL_UNSAFE`:收紧 Windows ACL,只保留当前用户、Administrators、SYSTEM。
52
+ - `SECRET_FILE_REPARSE_PROHIBITED`:将 `.env` 替换为普通文件(去掉符号链接/重解析点)。
53
+ - `SECRET_FILE_PATH_PROHIBITED`:修正 `ARGO_ENV_FILE` 与安装根 `.env` 不一致的路径。
73
54
  - git 跟踪/忽略类错误(`SECRET_FILE_TRACKED` / `SECRET_FILE_NOT_IGNORED`)只在 `.env` 位于 git 仓库内时出现;全局 `.env` 位于仓库外时天然不适用。
74
55
 
75
- Windows ACL 修复:
76
-
77
- ```powershell
78
- $identity = whoami
79
- icacls "$env:USERPROFILE\.argo\.env" /inheritance:r /grant:r "${identity}:F" "BUILTIN\Administrators:F" "NT AUTHORITY\SYSTEM:F" /remove:g "BUILTIN\Users" "Everyone" "Authenticated Users" "NT AUTHORITY\Authenticated Users"
80
- ```
81
-
82
- 修复后必须重跑 init。
56
+ 修复后重跑 `initializeWorkspace`。
83
57
 
84
58
  ### 4. Report Concisely
85
59
 
86
- 输出应直接说明:
87
-
88
- - `argo` MCP 是否正常
89
- - `SystemArchitecture.json` 是否正常
90
- - Neo4j 是否连通
91
- - 是否完成了一次初始同步
92
- - 语义生命周期状态、alignment、是否因 `--check-only` 跳过
93
- - 报告文件位置
60
+ 输出应直接说明:`mcp` 是否正常、`SystemArchitecture.json` 是否正常、Neo4j 是否连通、是否完成一次初始同步、语义生命周期状态与 alignment、报告路径(`.argo/temp/argo-harness-init-report.json`)。
94
61
 
95
62
  ## Output
96
63
 
@@ -98,8 +65,8 @@ icacls "$env:USERPROFILE\.argo\.env" /inheritance:r /grant:r "${identity}:F" "BU
98
65
 
99
66
  ### 1. Environment Status
100
67
  - overall status: ok / failed
101
- - whether Argo MCP health passed
102
- - whether Neo4j health passed
68
+ - whether mcp health passed
69
+ - whether neo4j health passed
103
70
 
104
71
  ### 2. Sync Status
105
72
  - whether initial sync was executed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archgraph-argo",
3
- "version": "0.10.34",
3
+ "version": "0.10.35",
4
4
  "description": "Deploy the ArchGraph ARGO toolchain, skills, and rules (schema, scripts, argo-init skill, global rule) with one command.",
5
5
  "license": "MIT",
6
6
  "bin": {