archgraph-argo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +115 -0
  3. package/argo/package.json +8 -0
  4. package/argo/rules/intent-architecture-global-rule.md +45 -0
  5. package/argo/schema/ImplementationToCodingHandoff.schema.json +252 -0
  6. package/argo/schema/ImplementationToIntentTraceProposal.schema.json +180 -0
  7. package/argo/schema/IntentToImplementationHandoff.schema.json +75 -0
  8. package/argo/schema/SystemArchitecture.schema.json +378 -0
  9. package/argo/schema/archimate3.2.pdf +0 -0
  10. package/argo/scripts/ARCHITECTURE.md +57 -0
  11. package/argo/scripts/archimate32-rules.js +12301 -0
  12. package/argo/scripts/argo-mcp-server.js +629 -0
  13. package/argo/scripts/argo-paths.js +77 -0
  14. package/argo/scripts/ensureArgoHarnessEnvironment.js +340 -0
  15. package/argo/scripts/generateArchitectureDiffPlantuml.js +466 -0
  16. package/argo/scripts/graph-rag/ARCHITECTURE.md +192 -0
  17. package/argo/scripts/graph-rag/canonicalProjectionAuthority.js +45 -0
  18. package/argo/scripts/graph-rag/defaultSemanticRetrieval.js +969 -0
  19. package/argo/scripts/graph-rag/embeddingQualificationGate.js +59 -0
  20. package/argo/scripts/graph-rag/externalProductionConfig.js +74 -0
  21. package/argo/scripts/graph-rag/liveEmbeddingIndexGate.js +129 -0
  22. package/argo/scripts/graph-rag/liveEmbeddingNeo4jBoundary.js +137 -0
  23. package/argo/scripts/graph-rag/liveEmbeddingProviderClient.js +49 -0
  24. package/argo/scripts/graph-rag/liveEmbeddingProviderConfig.js +481 -0
  25. package/argo/scripts/graph-rag/mutationEmbeddingVectorLifecycle.js +1261 -0
  26. package/argo/scripts/graph-rag/neo4jNativeRetrieval.js +37 -0
  27. package/argo/scripts/graph-rag/productionGraphRagRuntime.js +1624 -0
  28. package/argo/scripts/graph-rag/semantic-persistence/ARCHITECTURE.md +51 -0
  29. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticBackfill.js +241 -0
  30. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticCheckpointStore.js +99 -0
  31. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticNeo4jAdapter.js +149 -0
  32. package/argo/scripts/graph-rag/semantic-persistence/productionSemanticProjectionStore.js +171 -0
  33. package/argo/scripts/graph-rag/semanticOperatorError.js +38 -0
  34. package/argo/scripts/graph-rag/semanticOperatorJourney.js +459 -0
  35. package/argo/scripts/graph-rag/semanticReadinessAttestationStore.js +398 -0
  36. package/argo/scripts/graph-rag/systemMetadataCommandAdapter.js +269 -0
  37. package/argo/scripts/graph-semantics.js +220 -0
  38. package/argo/scripts/neo4j-system-architecture-store.js +777 -0
  39. package/argo/scripts/repositoryArgoEnvironment.js +101 -0
  40. package/argo/scripts/runArchitectureTests.js +583 -0
  41. package/argo/scripts/semanticOperatorJourneyCli.js +91 -0
  42. package/argo/scripts/syncSystemArchitectureToNeo4j.js +67 -0
  43. package/argo/scripts/systemarchitecture-mcp-server.js +2965 -0
  44. package/argo/scripts/test-executors/_template.js +58 -0
  45. package/argo/scripts/test-executors/default.js +199 -0
  46. package/argo/scripts/validateStageHandoff.js +459 -0
  47. package/argo/scripts/validateSystemArchitecture.js +254 -0
  48. package/argo/scripts/validateTraceProposal.js +181 -0
  49. package/argo/scripts/validator-mcp-server.js +377 -0
  50. package/argo/skills/argo-init/SKILL.md +110 -0
  51. package/bin/argo-deploy.js +12 -0
  52. package/install-argo.ps1 +112 -0
  53. package/package.json +28 -0
  54. package/vendor/neo4j-driver-6.2.0.tgz +0 -0
@@ -0,0 +1,254 @@
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
+
254
+ main();
@@ -0,0 +1,181 @@
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 DEFAULT_PROPOSAL_PATH = 'design/KG/ImplementationToIntentTraceProposal.json';
11
+ const TRACE_PROPOSAL_SCHEMA_PATH = '.argo/schema/ImplementationToIntentTraceProposal.schema.json';
12
+
13
+ function main() {
14
+ const proposalPath = process.argv[2] || DEFAULT_PROPOSAL_PATH;
15
+ const errors = validateTraceProposal(proposalPath);
16
+
17
+ if (errors.length > 0) {
18
+ console.error('Trace proposal validation failed:');
19
+ for (const error of errors) {
20
+ console.error(`- ${error}`);
21
+ }
22
+ process.exit(1);
23
+ }
24
+
25
+ console.log(`Trace proposal validation passed for: ${proposalPath}`);
26
+ }
27
+
28
+ function resolveSchemaAbsolutePath(schemaPath) {
29
+ const bundledCandidate = path.join(getArgoRoot(), 'schema', path.basename(schemaPath));
30
+ if (fs.existsSync(bundledCandidate)) {
31
+ return bundledCandidate;
32
+ }
33
+ return path.join(repoRoot, schemaPath);
34
+ }
35
+
36
+ function validateTraceProposal(proposalPath) {
37
+ const errors = [];
38
+ const schemaAbsolutePath = resolveSchemaAbsolutePath(TRACE_PROPOSAL_SCHEMA_PATH);
39
+ if (!fs.existsSync(schemaAbsolutePath)) {
40
+ errors.push(`schema file is missing at ${TRACE_PROPOSAL_SCHEMA_PATH}`);
41
+ return errors;
42
+ }
43
+
44
+ const proposalAbsolutePath = path.join(repoRoot, proposalPath.replace(/[\\/]+/g, path.sep));
45
+ if (!fs.existsSync(proposalAbsolutePath)) {
46
+ errors.push(`proposal file is missing at ${proposalPath}`);
47
+ return errors;
48
+ }
49
+
50
+ const document = readJson(proposalAbsolutePath, proposalPath, errors);
51
+ if (!document) {
52
+ return errors;
53
+ }
54
+
55
+ requireExact(document, 'proposalType', 'implementation-to-intent-trace', errors, proposalPath);
56
+ requireString(document, 'generatedAt', errors, proposalPath);
57
+ requireExact(document, 'sourceAgent', 'ImplementationDesign', errors, proposalPath);
58
+ requireExact(document, 'targetAgent', 'IntentionDesign', errors, proposalPath);
59
+ requireExact(document, 'lifecycle', 'temporary-trace-proposal', errors, proposalPath);
60
+
61
+ const graphPath = requireString(document, 'sourceIntentGraphPath', errors, proposalPath);
62
+ if (graphPath) {
63
+ ensureRepoPathExists(graphPath, `${proposalPath}.sourceIntentGraphPath`, errors);
64
+ }
65
+
66
+ const implementationContracts = requireStringArray(document, 'implementationContracts', true, errors, proposalPath);
67
+ if (Array.isArray(implementationContracts)) {
68
+ implementationContracts.forEach((contractPath, index) => {
69
+ ensureRepoPathExists(contractPath, `${proposalPath}.implementationContracts[${index}]`, errors);
70
+ });
71
+ }
72
+
73
+ const anchorProposals = requireArray(document, 'anchorProposals', true, errors, proposalPath);
74
+ if (Array.isArray(anchorProposals)) {
75
+ anchorProposals.forEach((anchor, index) => validateAnchorProposal(anchor, `${proposalPath}.anchorProposals[${index}]`, errors));
76
+ }
77
+
78
+ return errors;
79
+ }
80
+
81
+ function validateAnchorProposal(anchor, prefix, errors) {
82
+ requireString(anchor, 'intentElementId', errors, prefix);
83
+ requireString(anchor, 'implementationElementName', errors, prefix);
84
+ const implementationElementKind = requireString(anchor, 'implementationElementKind', errors, prefix);
85
+ if (implementationElementKind && ![
86
+ 'stable-directory',
87
+ 'contract-file',
88
+ 'explicit-test-entry',
89
+ 'critical-guardrail',
90
+ 'runtime-component',
91
+ 'schema-contract',
92
+ 'mcp-tool',
93
+ 'command',
94
+ ].includes(implementationElementKind)) {
95
+ errors.push(`${prefix}.implementationElementKind has unsupported value '${implementationElementKind}'`);
96
+ }
97
+
98
+ const implementsType = requireString(anchor, 'implementsType', errors, prefix);
99
+ if (implementsType && !['direct', 'indirect'].includes(implementsType)) {
100
+ errors.push(`${prefix}.implementsType must be 'direct' or 'indirect'`);
101
+ }
102
+
103
+ requireString(anchor, 'tracePurpose', errors, prefix);
104
+ const contractPaths = requireStringArray(anchor, 'contractPaths', true, errors, prefix);
105
+ if (Array.isArray(contractPaths)) {
106
+ contractPaths.forEach((contractPath, index) => {
107
+ ensureRepoPathExists(contractPath, `${prefix}.contractPaths[${index}]`, errors);
108
+ });
109
+ }
110
+ const contextEntryPoints = requireStringArray(anchor, 'contextEntryPoints', true, errors, prefix);
111
+ if (Array.isArray(contextEntryPoints)) {
112
+ contextEntryPoints.forEach((entryPoint, index) => {
113
+ ensureRepoPathExists(entryPoint, `${prefix}.contextEntryPoints[${index}]`, errors);
114
+ });
115
+ }
116
+ requireStringArray(anchor, 'excludedDetails', true, errors, prefix);
117
+ }
118
+
119
+ function readJson(filePath, label, errors) {
120
+ try {
121
+ return JSON.parse(fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, ''));
122
+ } catch (error) {
123
+ errors.push(`failed to parse ${label}: ${String(error)}`);
124
+ return undefined;
125
+ }
126
+ }
127
+
128
+ function requireExact(object, key, expectedValue, errors, prefix) {
129
+ const value = requireString(object, key, errors, prefix);
130
+ if (value && value !== expectedValue) {
131
+ errors.push(`${prefix}.${key} must be '${expectedValue}'`);
132
+ }
133
+ }
134
+
135
+ function requireString(object, key, errors, prefix) {
136
+ if (!object || typeof object[key] !== 'string' || object[key].trim() === '') {
137
+ errors.push(`${prefix}.${key} must be a non-empty string`);
138
+ return undefined;
139
+ }
140
+ return object[key];
141
+ }
142
+
143
+ function requireArray(object, key, mustHaveItems, errors, prefix) {
144
+ if (!object || !Array.isArray(object[key])) {
145
+ errors.push(`${prefix}.${key} must be an array`);
146
+ return undefined;
147
+ }
148
+ if (mustHaveItems && object[key].length === 0) {
149
+ errors.push(`${prefix}.${key} must not be empty`);
150
+ }
151
+ return object[key];
152
+ }
153
+
154
+ function requireStringArray(object, key, mustHaveItems, errors, prefix) {
155
+ const value = requireArray(object, key, mustHaveItems, errors, prefix);
156
+ if (!Array.isArray(value)) {
157
+ return undefined;
158
+ }
159
+ value.forEach((entry, index) => {
160
+ if (typeof entry !== 'string' || entry.trim() === '') {
161
+ errors.push(`${prefix}.${key}[${index}] must be a non-empty string`);
162
+ }
163
+ });
164
+ return value;
165
+ }
166
+
167
+ function ensureRepoPathExists(relativePath, label, errors) {
168
+ const normalized = relativePath.replace(/[\\/]+/g, path.sep);
169
+ const absolutePath = path.join(repoRoot, normalized);
170
+ if (!fs.existsSync(absolutePath)) {
171
+ errors.push(`${label} points to a missing path: ${relativePath}`);
172
+ }
173
+ }
174
+
175
+ if (require.main === module) {
176
+ main();
177
+ }
178
+
179
+ module.exports = {
180
+ validateTraceProposal,
181
+ };