@archinsight/cli 3.0.0-snapshot.4 → 3.0.0-snapshot.6

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 (3) hide show
  1. package/README.md +22 -3
  2. package/build/index.js +2651 -49
  3. package/package.json +1 -1
package/build/index.js CHANGED
@@ -57,7 +57,7 @@ var require_archy = __commonJS({
57
57
 
58
58
  // src/index.ts
59
59
  var import_archy = __toESM(require_archy(), 1);
60
- import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
60
+ import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
61
61
  import path from "node:path";
62
62
  import { instance } from "@viz-js/viz";
63
63
 
@@ -32343,7 +32343,7 @@ var coreSources = [
32343
32343
  },
32344
32344
  {
32345
32345
  "sourceName": "core_deployment.ai",
32346
- "source": "define type DeploymentElement of Element\n\ndefine type InfrastructureComponent of DeploymentElement\n constructor infrastructureComponent\n\n required Text name\n Text description\n List of TypeSlotReference _\n\ndefine type Environment of BoundaryElement\n constructor environment\n\n required Text name\n\ndefine type DeploymentProfile of BoundaryElement\n constructor deploymentProfile\n\n List of Environment environments\n List of TypeSlotReference _\n\ndefine type DeploymentProfileReference of TypeSlotReference\n required DeploymentProfile profile\n\ndefine presentation DeploymentProfile\n graphviz\n visible = false"
32346
+ "source": "define type DeploymentElement of Element\n\ndefine type InfrastructureComponent of DeploymentElement\n constructor infrastructureComponent\n\n Text name\n Text technology\n Text description\n List of TypeSlotReference _\n\ndefine type Storage of InfrastructureComponent\n constructor storage\n\n project:\n $from -> $this\n\ndefine type Broker of InfrastructureComponent\n constructor broker\n\n Text address\n\n project:\n $from -> $this\n $to -> $this\n\ndefine type Compute of InfrastructureComponent\n constructor compute\n\n Text address\n List of InfrastructureComponent components\n\ndefine type NetworkConnection of InfrastructureComponent\n constructor networkConnection\n\n project:\n $from -> $to\n\ndefine type Environment of BoundaryElement\n constructor environment\n\n required Text name\n\ndefine type DeploymentProfile of BoundaryElement\n constructor deploymentProfile\n\n List of Environment environments\n List of TypeSlotReference _\n\ndefine type DeploymentProfileReference of TypeSlotReference\n required DeploymentProfile profile\n\ndefine presentation DeploymentProfile\n graphviz\n visible = false\n\ndefine presentation NetworkConnection\n graphviz\n visible = false\n"
32347
32347
  },
32348
32348
  {
32349
32349
  "sourceName": "core_operator.ai",
@@ -34184,6 +34184,7 @@ function linkProject(request) {
34184
34184
  sourceIdentity: edge.sourceName,
34185
34185
  fromId: edge.source,
34186
34186
  toId: target.id,
34187
+ projectedAttributes: materialized.edge.attributes,
34187
34188
  ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
34188
34189
  });
34189
34190
  pendingProjections.push({
@@ -34191,6 +34192,7 @@ function linkProject(request) {
34191
34192
  fromId: edge.source,
34192
34193
  toId: target.id,
34193
34194
  attributes: edgeAttributes,
34195
+ projectedAttributes: materialized.edge.attributes,
34194
34196
  ...materialized.edge.annotations === void 0 ? {} : { annotations: materialized.edge.annotations }
34195
34197
  });
34196
34198
  }
@@ -34220,7 +34222,7 @@ function linkProject(request) {
34220
34222
  });
34221
34223
  }
34222
34224
  for (const projection of pendingProjections) {
34223
- addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations);
34225
+ addProjectedEdges(linkedEdges, projection.sourceIdentity, projection.fromId, projection.toId, projection.attributes, linkedElementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, void 0, projection.annotations, projection.projectedAttributes);
34224
34226
  }
34225
34227
  const slotDomainTypes = typeSystem.slotDomainTypes();
34226
34228
  for (const element of elements) {
@@ -34233,7 +34235,7 @@ function linkProject(request) {
34233
34235
  const presentations = buildPresentationIndex(request.snapshot.presentations ?? [], typeSystem, diagnostics);
34234
34236
  const graph = buildIndexedGraph(documents, elements, imports, linkedEdges, typeSystem);
34235
34237
  const graphElements = elements.filter(isGraphElement);
34236
- inspectGraph(graph, graphElements, linkedEdges, diagnostics);
34238
+ inspectGraph(graph, graphElements, linkedEdges, resolvedElementAttributes, diagnostics);
34237
34239
  const tabRoots = tabRootsBySource(documents, elementsByContextAndLocalId);
34238
34240
  for (const document of documents) {
34239
34241
  resolveAttributes(
@@ -35248,7 +35250,14 @@ function resolveAttributes(owner, ownerType, attributes2, referenceAttributePosi
35248
35250
  });
35249
35251
  continue;
35250
35252
  }
35251
- result[name] = [...result[name] ?? [], { id: resolved.id, element: resolved }];
35253
+ result[name] = [...result[name] ?? [], {
35254
+ id: resolved.id,
35255
+ element: resolved,
35256
+ line: value.line,
35257
+ column: value.column,
35258
+ ...value.endLine === void 0 ? {} : { endLine: value.endLine },
35259
+ ...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
35260
+ }];
35252
35261
  }
35253
35262
  }
35254
35263
  return result;
@@ -35284,7 +35293,7 @@ function flattenAttributes(scalarAttributes, attributes2) {
35284
35293
  ...Object.fromEntries(Object.entries(attributes2).map(([name, values]) => [name, values.map((value) => value.id)]))
35285
35294
  };
35286
35295
  }
35287
- function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], visitedProjectionElements = /* @__PURE__ */ new Set()) {
35296
+ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes2, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes, visitedProjectionElements = /* @__PURE__ */ new Set()) {
35288
35297
  for (const values of Object.values(attributes2)) {
35289
35298
  for (const value of values) {
35290
35299
  if (value.element === void 0) {
@@ -35301,8 +35310,24 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
35301
35310
  if (isDirectSlotReferenceSelfProjection(value.element, fromId, toId)) {
35302
35311
  continue;
35303
35312
  }
35304
- for (const rule3 of typeSystem.projectionRules(value.element.type)) {
35305
- addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2);
35313
+ const rules = typeSystem.projectionRules(value.element.type);
35314
+ if (fromId === toId && rules.some(projectionRuleUsesTo)) {
35315
+ const position3 = value.line === void 0 || value.column === void 0 ? value.element : {
35316
+ line: value.line,
35317
+ column: value.column,
35318
+ ...value.endLine === void 0 ? {} : { endLine: value.endLine },
35319
+ ...value.endColumn === void 0 ? {} : { endColumn: value.endColumn }
35320
+ };
35321
+ diagnostics.push({
35322
+ code: "PROJECTION_TARGET_REQUIRED",
35323
+ message: `Projection for '${value.element.type}' uses '$to' and must be attached to a relationship, not to element '${fromId}'`,
35324
+ sourceName: sourceIdentity,
35325
+ ...diagnosticPosition2(position3)
35326
+ });
35327
+ continue;
35328
+ }
35329
+ for (const rule3 of rules) {
35330
+ addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, value.element, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2, projectedAttributes);
35306
35331
  }
35307
35332
  addProjectedEdges(
35308
35333
  linkedEdges,
@@ -35317,12 +35342,13 @@ function addProjectedEdges(linkedEdges, sourceIdentity, fromId, toId, attributes
35317
35342
  diagnostics,
35318
35343
  projectionScope,
35319
35344
  annotations2,
35345
+ void 0,
35320
35346
  visitedProjectionElements
35321
35347
  );
35322
35348
  }
35323
35349
  }
35324
35350
  }
35325
- function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
35351
+ function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, values, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
35326
35352
  addProjectedEdges(
35327
35353
  linkedEdges,
35328
35354
  sourceIdentity,
@@ -35335,7 +35361,8 @@ function addProjectedEdgesForValues(linkedEdges, sourceIdentity, fromId, toId, v
35335
35361
  typeSystem,
35336
35362
  diagnostics,
35337
35363
  projectionScope,
35338
- annotations2
35364
+ annotations2,
35365
+ projectedAttributes
35339
35366
  );
35340
35367
  }
35341
35368
  function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
@@ -35352,15 +35379,16 @@ function addEdgeScopes(scopesByCarrierId, attributes2, scope) {
35352
35379
  function isDirectSlotReferenceSelfProjection(element, fromId, toId) {
35353
35380
  return fromId === toId && element.parent === fromId && element.scalarAttributes.parentType !== void 0 && element.scalarAttributes.attributeName !== void 0;
35354
35381
  }
35355
- function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = []) {
35382
+ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, projectionElement, rule3, elementsById, resolvedElementAttributes, ownerIndependentProjectionKeys, typeSystem, diagnostics, projectionScope, annotations2 = [], projectedAttributes) {
35356
35383
  const sources = projectionTerm(rule3.source, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
35357
35384
  const targets = projectionTerm(rule3.target, fromId, toId, projectionElement, elementsById, resolvedElementAttributes, diagnostics);
35385
+ const carriedAttributes = rule3.source.kind === "from" ? projectedAttributes : void 0;
35358
35386
  for (const source of sources) {
35359
35387
  for (const target of targets) {
35360
35388
  if (!projectionRuleUsesOwner(rule3)) {
35361
35389
  const key = `${projectionElement.id}\0${source}\0${rule3.operator}\0${target}`;
35362
35390
  if (ownerIndependentProjectionKeys.has(key)) {
35363
- mergeProjectedEdgeAnnotations(linkedEdges, source, rule3.operator, target, annotations2);
35391
+ mergeProjectedEdge(linkedEdges, source, rule3.operator, target, annotations2, carriedAttributes);
35364
35392
  continue;
35365
35393
  }
35366
35394
  ownerIndependentProjectionKeys.add(key);
@@ -35369,6 +35397,18 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35369
35397
  const targetElement = elementsById.get(target);
35370
35398
  const operator = sourceElement === void 0 || targetElement === void 0 ? void 0 : typeSystem.operatorConstructor(rule3.operator, sourceElement.type, targetElement.type);
35371
35399
  const type = operator?.ownerType ?? rule3.operator;
35400
+ const existingIndex = linkedEdges.findIndex((edge) => edge.projected === true && edge.source === source && edge.operator === rule3.operator && edge.target === target && edge.projectionScope === projectionScope);
35401
+ if (existingIndex >= 0) {
35402
+ const edge = linkedEdges[existingIndex];
35403
+ if (edge !== void 0) {
35404
+ linkedEdges[existingIndex] = {
35405
+ ...edge,
35406
+ attributes: mergeAttributeValues(carriedAttributes, edge.attributes),
35407
+ annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
35408
+ };
35409
+ }
35410
+ continue;
35411
+ }
35372
35412
  linkedEdges.push({
35373
35413
  source,
35374
35414
  target,
@@ -35377,7 +35417,7 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35377
35417
  operator: rule3.operator,
35378
35418
  type,
35379
35419
  sourceIdentity,
35380
- attributes: {},
35420
+ attributes: carriedAttributes ?? {},
35381
35421
  ...listAttributesProperty(typeSystem, type),
35382
35422
  projected: true,
35383
35423
  ...projectionScope === void 0 ? {} : { projectionScope },
@@ -35386,8 +35426,8 @@ function addProjectedRuleEdge(linkedEdges, sourceIdentity, fromId, toId, project
35386
35426
  }
35387
35427
  }
35388
35428
  }
35389
- function mergeProjectedEdgeAnnotations(linkedEdges, source, operator, target, annotations2) {
35390
- if (annotations2.length === 0) {
35429
+ function mergeProjectedEdge(linkedEdges, source, operator, target, annotations2, attributes2) {
35430
+ if (annotations2.length === 0 && (attributes2 === void 0 || Object.keys(attributes2).length === 0)) {
35391
35431
  return;
35392
35432
  }
35393
35433
  const index = linkedEdges.findIndex((edge2) => edge2.projected === true && edge2.source === source && edge2.operator === operator && edge2.target === target);
@@ -35400,9 +35440,19 @@ function mergeProjectedEdgeAnnotations(linkedEdges, source, operator, target, an
35400
35440
  }
35401
35441
  linkedEdges[index] = {
35402
35442
  ...edge,
35443
+ attributes: mergeAttributeValues(attributes2, edge.attributes),
35403
35444
  annotations: uniqueAnnotations([...edge.annotations ?? [], ...annotations2])
35404
35445
  };
35405
35446
  }
35447
+ function mergeAttributeValues(base, override) {
35448
+ if (base === void 0 || Object.keys(base).length === 0) {
35449
+ return override;
35450
+ }
35451
+ if (Object.keys(override).length === 0) {
35452
+ return base;
35453
+ }
35454
+ return { ...base, ...override };
35455
+ }
35406
35456
  function uniqueAnnotations(annotations2) {
35407
35457
  const seen = /* @__PURE__ */ new Set();
35408
35458
  const result = [];
@@ -35427,6 +35477,12 @@ function referenceAttributesProperty(attributes2) {
35427
35477
  function projectionRuleUsesOwner(rule3) {
35428
35478
  return projectionTermUsesOwner(rule3.source) || projectionTermUsesOwner(rule3.target);
35429
35479
  }
35480
+ function projectionRuleUsesTo(rule3) {
35481
+ return projectionTermUsesTo(rule3.source) || projectionTermUsesTo(rule3.target);
35482
+ }
35483
+ function projectionTermUsesTo(term) {
35484
+ return term.kind === "to";
35485
+ }
35430
35486
  function projectionTermUsesOwner(term) {
35431
35487
  return term.kind === "from" || term.kind === "to" || term.kind === "slot";
35432
35488
  }
@@ -36018,7 +36074,8 @@ function applyDeploymentUsesCarrier(carrier, parent, context) {
36018
36074
  context.typeSystem,
36019
36075
  context.diagnostics,
36020
36076
  projectionScope,
36021
- annotations2
36077
+ annotations2,
36078
+ scope.projectedAttributes
36022
36079
  );
36023
36080
  }
36024
36081
  }
@@ -36202,14 +36259,14 @@ function nearestAncestor(element, elementsById, predicate) {
36202
36259
  }
36203
36260
  return void 0;
36204
36261
  }
36205
- function inspectGraph(graph, elements, edges, diagnostics) {
36262
+ function inspectGraph(graph, elements, edges, resolvedElementAttributes, diagnostics) {
36206
36263
  if (diagnostics.some((diagnostic) => diagnostic.level === void 0 || diagnostic.level === "ERROR")) {
36207
36264
  return;
36208
36265
  }
36209
- reportIsolatedElements(graph, elements, diagnostics);
36266
+ reportIsolatedElements(graph, elements, edges, resolvedElementAttributes, diagnostics);
36210
36267
  reportShadowedLowerLevelEdges(graph, edges, diagnostics);
36211
36268
  }
36212
- function reportIsolatedElements(graph, elements, diagnostics) {
36269
+ function reportIsolatedElements(graph, elements, edges, resolvedElementAttributes, diagnostics) {
36213
36270
  const referenced = /* @__PURE__ */ new Set();
36214
36271
  for (const relationId of graph.relationsOfKind("REFERENCES")) {
36215
36272
  const relation = graph.relation(relationId);
@@ -36218,6 +36275,21 @@ function reportIsolatedElements(graph, elements, diagnostics) {
36218
36275
  referenced.add(relation.target);
36219
36276
  }
36220
36277
  }
36278
+ for (const edge of edges) {
36279
+ referenced.add(edge.source);
36280
+ referenced.add(edge.target);
36281
+ }
36282
+ for (const [elementId, attributes2] of resolvedElementAttributes) {
36283
+ for (const values of Object.values(attributes2)) {
36284
+ if (values.length === 0) {
36285
+ continue;
36286
+ }
36287
+ referenced.add(elementId);
36288
+ for (const value of values) {
36289
+ referenced.add(value.id);
36290
+ }
36291
+ }
36292
+ }
36221
36293
  for (const element of elements) {
36222
36294
  if (element.anonymous || containsNestedElement(graph, element.id) || referenced.has(element.id)) {
36223
36295
  continue;
@@ -37776,7 +37848,7 @@ var QueryParser = class {
37776
37848
  };
37777
37849
 
37778
37850
  // src/version.ts
37779
- var version = "3.0.0-snapshot.4";
37851
+ var version = "3.0.0-snapshot.6";
37780
37852
 
37781
37853
  // src/index.ts
37782
37854
  var hiddenStructureTypes = /* @__PURE__ */ new Set(["List", "Nothing", "Text", "text"]);
@@ -37969,11 +38041,24 @@ async function runSkillInit(args, skillPackage) {
37969
38041
  const projectRoot = path.resolve(projectPath(args));
37970
38042
  const usesDefaultOutput = args.output === void 0;
37971
38043
  const outputRoot = path.resolve(projectRoot, args.output ?? skillPackage.defaultOutput);
38044
+ if (args.force && await exists(outputRoot)) {
38045
+ assertSafeSkillOutputRoot(projectRoot, outputRoot);
38046
+ await rm(outputRoot, { recursive: true, force: true });
38047
+ }
37972
38048
  for (const file of skillPackage.files) {
37973
38049
  await writeGeneratedFile(path.join(outputRoot, file.path), file.content, args.force);
37974
38050
  }
37975
38051
  process.stdout.write(skillPackageSuccess(projectRoot, outputRoot, skillPackage, usesDefaultOutput));
37976
38052
  }
38053
+ function assertSafeSkillOutputRoot(projectRoot, outputRoot) {
38054
+ if (outputRoot === path.parse(outputRoot).root || outputRoot === process.cwd() || outputRoot === projectRoot) {
38055
+ throw new CliError(`Refusing to delete unsafe skill output directory '${outputRoot}'. Choose a dedicated --out directory.`);
38056
+ }
38057
+ const projectRelativeToOutput = path.relative(outputRoot, projectRoot);
38058
+ if (projectRelativeToOutput !== "" && !projectRelativeToOutput.startsWith("..") && !path.isAbsolute(projectRelativeToOutput)) {
38059
+ throw new CliError(`Refusing to delete skill output directory '${outputRoot}' because it contains the project root.`);
38060
+ }
38061
+ }
37977
38062
  async function loadProject(input) {
37978
38063
  const root = path.resolve(input);
37979
38064
  const sources = await readSources(root);
@@ -38426,7 +38511,7 @@ Options:
38426
38511
  -o, --out <file> Write output to file instead of stdout; for skill init, write the guide directory.
38427
38512
  -t, --theme <theme> Render theme, default: light.
38428
38513
  --target <target> Skill target: generic, codex, or claude.
38429
- --force Replace existing generated skill files.
38514
+ --force Delete and recreate the generated skill directory.
38430
38515
  -V, --version Print version.
38431
38516
  -h, --help Show help.
38432
38517
 
@@ -38497,6 +38582,26 @@ function sharedSkillFiles() {
38497
38582
  path: "references/layered-architecture.md",
38498
38583
  content: genericLayeredArchitectureReference()
38499
38584
  },
38585
+ {
38586
+ path: "references/c1-context.md",
38587
+ content: genericC1ContextReference()
38588
+ },
38589
+ {
38590
+ path: "references/c2-containers.md",
38591
+ content: genericC2ContainersReference()
38592
+ },
38593
+ {
38594
+ path: "references/c3-components.md",
38595
+ content: genericC3ComponentsReference()
38596
+ },
38597
+ {
38598
+ path: "references/c4-deployment.md",
38599
+ content: genericC4DeploymentReference()
38600
+ },
38601
+ {
38602
+ path: "references/scaling.md",
38603
+ content: genericScalingReference()
38604
+ },
38500
38605
  {
38501
38606
  path: "references/project-structure.md",
38502
38607
  content: genericProjectStructureReference()
@@ -38513,14 +38618,58 @@ function sharedSkillFiles() {
38513
38618
  path: "references/queries.md",
38514
38619
  content: genericQueriesReference()
38515
38620
  },
38621
+ {
38622
+ path: "references/query-recipes.md",
38623
+ content: genericQueryRecipesReference()
38624
+ },
38516
38625
  {
38517
38626
  path: "examples/layered-architecture.ai",
38518
38627
  content: genericLayeredArchitectureExample()
38519
38628
  },
38629
+ {
38630
+ path: "examples/c1-context.ai",
38631
+ content: genericC1ContextExample()
38632
+ },
38633
+ {
38634
+ path: "examples/c2-containers.ai",
38635
+ content: genericC2ContainersExample()
38636
+ },
38637
+ {
38638
+ path: "examples/c3-components.ai",
38639
+ content: genericC3ComponentsExample()
38640
+ },
38641
+ {
38642
+ path: "examples/c4-deployment-framework.ai",
38643
+ content: genericC4DeploymentFrameworkExample()
38644
+ },
38645
+ {
38646
+ path: "examples/c4-deployment.ai",
38647
+ content: genericC4DeploymentExample()
38648
+ },
38520
38649
  {
38521
38650
  path: "examples/c2-containers.aiq",
38522
38651
  content: genericC2QueryExample()
38523
38652
  },
38653
+ {
38654
+ path: "examples/builtin-views/no-filter.aiq",
38655
+ content: noFilterQuery
38656
+ },
38657
+ {
38658
+ path: "examples/builtin-views/c1.aiq",
38659
+ content: c1Query
38660
+ },
38661
+ {
38662
+ path: "examples/builtin-views/c2.aiq",
38663
+ content: c2Query
38664
+ },
38665
+ {
38666
+ path: "examples/builtin-views/c3.aiq",
38667
+ content: c3Query
38668
+ },
38669
+ {
38670
+ path: "examples/builtin-views/c4.aiq",
38671
+ content: c4Query
38672
+ },
38524
38673
  ...coreSkillFiles()
38525
38674
  ];
38526
38675
  }
@@ -38583,8 +38732,13 @@ If \`archinsight\` is not available, ask the user to install or expose
38583
38732
  2. Preserve indentation and the project's existing naming style.
38584
38733
  3. Model architecture from the outside inward: context, external actors/systems,
38585
38734
  systems, containers/services, components, and deployment details.
38586
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38587
- 5. Validate every Insight change with \`archinsight link . --format text\`.
38735
+ 4. When the task touches infrastructure, runtime placement, regions, or
38736
+ deployment, decide per system whether pragmatic mixed C2 or clean
38737
+ C4/deployment is appropriate.
38738
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38739
+ 6. Keep definition/framework files separate from model files that declare
38740
+ \`context <id>\`.
38741
+ 7. Validate every Insight change with \`archinsight link . --format text\`.
38588
38742
 
38589
38743
  ## References
38590
38744
 
@@ -38593,12 +38747,25 @@ If \`archinsight\` is not available, ask the user to install or expose
38593
38747
  - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
38594
38748
  - Read \`references/layered-architecture.md\` when decomposing a system across
38595
38749
  C1/C2/C3/C4-style layers.
38750
+ - Read \`references/c1-context.md\` when adding or repairing system context
38751
+ models: actors, owned systems, external systems, and boundary choices.
38752
+ - Read \`references/c2-containers.md\` when adding or repairing
38753
+ container/service-level C2 models for a selected system.
38754
+ - Read \`references/c3-components.md\` when adding or repairing component-level
38755
+ C3 models for a selected container or service.
38756
+ - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38757
+ models, infrastructure inventories, environment-scoped infrastructure, or
38758
+ projection rules.
38759
+ - Read \`references/scaling.md\` when splitting a repository into reusable
38760
+ framework, environment, profile, system, or deployment-view files.
38596
38761
  - Read \`references/project-structure.md\` before searching for declarations,
38597
38762
  planning imports, or making broad edits.
38598
38763
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38599
38764
  attributes, presentations, or projections.
38600
38765
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38601
38766
  files.
38767
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
38768
+ element/edge or needs customization.
38602
38769
  - Read \`references/validation.md\` before running checks, structure inspection,
38603
38770
  or rendering.
38604
38771
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38626,12 +38793,25 @@ Treat this \`SKILL.md\` as the entrypoint. Load reference files only when needed
38626
38793
  - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
38627
38794
  - Read \`references/layered-architecture.md\` before decomposing a system across
38628
38795
  C1/C2/C3/C4-style layers.
38796
+ - Read \`references/c1-context.md\` before adding or repairing system context
38797
+ models: actors, owned systems, external systems, and boundary choices.
38798
+ - Read \`references/c2-containers.md\` before adding or repairing
38799
+ container/service-level C2 models for a selected system.
38800
+ - Read \`references/c3-components.md\` before adding or repairing component-level
38801
+ C3 models for a selected container or service.
38802
+ - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
38803
+ models, infrastructure inventories, environment-scoped infrastructure, or
38804
+ projection rules.
38805
+ - Read \`references/scaling.md\` before splitting a repository into reusable
38806
+ framework, environment, profile, system, or deployment-view files.
38629
38807
  - Read \`references/project-structure.md\` before searching for declarations,
38630
38808
  planning imports, or making broad edits.
38631
38809
  - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
38632
38810
  constructors, attributes, presentations, or projections.
38633
38811
  - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
38634
38812
  files.
38813
+ - Read \`references/query-recipes.md\` before customizing a built-in view or
38814
+ explaining why an expected element/edge is hidden.
38635
38815
  - Read \`references/validation.md\` before running checks, structure inspection,
38636
38816
  or rendering commands.
38637
38817
 
@@ -38658,11 +38838,16 @@ If \`archinsight\` is not available, ask the user to install or expose
38658
38838
  2. Preserve indentation and the project's existing naming style.
38659
38839
  3. Model architecture from the outside inward: context, external actors/systems,
38660
38840
  systems, containers/services, components, and deployment details.
38661
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38662
- 5. Use \`archinsight structure . --format text\` before broad edits when the
38841
+ 4. When the task touches infrastructure, runtime placement, regions, or
38842
+ deployment, decide per system whether pragmatic mixed C2 or clean
38843
+ C4/deployment is appropriate.
38844
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38845
+ 6. Keep definition/framework files separate from model files that declare
38846
+ \`context <id>\`.
38847
+ 7. Use \`archinsight structure . --format text\` before broad edits when the
38663
38848
  project shape is unclear.
38664
- 6. Validate every Insight change with \`archinsight link . --format text\`.
38665
- 7. If validation fails, fix the first real syntax/type/linking error before
38849
+ 8. Validate every Insight change with \`archinsight link . --format text\`.
38850
+ 9. If validation fails, fix the first real syntax/type/linking error before
38666
38851
  adding more model content.
38667
38852
 
38668
38853
  ## References
@@ -38672,12 +38857,25 @@ If \`archinsight\` is not available, ask the user to install or expose
38672
38857
  - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
38673
38858
  - Read \`references/layered-architecture.md\` when decomposing a system across
38674
38859
  C1/C2/C3/C4-style layers.
38860
+ - Read \`references/c1-context.md\` when adding or repairing system context
38861
+ models: actors, owned systems, external systems, and boundary choices.
38862
+ - Read \`references/c2-containers.md\` when adding or repairing
38863
+ container/service-level C2 models for a selected system.
38864
+ - Read \`references/c3-components.md\` when adding or repairing component-level
38865
+ C3 models for a selected container or service.
38866
+ - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38867
+ models, infrastructure inventories, environment-scoped infrastructure, or
38868
+ projection rules.
38869
+ - Read \`references/scaling.md\` when splitting a repository into reusable
38870
+ framework, environment, profile, system, or deployment-view files.
38675
38871
  - Read \`references/project-structure.md\` before searching for declarations,
38676
38872
  planning imports, or making broad edits.
38677
38873
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38678
38874
  attributes, presentations, or projections.
38679
38875
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38680
38876
  files.
38877
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
38878
+ element/edge or needs customization.
38681
38879
  - Read \`references/validation.md\` before running checks, structure inspection,
38682
38880
  or rendering.
38683
38881
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38706,12 +38904,25 @@ they are needed:
38706
38904
  - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
38707
38905
  - Read \`references/layered-architecture.md\` before decomposing a system across
38708
38906
  C1/C2/C3/C4-style layers.
38907
+ - Read \`references/c1-context.md\` before adding or repairing system context
38908
+ models: actors, owned systems, external systems, and boundary choices.
38909
+ - Read \`references/c2-containers.md\` before adding or repairing
38910
+ container/service-level C2 models for a selected system.
38911
+ - Read \`references/c3-components.md\` before adding or repairing component-level
38912
+ C3 models for a selected container or service.
38913
+ - Read \`references/c4-deployment.md\` before adding or repairing deployment/C4
38914
+ models, infrastructure inventories, environment-scoped infrastructure, or
38915
+ projection rules.
38916
+ - Read \`references/scaling.md\` before splitting a repository into reusable
38917
+ framework, environment, profile, system, or deployment-view files.
38709
38918
  - Read \`references/project-structure.md\` before searching for declarations,
38710
38919
  planning imports, or making broad edits.
38711
38920
  - Read \`references/core.md\` and \`.core/*.ai\` before assuming available
38712
38921
  constructors, attributes, presentations, or projections.
38713
38922
  - Read \`references/queries.md\` before writing custom diagram queries or \`.aiq\`
38714
38923
  files.
38924
+ - Read \`references/query-recipes.md\` before customizing a built-in view or
38925
+ explaining why an expected element/edge is hidden.
38715
38926
  - Read \`references/validation.md\` before asking the user to run validation,
38716
38927
  structure inspection, or rendering commands.
38717
38928
 
@@ -38738,12 +38949,17 @@ install or expose \`@archinsight/cli\` before changing \`.ai\` files.
38738
38949
  2. Preserve indentation and the project's existing naming style.
38739
38950
  3. Model architecture from the outside inward: context, external actors/systems,
38740
38951
  systems, containers/services, components, and deployment details.
38741
- 4. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38742
- 5. Use \`archinsight structure . --format text\` to inspect the current model
38952
+ 4. When the task touches infrastructure, runtime placement, regions, or
38953
+ deployment, decide per system whether pragmatic mixed C2 or clean
38954
+ C4/deployment is appropriate.
38955
+ 5. Prefer small, focused files connected by \`context\`, \`import\`, and \`extend\`.
38956
+ 6. Keep definition/framework files separate from model files that declare
38957
+ \`context <id>\`.
38958
+ 7. Use \`archinsight structure . --format text\` to inspect the current model
38743
38959
  before broad edits when the CLI is available.
38744
- 6. Validate every Insight change with \`archinsight link . --format text\` when
38960
+ 8. Validate every Insight change with \`archinsight link . --format text\` when
38745
38961
  shell access is available; otherwise ask the user to run validation.
38746
- 7. If validation fails, fix the first real syntax/type/linking error before
38962
+ 9. If validation fails, fix the first real syntax/type/linking error before
38747
38963
  adding more model content.
38748
38964
 
38749
38965
  ## Communication
@@ -38772,12 +38988,25 @@ sections of Insight unless the existing layering is already understood.
38772
38988
  - Read \`references/syntax.md\` before writing unfamiliar Insight syntax.
38773
38989
  - Read \`references/layered-architecture.md\` when decomposing a system across
38774
38990
  C1/C2/C3/C4-style layers.
38991
+ - Read \`references/c1-context.md\` when adding or repairing system context
38992
+ models: actors, owned systems, external systems, and boundary choices.
38993
+ - Read \`references/c2-containers.md\` when adding or repairing
38994
+ container/service-level C2 models for a selected system.
38995
+ - Read \`references/c3-components.md\` when adding or repairing component-level
38996
+ C3 models for a selected container or service.
38997
+ - Read \`references/c4-deployment.md\` when adding or repairing deployment/C4
38998
+ models, infrastructure inventories, environment-scoped infrastructure, or
38999
+ projection rules.
39000
+ - Read \`references/scaling.md\` when splitting a repository into reusable
39001
+ framework, environment, profile, system, or deployment-view files.
38775
39002
  - Read \`references/project-structure.md\` before searching for declarations,
38776
39003
  planning imports, or making broad edits.
38777
39004
  - Read \`references/core.md\` and \`.core/*.ai\` when checking built-in types,
38778
39005
  attributes, presentations, or projections.
38779
39006
  - Read \`references/queries.md\` when writing custom diagram queries or \`.aiq\`
38780
39007
  files.
39008
+ - Read \`references/query-recipes.md\` when a built-in view hides an expected
39009
+ element/edge or needs customization.
38781
39010
  - Read \`references/validation.md\` before running checks, structure inspection,
38782
39011
  or rendering.
38783
39012
  - Use \`examples/layered-architecture.ai\` as a compact valid model.
@@ -38799,6 +39028,40 @@ function genericModelingReference() {
38799
39028
  Insight syntax is small; most mistakes are modeling mistakes. Decide the view
38800
39029
  question before changing files.
38801
39030
 
39031
+ ## Separate Definitions From Model Sources
39032
+
39033
+ Keep language/framework definitions separate from graph model files.
39034
+
39035
+ - Definition/framework files contain \`define type\`, \`define operator\`,
39036
+ \`define presentation\`, \`extend type\`, \`extend enum of\`, and
39037
+ \`extend presentation\`.
39038
+ - Model files declare \`context <id>\` and create graph objects with
39039
+ constructors such as \`system\`, \`service\`, \`component\`, \`environment\`,
39040
+ or \`deploymentProfile\`.
39041
+
39042
+ Do not mix definition declarations and \`context\` declarations in one source
39043
+ file. Put shared vocabulary in a framework file, then put concrete contexts,
39044
+ systems, environments, profiles, and links in model files. This keeps schema
39045
+ changes reviewable and avoids source-level syntax failures.
39046
+
39047
+ ## Model Source Granularity
39048
+
39049
+ Default to one primary owned system per model source file: the system you are
39050
+ about to detail with containers, services, components, and deployment
39051
+ relationships. This keeps the selected source file useful as a C2/C3/C4 view
39052
+ scope and avoids accidental mega-files.
39053
+
39054
+ Do not create one file per external actor or external system. Shared external
39055
+ dependencies are usually better modeled once in a reusable external context, or
39056
+ in a few external contexts grouped by meaning such as \`external_platforms\`,
39057
+ \`partners\`, or \`regulators\`. Import those shared declarations from system
39058
+ files that need them.
39059
+
39060
+ If a user asks for deeper splitting, use \`extend <object>\` files for the
39061
+ detail being extracted. For example, keep the main service file readable and put
39062
+ large per-service component sets in a small utility subdirectory for that
39063
+ context.
39064
+
38802
39065
  ## Projections Are Bottom-Up
38803
39066
 
38804
39067
  Built-in C1/C2/C3/C4 views are selected from the linked model. They are not
@@ -38862,14 +39125,30 @@ type hierarchy:
38862
39125
  If a nested declaration fails type checking, fix the type/ownership model rather
38863
39126
  than forcing a link or inventing a wrapper element.
38864
39127
 
38865
- ## Keep Infrastructure in the Right View
39128
+ ## Choose Infrastructure Depth Per System
39129
+
39130
+ Do not force every project into C4/deployment on the first pass. Most modeling
39131
+ work can proceed through C1-C3 without asking about deployment depth. When the
39132
+ task first touches infrastructure, runtime placement, regions, compute, brokers,
39133
+ gateways, storage, or deployment, ask the user or infer from the repository
39134
+ whether the affected system needs a pragmatic mixed C2 view or a clean
39135
+ C4/deployment model.
38866
39136
 
38867
- Do not transcribe infrastructure into C2 just because another diagram drew it
38868
- there. Databases, queues, secret stores, compute nodes, gateways, and runtime
38869
- placement are usually deployment/C4 concerns unless the project defines them as
38870
- part of the selected view.
39137
+ Pragmatic mixed C2 is fast: model databases, brokers, gateways, or secret stores
39138
+ next to services when the user wants a quick single-environment diagram. The
39139
+ cost is that C2 now mixes logical containers with infrastructure, and C4 is
39140
+ effectively absent for that system.
38871
39141
 
38872
- Use deployment types and projection queries when physical realization matters.
39142
+ Clean C4 keeps C2 logical and moves physical realization into deployment
39143
+ profiles, environments, inventory slots, and projection rules. This is more work
39144
+ up front, but it supports many-to-many deployment: one logical service can run
39145
+ in several environments whose infrastructure differs by region, provider, or
39146
+ organizational boundary.
39147
+
39148
+ This choice is per-system, not global. A critical system can use clean C4 while
39149
+ peripheral systems stay pragmatic in C2. Starting cheap is acceptable, but know
39150
+ that upgrading mixed C2 infrastructure into clean C4 is a migration, not just an
39151
+ extra attribute.
38873
39152
 
38874
39153
  ## Eventing
38875
39154
 
@@ -38877,8 +39156,10 @@ Use \`~>\` for asynchronous relationships. Model one async wire per meaningful
38877
39156
  topic or event flow between real producer and consumer elements.
38878
39157
 
38879
39158
  Do not invent a broker node just to make the diagram look familiar. If the
38880
- broker is deployment infrastructure, model it in deployment/C4. If the producer
38881
- or consumer is not known, leave a gap and report it instead of fabricating an
39159
+ chosen style is clean C4 and the broker is deployment infrastructure, model it
39160
+ in deployment/C4. If the chosen style is pragmatic mixed C2, a broker-like node
39161
+ can be acceptable, but document that the view mixes levels. If the producer or
39162
+ consumer is not known, leave a gap and report it instead of fabricating an
38882
39163
  element.
38883
39164
 
38884
39165
  ## No Fabricated Elements
@@ -38962,6 +39243,11 @@ Definition files are different from model files. They declare vocabulary:
38962
39243
  \`extend enum of\`, and \`extend presentation\`. Model files usually start with
38963
39244
  \`context <id>\` and then create graph object instances with constructors.
38964
39245
 
39246
+ Do not mix these source forms in one file. A framework/definitions file should
39247
+ contain only vocabulary/schema declarations. A model file should declare a
39248
+ \`context <id>\` and graph object instances. If both are needed, create two
39249
+ files and validate the whole project.
39250
+
38965
39251
  ## Type Definitions and Extensions
38966
39252
 
38967
39253
  Use \`define type\` to create a new graph/value type. Use \`extend type\` to add
@@ -39121,8 +39407,8 @@ label feature.
39121
39407
  Projects can extend the language with typed vocabulary:
39122
39408
 
39123
39409
  \`\`\`insight
39124
- define type Broker of InfrastructureComponent
39125
- constructor broker
39410
+ define type Cache of InfrastructureComponent
39411
+ constructor cache
39126
39412
  \`\`\`
39127
39413
 
39128
39414
  When adding custom types, follow the existing framework files and validate
@@ -39138,7 +39424,8 @@ layer useful on its own.
39138
39424
 
39139
39425
  ## C1: System Context
39140
39426
 
39141
- Start with the context, people, owned systems, and external dependencies.
39427
+ Start with the context, people, owned systems, and external dependencies. Read
39428
+ \`references/c1-context.md\` before writing a real C1 model.
39142
39429
 
39143
39430
  \`\`\`insight
39144
39431
  context ecommerce
@@ -39165,7 +39452,8 @@ which external dependencies matter. Whether a peer is an owned \`system\`, an
39165
39452
 
39166
39453
  ## C2: Containers and Services
39167
39454
 
39168
- Nest deployable units under the owned system:
39455
+ Nest deployable units under the owned system. Read
39456
+ \`references/c2-containers.md\` before writing a real C2 model.
39169
39457
 
39170
39458
  \`\`\`insight
39171
39459
  system storefront
@@ -39191,8 +39479,9 @@ the selected source file.
39191
39479
 
39192
39480
  ## C3: Components
39193
39481
 
39194
- Put component details in a separate file with \`extend\` when the service becomes
39195
- interesting enough to decompose:
39482
+ Put component details in a separate file with \`extend\` when a container or
39483
+ service becomes interesting enough to decompose. Read
39484
+ \`references/c3-components.md\` before writing a real C3 model.
39196
39485
 
39197
39486
  \`\`\`insight
39198
39487
  context ecommerce
@@ -39218,7 +39507,7 @@ can intentionally choose a different scope.
39218
39507
  ## C4 and Deployment
39219
39508
 
39220
39509
  Use deployment profiles and infrastructure types when physical realization is
39221
- important:
39510
+ important. Read \`references/c4-deployment.md\` before writing a real C4 model.
39222
39511
 
39223
39512
  \`\`\`insight
39224
39513
  deploymentProfile production
@@ -39229,9 +39518,12 @@ environment eu
39229
39518
  name = Europe
39230
39519
  \`\`\`
39231
39520
 
39232
- Attach deployment details to systems, containers, services, or links only when
39233
- they clarify real runtime paths.
39234
- C4/deployment files often focus one deployment slice, but the rendered scope is
39521
+ Attach deployment details to systems, containers, services, components, or links
39522
+ only when they clarify real runtime paths. Prefer attaching deployment to C2
39523
+ containers/services when possible because C2 is usually the most representative
39524
+ logical runtime boundary.
39525
+
39526
+ C4/deployment files often focus one deployment slice. The rendered scope is
39235
39527
  defined by the query, projection selectors, and selected source file.
39236
39528
 
39237
39529
  ## Layering Rules
@@ -39246,6 +39538,1618 @@ defined by the query, projection selectors, and selected source file.
39246
39538
  - Validate after each layer before adding the next.
39247
39539
  `;
39248
39540
  }
39541
+ function genericC1ContextReference() {
39542
+ return `# C1 System Context
39543
+
39544
+ Use this reference only for C1 work: modeling a bounded context, its users,
39545
+ owned systems, external systems, and high-level relationships.
39546
+
39547
+ ## What C1 Answers
39548
+
39549
+ A C1 view answers: "What system are we discussing, who uses it, and which
39550
+ outside systems does it depend on?"
39551
+
39552
+ Do not include containers, services, components, databases, queues, or runtime
39553
+ nodes unless the project deliberately treats them as context-level systems. C1
39554
+ is about boundaries and responsibilities, not implementation structure.
39555
+
39556
+ ## C1 Workflow
39557
+
39558
+ 1. Name the bounded \`context <id>\`.
39559
+ 2. Add external actors that initiate or consume behavior.
39560
+ 3. Add owned \`system\` declarations inside the modeled boundary.
39561
+ 4. Add \`external system\` declarations for dependencies outside the boundary.
39562
+ 5. Add high-level links that explain business or capability flow.
39563
+ 6. Validate with \`archinsight link . --format text\`.
39564
+ 7. Render with \`archinsight render . -c <context-id> -v c1 -f svg -o c1.svg\`.
39565
+
39566
+ ## Boundary Choices
39567
+
39568
+ Choose the modeled boundary before choosing constructors.
39569
+
39570
+ - Use \`system\` for systems owned inside the current context.
39571
+ - Use \`external system\` for systems outside the current context boundary.
39572
+ - Use \`external actor\` for people, roles, teams, or external automation that
39573
+ interacts with the system from outside.
39574
+ - Use \`import <id> from context <context-id>\` when a reusable outside system is
39575
+ declared in another context.
39576
+
39577
+ Externality is relative. A system can be external to the current system but
39578
+ still owned in the same context. A vendor platform or regulator is usually
39579
+ external to the context.
39580
+
39581
+ ## Basic C1 Pattern
39582
+
39583
+ \`\`\`insight
39584
+ context commerce
39585
+ name = Commerce Platform
39586
+
39587
+ external actor shopper
39588
+ name = Shopper
39589
+ technology = Browser
39590
+ description = Browses products and places orders
39591
+ links:
39592
+ -> storefront
39593
+ description = Shops and checks out
39594
+
39595
+ external actor support_agent
39596
+ name = Support agent
39597
+ technology = Back-office browser
39598
+ description = Helps customers investigate orders
39599
+ links:
39600
+ -> order_admin
39601
+ description = Looks up order state and customer communication
39602
+
39603
+ external system payment_provider
39604
+ name = Payment Provider
39605
+ technology = HTTPS API
39606
+ description = Authorizes card payments
39607
+
39608
+ system storefront
39609
+ name = Storefront
39610
+ technology = Web application
39611
+ description = Lets shoppers browse products and place orders
39612
+ links:
39613
+ -> payment_provider
39614
+ technology = HTTPS
39615
+ description = Requests payment authorization
39616
+
39617
+ system order_admin
39618
+ name = Order Admin
39619
+ technology = Internal web application
39620
+ description = Lets support staff inspect and manage orders
39621
+ links:
39622
+ -> storefront
39623
+ description = Reads customer order data
39624
+ \`\`\`
39625
+
39626
+ ## Owned Peer Pattern
39627
+
39628
+ Do not make every peer \`external system\`. If two systems are owned inside the
39629
+ same architecture boundary, keep both as \`system\` and link them:
39630
+
39631
+ \`\`\`insight
39632
+ context company_platform
39633
+ name = Company Platform
39634
+
39635
+ system fintech
39636
+ name = Fintech
39637
+ description = Payment and account capabilities
39638
+
39639
+ system compliance
39640
+ name = Compliance
39641
+ description = Compliance rules, audit, and reporting
39642
+ links:
39643
+ -> fintech
39644
+ description = Reads transactions for screening and reporting
39645
+ \`\`\`
39646
+
39647
+ Here \`fintech\` can be outside the compliance team boundary, but it is not
39648
+ outside the company platform context. Use the context boundary, not team
39649
+ ownership alone, to decide \`system\` vs \`external system\`.
39650
+
39651
+ ## Reusable External Context Pattern
39652
+
39653
+ When the same outside dependency appears in many contexts, declare it once and
39654
+ import it:
39655
+
39656
+ \`\`\`insight
39657
+ context external_platforms
39658
+
39659
+ external system stripe
39660
+ name = Stripe
39661
+ technology = HTTPS API
39662
+ description = External payment platform
39663
+ \`\`\`
39664
+
39665
+ \`\`\`insight
39666
+ context commerce
39667
+
39668
+ import stripe from context external_platforms
39669
+
39670
+ system storefront
39671
+ name = Storefront
39672
+ links:
39673
+ -> stripe from external_platforms
39674
+ technology = HTTPS
39675
+ description = Requests payment authorization
39676
+ \`\`\`
39677
+
39678
+ Use imports for shared declarations; do not duplicate the same vendor system in
39679
+ every context unless the project intentionally wants separate local identities.
39680
+
39681
+ ## C1 Links
39682
+
39683
+ Links should be high-level and readable:
39684
+
39685
+ \`\`\`insight
39686
+ links:
39687
+ -> storefront
39688
+ description = Places orders
39689
+ \`\`\`
39690
+
39691
+ Add \`technology\`, \`call\`, or \`via\` only when the detail is stable and useful
39692
+ at context level. Prefer capability language over endpoint trivia.
39693
+
39694
+ Use \`~>\` for meaningful asynchronous context flows:
39695
+
39696
+ \`\`\`insight
39697
+ links:
39698
+ ~> analytics_platform
39699
+ technology = Kafka
39700
+ via = order.completed
39701
+ description = Publishes completed order events
39702
+ \`\`\`
39703
+
39704
+ ## What Not To Put In C1
39705
+
39706
+ - Internal containers such as \`web_app\`, \`api\`, or \`worker\`.
39707
+ - Components, classes, packages, screens, handlers, or repositories.
39708
+ - Databases, queues, pods, nodes, gateways, or regions unless modeled as
39709
+ context-level systems.
39710
+ - Low-level calls between internals.
39711
+ - Placeholder systems invented only to make the diagram symmetric.
39712
+
39713
+ ## Common C1 Mistakes
39714
+
39715
+ - Treating a peer owned in the same context as \`external system\`.
39716
+ - Duplicating imported external systems instead of importing the shared
39717
+ declaration.
39718
+ - Adding implementation details that belong to C2/C3/C4.
39719
+ - Drawing a relationship without naming what capability or dependency it means.
39720
+ - Choosing constructors before deciding the context boundary.
39721
+
39722
+ ## Validation Commands
39723
+
39724
+ \`\`\`shell
39725
+ archinsight structure . --format text
39726
+ archinsight link . --format text
39727
+ archinsight render . -c commerce -v c1 -f svg -o commerce-c1.svg
39728
+ \`\`\`
39729
+
39730
+ Use \`examples/c1-context.ai\` as a compact valid C1 model when syntax is
39731
+ unclear.
39732
+ `;
39733
+ }
39734
+ function genericC2ContainersReference() {
39735
+ return `# C2 Containers and Services
39736
+
39737
+ Use this reference only for C2 work: decomposing one selected owned system into
39738
+ deployable containers, backend services, and their runtime collaborations.
39739
+
39740
+ ## What C2 Answers
39741
+
39742
+ A C2 view answers: "Inside this system, which deployable or executable units
39743
+ exist, what technologies do they use, and how do they collaborate?"
39744
+
39745
+ Prefer one focal system per C2 source file. The built-in C2 view is scoped by
39746
+ the selected source file, so a C2 file should usually contain the selected
39747
+ \`system <id>\` declaration or an \`extend system <id>\` block with its
39748
+ containers/services.
39749
+
39750
+ ## C2 Purity vs Pragmatic Infrastructure
39751
+
39752
+ The clean C2 answer is logical: deployable containers/services and how they
39753
+ collaborate. In that mode, databases, brokers, gateways, vaults, compute, and
39754
+ regions belong to C4/deployment.
39755
+
39756
+ Archinsight does not force that choice. For a quick or single-environment model,
39757
+ it is acceptable to put simple infrastructure-like runtime nodes into C2 when
39758
+ the user wants speed over strict layer separation. Be explicit about the
39759
+ tradeoff: the C2 view becomes mixed, C4 is not really modeled for that system,
39760
+ and many-to-many deployment across different environments will not be available
39761
+ until the model is migrated to clean C4.
39762
+
39763
+ Choose this per system. Do not make the whole repository clean or mixed just
39764
+ because one system needs that style.
39765
+
39766
+ ## C2 Workflow
39767
+
39768
+ 1. Run \`archinsight structure . --format text\` to find the exact system id,
39769
+ existing containers/services, and external declarations.
39770
+ 2. Create or edit a C2 file in the same \`context <id>\`.
39771
+ 3. Import external systems from other contexts when needed.
39772
+ 4. Add \`container\` declarations for deployable applications or executables.
39773
+ 5. Add \`service\` declarations for backend services or service-like runtime
39774
+ units.
39775
+ 6. Add runtime links between containers/services and real external systems.
39776
+ 7. Validate with \`archinsight link . --format text\`.
39777
+ 8. Render with \`archinsight render . -c <context-id> -s <c2-file.ai> -v c2 -f svg -o c2.svg\`.
39778
+
39779
+ ## File Split Pattern
39780
+
39781
+ Keep C1 focused on the system boundary:
39782
+
39783
+ \`\`\`insight
39784
+ context commerce
39785
+ name = Commerce Platform
39786
+
39787
+ external system payment_provider
39788
+ name = Payment Provider
39789
+ technology = HTTPS API
39790
+
39791
+ system storefront
39792
+ name = Storefront
39793
+ technology = Commerce system
39794
+ description = Lets shoppers browse products and place orders
39795
+ \`\`\`
39796
+
39797
+ Put C2 details in a system file:
39798
+
39799
+ \`\`\`insight
39800
+ context commerce
39801
+
39802
+ extend system storefront
39803
+ container web_app
39804
+ name = Web app
39805
+ technology = SvelteKit, TypeScript
39806
+ description = Renders product pages and checkout screens
39807
+ links:
39808
+ -> checkout_api
39809
+ technology = HTTPS, JSON
39810
+ call = POST /checkout
39811
+ description = Starts checkout and shows order status
39812
+
39813
+ service checkout_api
39814
+ name = Checkout API
39815
+ technology = Kotlin, PostgreSQL
39816
+ description = Prices carts, creates orders, and coordinates payment
39817
+ links:
39818
+ -> payment_provider
39819
+ technology = HTTPS
39820
+ call = POST /payments/authorizations
39821
+ description = Requests payment authorization
39822
+ \`\`\`
39823
+
39824
+ ## Frontend and Backend Pattern
39825
+
39826
+ Use \`container\` for applications and executables that have an addressable
39827
+ runtime boundary:
39828
+
39829
+ \`\`\`insight
39830
+ container web_app
39831
+ name = Web app
39832
+ technology = SvelteKit, TypeScript
39833
+ description = Browser-facing application for customers
39834
+ \`\`\`
39835
+
39836
+ Use \`service\` for backend services and service-like runtime units:
39837
+
39838
+ \`\`\`insight
39839
+ service checkout_api
39840
+ name = Checkout API
39841
+ technology = Kotlin, PostgreSQL
39842
+ description = Coordinates checkout and payment authorization
39843
+ \`\`\`
39844
+
39845
+ Do not turn every library, package, or class into a C2 node. Those belong to C3
39846
+ only when they become stable architectural responsibilities.
39847
+
39848
+ ## External System Pattern
39849
+
39850
+ For an external dependency declared in the same context:
39851
+
39852
+ \`\`\`insight
39853
+ external system payment_provider
39854
+ name = Payment Provider
39855
+ technology = HTTPS API
39856
+
39857
+ system storefront
39858
+ name = Storefront
39859
+
39860
+ service checkout_api
39861
+ name = Checkout API
39862
+ links:
39863
+ -> payment_provider
39864
+ technology = HTTPS
39865
+ call = POST /payments/authorizations
39866
+ \`\`\`
39867
+
39868
+ For a dependency declared in another context, import it:
39869
+
39870
+ \`\`\`insight
39871
+ context commerce
39872
+
39873
+ import stripe from context external_platforms
39874
+
39875
+ extend system storefront
39876
+ service checkout_api
39877
+ name = Checkout API
39878
+ links:
39879
+ -> stripe from external_platforms
39880
+ technology = HTTPS
39881
+ call = POST /payments/authorizations
39882
+ \`\`\`
39883
+
39884
+ Do not copy an outside system into the current context just to satisfy a link.
39885
+ Import the real declaration when it is shared.
39886
+
39887
+ ## Async and Eventing Pattern
39888
+
39889
+ Use \`~>\` for meaningful asynchronous relationships:
39890
+
39891
+ \`\`\`insight
39892
+ service checkout_api
39893
+ name = Checkout API
39894
+ links:
39895
+ ~> analytics_platform
39896
+ technology = Kafka
39897
+ via = checkout.completed
39898
+ description = Publishes completed checkout events
39899
+ \`\`\`
39900
+
39901
+ Do not add a broker node just to make an event diagram look familiar. In clean
39902
+ C2, a broker is usually deployment/C4 infrastructure unless the project defines
39903
+ it as a runtime system or service in the selected view. In pragmatic mixed C2,
39904
+ adding a broker can be acceptable for a quick view, but it means the diagram is
39905
+ no longer strictly logical C2.
39906
+
39907
+ ## C2 Link Details
39908
+
39909
+ Use link attributes to make runtime collaboration understandable:
39910
+
39911
+ \`\`\`insight
39912
+ links:
39913
+ -> checkout_api
39914
+ technology = HTTPS, JSON
39915
+ call = POST /checkout
39916
+ description = Starts checkout and returns order status
39917
+ \`\`\`
39918
+
39919
+ \`call\` is singular. Use \`via\` for async topics or channels. Keep endpoint
39920
+ details at C2 only when they clarify the architecture; otherwise use a plain
39921
+ \`description\`.
39922
+
39923
+ ## What Not To Put In C2
39924
+
39925
+ - Components, classes, handlers, repositories, or UI widgets.
39926
+ - Deployment nodes, pods, regions, network gateways, or secret stores in clean
39927
+ C2. Include them only when the user intentionally wants pragmatic mixed C2 or
39928
+ the project models them as C2 runtime systems.
39929
+ - Database tables and internal schemas.
39930
+ - One-off scripts or build-time tools unless they are real runtime units.
39931
+ - Duplicate links already represented at a lower C3 level unless the C2 view is
39932
+ intentionally showing the rollup.
39933
+
39934
+ ## Common C2 Mistakes
39935
+
39936
+ - Adding C2 nodes directly under \`context\` instead of under a \`system\`.
39937
+ - Modeling infrastructure in C2 without deciding that the system is using the
39938
+ pragmatic mixed-C2 style.
39939
+ - Mixing C2 container/service links with C3 component links in the same source
39940
+ file without a clear view goal.
39941
+ - Forgetting \`--source <c2-file.ai>\` when rendering C2.
39942
+ - Making every peer an \`external system\` instead of deciding whether it is
39943
+ owned in the current context.
39944
+
39945
+ ## Validation Commands
39946
+
39947
+ \`\`\`shell
39948
+ archinsight structure . --format text
39949
+ archinsight link . --format text
39950
+ archinsight render . -c commerce -s storefront-containers.ai -v c2 -f svg -o storefront-c2.svg
39951
+ \`\`\`
39952
+
39953
+ Use \`examples/c2-containers.ai\` as a compact valid C2 model when syntax is
39954
+ unclear.
39955
+ `;
39956
+ }
39957
+ function genericC3ComponentsReference() {
39958
+ return `# C3 Components
39959
+
39960
+ Use this reference only for C3 work: decomposing one selected container or
39961
+ service into internal components and their collaborations.
39962
+
39963
+ ## What C3 Answers
39964
+
39965
+ A C3 view answers: "Inside this container/service, what named responsibilities
39966
+ collaborate to deliver its behavior?"
39967
+
39968
+ Prefer one focal container or service per C3 source file. The built-in C3 view
39969
+ is scoped by the selected source file, so the C3 file should usually contain an
39970
+ \`extend container <id>\` or \`extend service <id>\` block for the focal element.
39971
+
39972
+ Do not model every class, function, method, or package. A component should be a
39973
+ stable architectural responsibility that is useful in a diagram and review.
39974
+
39975
+ ## C3 Workflow
39976
+
39977
+ 1. Run \`archinsight structure . --format text\` to find the exact container or
39978
+ service id, available constructors, and existing imports.
39979
+ 2. Create or edit a C3 file in the same \`context <id>\`.
39980
+ 3. Import elements from other contexts only when the component links to them.
39981
+ 4. Use \`extend container <id>\` or \`extend service <id>\`.
39982
+ 5. Add \`component\` declarations with \`name\`, \`technology\`, and
39983
+ \`responsibility\`.
39984
+ 6. Add links between components and to real external endpoints.
39985
+ 7. Validate with \`archinsight link . --format text\`.
39986
+ 8. Render with \`archinsight render . -c <context-id> -s <c3-file.ai> -v c3 -f svg -o c3.svg\`.
39987
+
39988
+ ## File Split Pattern
39989
+
39990
+ Keep the C2 declaration small:
39991
+
39992
+ \`\`\`insight
39993
+ context commerce
39994
+ name = Commerce Platform
39995
+
39996
+ external system payment_provider
39997
+ name = Payment Provider
39998
+ technology = HTTPS API
39999
+
40000
+ system storefront
40001
+ name = Storefront
40002
+
40003
+ service checkout_api
40004
+ name = Checkout API
40005
+ technology = Kotlin, PostgreSQL
40006
+ description = Handles cart pricing, order placement, and payment orchestration
40007
+ \`\`\`
40008
+
40009
+ Put component details in a C3 file:
40010
+
40011
+ \`\`\`insight
40012
+ context commerce
40013
+
40014
+ extend service checkout_api
40015
+ component checkout_controller
40016
+ name = Checkout controller
40017
+ technology = REST controller
40018
+ responsibility = Accepts checkout requests and returns order status
40019
+ links:
40020
+ -> checkout_service
40021
+
40022
+ component checkout_service
40023
+ name = Checkout service
40024
+ technology = Kotlin
40025
+ responsibility = Coordinates pricing, payment authorization, and order creation
40026
+ links:
40027
+ -> payment_gateway
40028
+ -> order_repository
40029
+
40030
+ component payment_gateway
40031
+ name = Payment gateway
40032
+ technology = HTTP client
40033
+ responsibility = Translates internal payment commands to provider API calls
40034
+ links:
40035
+ -> payment_provider
40036
+ technology = HTTPS
40037
+ call = POST /payments/authorizations
40038
+ description = Authorizes customer payment
40039
+
40040
+ component order_repository
40041
+ name = Order repository
40042
+ technology = SQL
40043
+ responsibility = Persists order state and checkout audit records
40044
+ \`\`\`
40045
+
40046
+ ## Frontend Container Pattern
40047
+
40048
+ Use C3 for UI responsibilities when the frontend container has distinct
40049
+ architectural parts:
40050
+
40051
+ \`\`\`insight
40052
+ context commerce
40053
+
40054
+ extend container web_app
40055
+ component route_shell
40056
+ name = Route shell
40057
+ technology = SvelteKit routing
40058
+ responsibility = Owns route loading, authenticated layout, and page composition
40059
+ links:
40060
+ -> checkout_page
40061
+ -> session_store
40062
+
40063
+ component checkout_page
40064
+ name = Checkout page
40065
+ technology = Svelte
40066
+ responsibility = Collects checkout input and presents order progress
40067
+ links:
40068
+ -> api_client
40069
+
40070
+ component session_store
40071
+ name = Session store
40072
+ technology = Browser storage
40073
+ responsibility = Keeps current user and session state for client-side decisions
40074
+
40075
+ component api_client
40076
+ name = API client
40077
+ technology = Fetch, JSON
40078
+ responsibility = Wraps backend API calls and maps transport errors to UI state
40079
+ links:
40080
+ -> checkout_api
40081
+ technology = HTTPS, JSON
40082
+ call = POST /checkout
40083
+ \`\`\`
40084
+
40085
+ This is useful when frontend structure affects architecture. If the frontend is
40086
+ only a thin page with no meaningful internal decisions, leave it at C2.
40087
+
40088
+ ## Backend Service Pattern
40089
+
40090
+ Use C3 to separate adapters, orchestration, domain logic, persistence, and
40091
+ integration boundaries:
40092
+
40093
+ \`\`\`insight
40094
+ context commerce
40095
+
40096
+ extend service inventory_api
40097
+ component inventory_resource
40098
+ name = Inventory resource
40099
+ technology = REST
40100
+ responsibility = Exposes stock reservations and availability endpoints
40101
+ links:
40102
+ -> reservation_service
40103
+
40104
+ component reservation_service
40105
+ name = Reservation service
40106
+ technology = Java
40107
+ responsibility = Applies reservation rules and coordinates stock updates
40108
+ links:
40109
+ -> inventory_policy
40110
+ -> reservation_repository
40111
+ ~> inventory_events
40112
+ technology = Kafka
40113
+ via = inventory.reserved
40114
+ description = Publishes successful reservation events
40115
+
40116
+ component inventory_policy
40117
+ name = Inventory policy
40118
+ technology = Java
40119
+ responsibility = Decides whether stock can be promised to an order
40120
+
40121
+ component reservation_repository
40122
+ name = Reservation repository
40123
+ technology = SQL
40124
+ responsibility = Stores reservation state and idempotency keys
40125
+
40126
+ component inventory_events
40127
+ name = Inventory events
40128
+ technology = Kafka producer
40129
+ responsibility = Publishes inventory domain events for downstream systems
40130
+ \`\`\`
40131
+
40132
+ Use \`->\` for synchronous calls and \`~>\` for asynchronous flows. Use singular
40133
+ \`call\` for the synchronous operation and \`via\` for the asynchronous topic,
40134
+ queue, or channel.
40135
+
40136
+ ## Imported Boundary Pattern
40137
+
40138
+ When a component links to an element from another context, import it and use
40139
+ \`from <context-id>\` on the link target:
40140
+
40141
+ \`\`\`insight
40142
+ context commerce
40143
+
40144
+ import fraud_api from context risk_platform
40145
+
40146
+ extend service checkout_api
40147
+ component risk_adapter
40148
+ name = Risk adapter
40149
+ technology = HTTP client
40150
+ responsibility = Requests fraud decisions before payment authorization
40151
+ links:
40152
+ -> fraud_api from risk_platform
40153
+ technology = HTTPS
40154
+ call = POST /risk/decisions
40155
+ description = Requests checkout risk decision
40156
+ \`\`\`
40157
+
40158
+ Do not copy an imported system into the current context just to make the C3
40159
+ diagram render. Import the real declaration and validate the link.
40160
+
40161
+ ## Component Naming
40162
+
40163
+ Prefer names that reveal responsibility:
40164
+
40165
+ - \`checkout_controller\`, \`checkout_service\`, \`payment_gateway\`
40166
+ - \`reservation_policy\`, \`reservation_repository\`, \`inventory_events\`
40167
+ - \`route_shell\`, \`checkout_page\`, \`api_client\`
40168
+
40169
+ Avoid names that are only implementation trivia:
40170
+
40171
+ - \`utils\`, \`helpers\`, \`module1\`, \`manager\`
40172
+ - individual classes unless the class is the architectural boundary
40173
+ - framework-generated files or folders
40174
+
40175
+ ## Responsibility Boundaries
40176
+
40177
+ A good C3 component has at least one of these:
40178
+
40179
+ - a distinct external adapter;
40180
+ - a domain or orchestration responsibility;
40181
+ - a persistence boundary;
40182
+ - an asynchronous producer or consumer role;
40183
+ - a security, policy, parsing, rendering, or transformation responsibility;
40184
+ - a UI composition, state, or backend API boundary that affects architecture.
40185
+
40186
+ If a component cannot be described without mentioning code organization only,
40187
+ leave it out or ask for a more architectural boundary.
40188
+
40189
+ ## Links in C3
40190
+
40191
+ Links should explain runtime collaboration inside the focal container/service.
40192
+
40193
+ Use internal component links:
40194
+
40195
+ \`\`\`insight
40196
+ links:
40197
+ -> checkout_service
40198
+ \`\`\`
40199
+
40200
+ Add call details when they matter:
40201
+
40202
+ \`\`\`insight
40203
+ links:
40204
+ -> payment_gateway
40205
+ call = authorize(paymentCommand)
40206
+ description = Requests payment authorization
40207
+ \`\`\`
40208
+
40209
+ Use async details for events:
40210
+
40211
+ \`\`\`insight
40212
+ links:
40213
+ ~> inventory_events
40214
+ via = inventory.reserved
40215
+ description = Publishes reservation completion
40216
+ \`\`\`
40217
+
40218
+ Do not add a broker as a component unless the broker is actually part of the
40219
+ focal container/service. Shared brokers, queues, gateways, and runtime placement
40220
+ usually belong to deployment/C4 or infrastructure modeling.
40221
+
40222
+ ## Common C3 Mistakes
40223
+
40224
+ - Writing C3 components under a \`system\` instead of under a container/service
40225
+ unless the project type model explicitly allows that.
40226
+ - Creating one C3 file for every class or package.
40227
+ - Linking to an external element without importing it when it lives in another
40228
+ context.
40229
+ - Forgetting \`--source <c3-file.ai>\` when rendering C3.
40230
+ - Mixing C2 container links and C3 component links in one view question.
40231
+ - Keeping a broad container/service link and an equivalent lower-level component
40232
+ link without deciding which level should own the relationship.
40233
+ - Inventing components to satisfy a diagram shape instead of describing real
40234
+ responsibilities.
40235
+
40236
+ ## Validation Commands
40237
+
40238
+ \`\`\`shell
40239
+ archinsight structure . --format text
40240
+ archinsight link . --format text
40241
+ archinsight render . -c commerce -s checkout_components.ai -v c3 -f svg -o checkout-c3.svg
40242
+ \`\`\`
40243
+
40244
+ Use \`examples/c3-components.ai\` as a compact valid C3 model when syntax is
40245
+ unclear.
40246
+ `;
40247
+ }
40248
+ function genericC4DeploymentReference() {
40249
+ return `# C4 Deployment and Infrastructure
40250
+
40251
+ Use this reference only for C4 work: deployment profiles, environments,
40252
+ environment-scoped infrastructure inventory, \`uses\` / \`runsOn\`, and
40253
+ projection rules.
40254
+
40255
+ ## Contents
40256
+
40257
+ - What C4 Answers
40258
+ - Before You Use C4
40259
+ - Mental Model
40260
+ - C4 Workflow
40261
+ - Environment Inventory
40262
+ - Why Infrastructure Is Per Environment
40263
+ - Attaching Deployment To C1-C3 Elements
40264
+ - usesProfile, environmentsFrom, runsOn, and uses
40265
+ - Deployment Archetypes
40266
+ - Projection Rules
40267
+ - Traffic Path Example
40268
+ - Compute and Grouping
40269
+ - Many-To-Many Deployment
40270
+ - What Not To Put In C4
40271
+ - Common C4 Mistakes
40272
+ - Validation Commands
40273
+
40274
+ ## What C4 Answers
40275
+
40276
+ A C4/deployment view answers: "Where do logical architecture elements run, what
40277
+ environment-specific infrastructure do they use, and what physical path does a
40278
+ logical relationship expand into?"
40279
+
40280
+ C4 is not just another decomposition level. C1-C3 mostly describe logical
40281
+ architecture. C4 maps logical elements and links onto environment-local
40282
+ infrastructure inventory.
40283
+
40284
+ ## Before You Use C4
40285
+
40286
+ C4/deployment is optional. Do not push the user into environments, projection
40287
+ rules, and infrastructure inventory when they only need a quick logical/runtime
40288
+ view.
40289
+
40290
+ If the work has reached infrastructure, runtime placement, regions, compute, or
40291
+ deployment, ask or infer the intended style for the current system:
40292
+
40293
+ - Pragmatic mixed C2: put simple infrastructure-like runtime nodes such as a
40294
+ database, broker, gateway, or vault near the services in C2. This is fast and
40295
+ easier for simple or single-environment systems, but it mixes abstraction
40296
+ levels and does not produce a real C4 model.
40297
+ - Clean C4: keep C2 logical and describe physical realization through
40298
+ \`Environment\` slots, deployment profiles, inventory, \`runsOn\`, \`uses\`,
40299
+ and projection rules. This takes more design work, but supports region/env
40300
+ differences, many-to-many deployment, and organization-specific runtime
40301
+ complexity.
40302
+
40303
+ The choice is per-system. Model a critical system with clean C4 and keep a
40304
+ peripheral system pragmatic in C2 if that matches the user's needs. If a system
40305
+ starts as mixed C2 and later needs multi-env deployment, expect a migration:
40306
+ infrastructure nodes must move into environment inventory and links must gain
40307
+ deployment/projection semantics.
40308
+
40309
+ ## Mental Model
40310
+
40311
+ There are three layers:
40312
+
40313
+ 1. Schema: extend \`Environment\` with infrastructure slots such as
40314
+ \`Compute compute\`, \`Storage storage\`, \`Broker broker\`,
40315
+ \`NetworkConnection network\`, or \`PublicGateway publicGateway\`.
40316
+ \`Compute\`, \`Storage\`, \`Broker\`, and \`NetworkConnection\` are core
40317
+ deployment types.
40318
+ 2. Inventory: each \`environment <id>\` fills those slots with concrete
40319
+ infrastructure instances for that environment.
40320
+ 3. Deployment references: logical systems, containers, services, components, or
40321
+ links use \`deployment:\` with \`runsOn\`, \`uses\`, \`usesProfile\`, or
40322
+ \`environmentsFrom\` to reference the inventory.
40323
+
40324
+ An \`InfrastructureComponent\` is not an orphan. It is usually inventory inside
40325
+ an \`environment\` slot. The hook is the type extension:
40326
+
40327
+ \`\`\`insight
40328
+ extend type Environment
40329
+ Compute compute
40330
+ Storage storage
40331
+ Broker broker
40332
+ NetworkConnection network
40333
+ PublicGateway publicGateway
40334
+ \`\`\`
40335
+
40336
+ After that, every \`environment <id>\` can provide those slots:
40337
+
40338
+ \`\`\`insight
40339
+ environment prod
40340
+ name = Production
40341
+
40342
+ compute:
40343
+ compute kube
40344
+ name = Kubernetes
40345
+
40346
+ storage:
40347
+ storage db
40348
+ name = PostgreSQL
40349
+
40350
+ broker:
40351
+ broker events
40352
+ name = Event broker
40353
+ address = kafka.prod.internal:9092
40354
+
40355
+ network:
40356
+ networkConnection private_path
40357
+ name = Private service path
40358
+ \`\`\`
40359
+
40360
+ ## C4 Workflow
40361
+
40362
+ 1. Inspect existing deployment types with \`archinsight structure . --format text\`.
40363
+ 2. Read \`references/core.md\` and project framework files for existing
40364
+ \`extend type Environment\`, infrastructure types, and projection rules.
40365
+ 3. Add or reuse infrastructure types in a definition file. Prefer core
40366
+ \`Compute\`, \`Storage\`, \`Broker\`, and \`NetworkConnection\` for common
40367
+ deployment inventory.
40368
+ 4. Extend \`Environment\` with slots for the infrastructure inventory.
40369
+ 5. Create one or more \`environment <id>\` declarations and fill the slots.
40370
+ 6. Add \`deploymentProfile\` declarations that select environments and common
40371
+ \`runsOn\` / \`uses\` defaults.
40372
+ 7. Attach \`deployment:\` blocks to logical elements or links.
40373
+ 8. Validate with \`archinsight link . --format text\`.
40374
+ 9. Render with \`archinsight render . -c <context-id> -s <c4-file.ai> -v c4 -f svg -o c4.svg\`.
40375
+
40376
+ ## Environment Inventory
40377
+
40378
+ Define infrastructure vocabulary in a definition file:
40379
+
40380
+ \`\`\`insight
40381
+ extend type Environment
40382
+ ServiceProvider cloud
40383
+ Compute compute
40384
+ Storage storage
40385
+ Broker broker
40386
+ NetworkConnection network
40387
+ PublicGateway publicGateway
40388
+
40389
+ define type ServiceProvider of InfrastructureComponent
40390
+ constructor serviceProvider
40391
+
40392
+ define type PublicGateway of InfrastructureComponent
40393
+ constructor publicGateway
40394
+ required InfrastructureComponent cdn
40395
+ required InfrastructureComponent loadBalancer
40396
+ \`\`\`
40397
+
40398
+ Then fill concrete environments:
40399
+
40400
+ \`\`\`insight
40401
+ environment prod
40402
+ name = Production
40403
+
40404
+ cloud:
40405
+ serviceProvider aws
40406
+ name = AWS
40407
+
40408
+ compute:
40409
+ compute eks
40410
+ name = EKS
40411
+ runsOn cloud
40412
+
40413
+ storage:
40414
+ storage orders_db
40415
+ name = Orders PostgreSQL
40416
+ runsOn cloud
40417
+
40418
+ broker:
40419
+ broker events
40420
+ name = Event broker
40421
+ technology = Kafka
40422
+ address = kafka.prod.internal:9092
40423
+ runsOn compute
40424
+
40425
+ network:
40426
+ networkConnection private_path
40427
+ name = Private service path
40428
+ runsOn compute
40429
+
40430
+ publicGateway:
40431
+ publicGateway public_edge
40432
+ name = Public edge
40433
+ cdn:
40434
+ infrastructureComponent cloudfront
40435
+ name = CloudFront
40436
+ runsOn cloud
40437
+ loadBalancer:
40438
+ infrastructureComponent alb
40439
+ name = Application Load Balancer
40440
+ runsOn cloud
40441
+ runsOn compute
40442
+ \`\`\`
40443
+
40444
+ \`cloud\`, \`compute\`, \`storage\`, and \`publicGateway\` are slots on this
40445
+ specific \`prod\` environment. Another environment can fill the same slots with
40446
+ different concrete infrastructure.
40447
+
40448
+ ## Why Infrastructure Is Per Environment
40449
+
40450
+ Infrastructure must be per environment because deployment is many-to-many:
40451
+
40452
+ - one logical service can run in several environments;
40453
+ - each environment can use different compute, storage, gateways, regions, or
40454
+ providers;
40455
+ - the same \`uses storage\` reference must resolve to the current environment's
40456
+ storage instance, not to one global database node;
40457
+ - projection rules need environment-local inventory to expand logical edges into
40458
+ physical paths.
40459
+
40460
+ If infrastructure were modeled as global nodes, the model could not say:
40461
+ "Checkout API runs on EKS in production, Cloud Run in staging, and uses a
40462
+ different database in each environment" without duplicating logical services.
40463
+
40464
+ ## Attaching Deployment To C1-C3 Elements
40465
+
40466
+ \`deployment\` is available on systems, containers/services, components, and
40467
+ wires. Attach it where it best represents the runtime boundary.
40468
+
40469
+ Prefer C2 containers/services for most deployment mapping:
40470
+
40471
+ - C1 systems are often too broad and hide real runtime placement.
40472
+ - C3 components are often too fine and can overfit code structure.
40473
+ - C2 containers/services usually represent deployable runtime units.
40474
+
40475
+ Use C1 deployment only when the whole system is deployed as one unit. Use C3
40476
+ deployment when a component is independently deployed or has a distinct physical
40477
+ path. Use wire deployment when a specific logical relationship travels through
40478
+ infrastructure such as a public gateway, network connection, broker, or egress
40479
+ path.
40480
+
40481
+ ## Element-Level vs Wire-Level Infrastructure
40482
+
40483
+ Attach infrastructure to an element when the projection only needs the deployed
40484
+ element itself:
40485
+
40486
+ - \`runsOn compute\`: placement/grouping.
40487
+ - \`uses storage\`: the element depends on stateful infrastructure.
40488
+ - \`uses observability\`: monitoring sidecars or collectors around the element.
40489
+
40490
+ Attach infrastructure to a wire when the projection needs a real target:
40491
+
40492
+ - \`uses publicGateway\`: expands a caller-to-service path through ingress.
40493
+ - \`uses network\`: keeps a direct source-to-target network path on C4.
40494
+ - \`uses broker\`: both producer and consumer physically connect to the broker.
40495
+
40496
+ Rule of thumb: if the infrastructure type's \`project:\` block mentions \`$to\`,
40497
+ use it on a relationship under \`links:\`. Using it on an element is invalid
40498
+ because an element deployment has no separate target endpoint.
40499
+
40500
+ ## usesProfile, environmentsFrom, runsOn, and uses
40501
+
40502
+ \`deploymentProfile\` names a reusable deployment scope:
40503
+
40504
+ \`\`\`insight
40505
+ deploymentProfile global
40506
+ environments:
40507
+ prod
40508
+ staging
40509
+
40510
+ runsOn compute
40511
+ \`\`\`
40512
+
40513
+ \`usesProfile\` copies the profile's environments and deployment operators to a
40514
+ logical element:
40515
+
40516
+ \`\`\`insight
40517
+ service checkout_api
40518
+ name = Checkout API
40519
+ deployment:
40520
+ usesProfile global
40521
+ uses storage
40522
+ \`\`\`
40523
+
40524
+ \`runsOn compute\` resolves the \`compute\` slot inside each selected
40525
+ environment and stores it as the logical element's placement. \`uses storage\`
40526
+ resolves the environment-local \`storage\` slot and projects edges to it.
40527
+
40528
+ \`environmentsFrom global\` copies only the environments from a profile. It is
40529
+ useful on a link when the path should share the same environment set but use its
40530
+ own infrastructure. It deliberately does not copy \`runsOn\` or \`uses\` from
40531
+ the profile:
40532
+
40533
+ \`\`\`insight
40534
+ links:
40535
+ -> checkout_api
40536
+ deployment:
40537
+ environmentsFrom global
40538
+ uses publicGateway
40539
+ \`\`\`
40540
+
40541
+ \`usesProfile global\` copies environments and profile operators. Use it on an
40542
+ element when the profile's defaults apply. Use \`environmentsFrom global\` on a
40543
+ link when only the environment scope should be reused.
40544
+
40545
+ You can also use \`environmentsFrom\` on an element when it should share the
40546
+ profile's environment list but choose its own placement or dependencies:
40547
+
40548
+ \`\`\`insight
40549
+ service batch_worker
40550
+ name = Batch Worker
40551
+ deployment:
40552
+ environmentsFrom regional_service
40553
+ runsOn compute
40554
+ uses storage
40555
+ \`\`\`
40556
+
40557
+ Here \`batch_worker\` deploys to the same environments as
40558
+ \`regional_service\`, but it does not inherit \`regional_service\` defaults such
40559
+ as \`uses observability\`. Add every desired \`runsOn\` and \`uses\` explicitly.
40560
+
40561
+ ## Deployment Archetypes
40562
+
40563
+ Use \`deploymentProfile\` to create named deployment archetypes such as
40564
+ \`global_service\`, \`regional_service\`, or \`public_regional_service\`. A
40565
+ profile should select concrete \`environment\` instances and attach the common
40566
+ deployment operators that most services of that archetype need.
40567
+
40568
+ Example environment inventory:
40569
+
40570
+ \`\`\`insight
40571
+ environment global_edge
40572
+ name = Global edge
40573
+
40574
+ compute:
40575
+ compute edge_runtime
40576
+ name = Edge runtime
40577
+
40578
+ publicGateway:
40579
+ publicGateway edge_gateway
40580
+ name = Global public gateway
40581
+ cdn:
40582
+ infrastructureComponent cloudfront
40583
+ name = CloudFront
40584
+ loadBalancer:
40585
+ infrastructureComponent global_lb
40586
+ name = Global Load Balancer
40587
+
40588
+ environment eu
40589
+ name = Europe
40590
+
40591
+ compute:
40592
+ compute kube_eu
40593
+ name = Kubernetes EU
40594
+
40595
+ storage:
40596
+ storage db_eu
40597
+ name = PostgreSQL EU
40598
+
40599
+ observability:
40600
+ monitoring otel_eu
40601
+ name = OpenTelemetry Collector EU
40602
+ display:
40603
+ infrastructureComponent grafana
40604
+ name = Grafana Cloud
40605
+ \`\`\`
40606
+
40607
+ Example profiles:
40608
+
40609
+ \`\`\`insight
40610
+ deploymentProfile global_service
40611
+ environments:
40612
+ global_edge
40613
+
40614
+ runsOn compute
40615
+
40616
+ deploymentProfile regional_service
40617
+ environments:
40618
+ eu
40619
+
40620
+ runsOn compute
40621
+ uses observability
40622
+ \`\`\`
40623
+
40624
+ Then attach the archetype with one \`usesProfile\`:
40625
+
40626
+ \`\`\`insight
40627
+ container web_app
40628
+ name = Web app
40629
+ deployment:
40630
+ usesProfile global_service
40631
+ links:
40632
+ -> checkout_api
40633
+ deployment:
40634
+ environmentsFrom global_service
40635
+ uses publicGateway
40636
+
40637
+ service checkout_api
40638
+ name = Checkout API
40639
+ deployment:
40640
+ usesProfile regional_service
40641
+ uses storage
40642
+ \`\`\`
40643
+
40644
+ The profile supplies the common environment scope, placement, and element-level
40645
+ infrastructure. Additional local \`uses\` entries extend the profile for that
40646
+ specific element. In the example, \`checkout_api\` inherits regional compute and
40647
+ observability from \`regional_service\`, then adds its own \`uses storage\`
40648
+ because this service owns persistent state. The \`web_app -> checkout_api\` wire uses
40649
+ \`environmentsFrom global_service\` to reuse the environment list while attaching
40650
+ the path-only \`publicGateway\` projection to the relationship.
40651
+
40652
+ Use separate profiles when the element-level defaults differ. For example,
40653
+ \`regional_service\` can include \`runsOn compute\` and \`uses observability\`,
40654
+ while \`regional_stateful_service\` can also include \`uses storage\`. Keep
40655
+ path-only infrastructure such as \`publicGateway\`, \`network\`, or \`broker\`
40656
+ on the wire deployment where the source and target are known.
40657
+
40658
+ When an element should reuse only the environments from an archetype, use
40659
+ \`environmentsFrom <profile>\` instead of \`usesProfile <profile>\` and then add
40660
+ the local \`runsOn\` / \`uses\` entries explicitly.
40661
+
40662
+ Do not try to make infrastructure global to avoid repeating profiles. The
40663
+ profile should select environment instances; the selected environments provide
40664
+ their own concrete infrastructure through slots.
40665
+
40666
+ ## Projection Rules
40667
+
40668
+ Projection rules live on infrastructure types. They explain how a logical
40669
+ \`uses <slot>\` reference expands into projected graph edges.
40670
+
40671
+ Core defaults:
40672
+
40673
+ - \`Storage\`: \`$from -> $this\`.
40674
+ - \`Broker\`: \`$from -> $this\` and \`$to -> $this\`, because both sides
40675
+ physically connect to the broker.
40676
+ - \`NetworkConnection\`: \`$from -> $to\`, for an ordinary direct network call
40677
+ that should still appear on the deployment layer.
40678
+
40679
+ Custom infrastructure types can define their own projection rules.
40680
+
40681
+ \`\`\`insight
40682
+ define type PublicGateway of InfrastructureComponent
40683
+ constructor publicGateway
40684
+ required InfrastructureComponent cdn
40685
+ required InfrastructureComponent loadBalancer
40686
+
40687
+ project:
40688
+ $from -> cdn
40689
+ cdn -> loadBalancer
40690
+ loadBalancer -> $this
40691
+ $this -> $to
40692
+ \`\`\`
40693
+
40694
+ When a service says \`uses storage\`, the selected environment's storage instance
40695
+ receives a projected edge from the logical service:
40696
+
40697
+ \`\`\`text
40698
+ checkout_api -> prod.orders_db
40699
+ checkout_api -> staging.orders_db
40700
+ \`\`\`
40701
+
40702
+ When a wire says \`uses network\`, the selected environment's network connection
40703
+ keeps the logical source-to-target relationship visible in the deployment view:
40704
+
40705
+ \`\`\`insight
40706
+ links:
40707
+ -> checkout_api
40708
+ deployment:
40709
+ environmentsFrom regional_service
40710
+ uses network
40711
+ \`\`\`
40712
+
40713
+ If a logical relationship is missing from a C4/deployment diagram, check whether
40714
+ the wire has deployment information and uses a path-producing slot such as
40715
+ \`network\`, \`publicGateway\`, or another type with a \`project:\` rule. C4
40716
+ queries commonly select projected deployment edges; a plain logical wire without
40717
+ deployment projection may be correct in C2/C3 but absent from the deployment
40718
+ layer.
40719
+
40720
+ If validation reports \`PROJECTION_TARGET_REQUIRED\`, you attached a projection
40721
+ that uses \`$to\` to an element. Move that \`uses ...\` entry to the relevant
40722
+ wire and reuse the element's environment scope with \`environmentsFrom\`.
40723
+
40724
+ Projection terms:
40725
+
40726
+ - \`$from\` is the logical source of the deployment use.
40727
+ - \`$to\` is the logical target when the deployment is attached to a wire.
40728
+ - \`$this\` is the infrastructure component instance selected by \`uses\`.
40729
+ - plain names such as \`cdn\` or \`loadBalancer\` are attributes/slots on
40730
+ \`$this\`.
40731
+
40732
+ ## Traffic Path Example
40733
+
40734
+ A public gateway can expand one logical edge into a physical path:
40735
+
40736
+ \`\`\`insight
40737
+ define type PublicGateway of InfrastructureComponent
40738
+ constructor publicGateway
40739
+ required InfrastructureComponent cdn
40740
+ required InfrastructureComponent loadBalancer
40741
+
40742
+ project:
40743
+ $from -> cdn
40744
+ cdn -> loadBalancer
40745
+ loadBalancer -> $this
40746
+ $this -> $to
40747
+ \`\`\`
40748
+
40749
+ Given this logical relationship:
40750
+
40751
+ \`\`\`insight
40752
+ external actor customer
40753
+ name = Customer
40754
+ links:
40755
+ -> web_app
40756
+ deployment:
40757
+ environmentsFrom public_regional_service
40758
+ uses publicGateway
40759
+ \`\`\`
40760
+
40761
+ And this environment inventory:
40762
+
40763
+ \`\`\`insight
40764
+ environment prod
40765
+ name = Production
40766
+
40767
+ publicGateway:
40768
+ publicGateway public_edge
40769
+ name = Public edge
40770
+ cdn:
40771
+ infrastructureComponent cloudfront
40772
+ name = CloudFront
40773
+ loadBalancer:
40774
+ infrastructureComponent alb
40775
+ name = Application Load Balancer
40776
+ \`\`\`
40777
+
40778
+ The projection creates the physical path:
40779
+
40780
+ \`\`\`text
40781
+ customer -> cloudfront -> alb -> public_edge -> web_app
40782
+ \`\`\`
40783
+
40784
+ The logical edge remains the authoring intent. The projected edges are derived
40785
+ from deployment inventory and the \`project:\` rule.
40786
+
40787
+ ## Compute and Grouping
40788
+
40789
+ \`runsOn compute\` is placement, not a traffic path by itself. It resolves the
40790
+ selected environment's compute slot and marks where a logical element runs:
40791
+
40792
+ \`\`\`insight
40793
+ deploymentProfile regional_service
40794
+ environments:
40795
+ prod
40796
+ staging
40797
+
40798
+ runsOn compute
40799
+ uses observability
40800
+
40801
+ deploymentProfile public_regional_service
40802
+ environments:
40803
+ prod
40804
+ staging
40805
+
40806
+ runsOn compute
40807
+ uses observability
40808
+
40809
+ service checkout_api
40810
+ name = Checkout API
40811
+ deployment:
40812
+ usesProfile global
40813
+ \`\`\`
40814
+
40815
+ If \`prod.compute\` is EKS and \`staging.compute\` is Cloud Run, the same
40816
+ \`checkout_api\` can render in both compute groups. The built-in C4 query groups
40817
+ by \`node.runsOn\`, so compute is usually the visual grouping anchor.
40818
+
40819
+ Use \`runsOn\` on infrastructure too:
40820
+
40821
+ \`\`\`insight
40822
+ storage orders_db
40823
+ name = Orders PostgreSQL
40824
+ runsOn cloud
40825
+ \`\`\`
40826
+
40827
+ This places the database under its provider or parent infrastructure in the
40828
+ rendered deployment graph.
40829
+
40830
+ ## Many-To-Many Deployment
40831
+
40832
+ This is the core reason for the model:
40833
+
40834
+ \`\`\`insight
40835
+ deploymentProfile global
40836
+ environments:
40837
+ prod
40838
+ staging
40839
+
40840
+ runsOn compute
40841
+
40842
+ service checkout_api
40843
+ name = Checkout API
40844
+ deployment:
40845
+ usesProfile global
40846
+ uses storage
40847
+ \`\`\`
40848
+
40849
+ If \`prod.compute = EKS\`, \`prod.storage = Aurora\`,
40850
+ \`staging.compute = Cloud Run\`, and \`staging.storage = Cloud SQL\`, the single
40851
+ logical service projects into both environments without duplicating
40852
+ \`checkout_api\`.
40853
+
40854
+ ## What Not To Put In C4
40855
+
40856
+ - Global infrastructure nodes when the infrastructure differs by environment.
40857
+ - Logical components invented only to represent physical routing.
40858
+ - C3 internals unless they are independently deployed.
40859
+ - Cloud resources with no relationship to a deployment question.
40860
+ - A broker/gateway/load balancer in C2 just because it appears in deployment,
40861
+ unless the system intentionally uses the pragmatic mixed-C2 style.
40862
+
40863
+ ## Common C4 Mistakes
40864
+
40865
+ - Defining infrastructure types but forgetting to extend \`Environment\` with
40866
+ slots for them.
40867
+ - Creating \`infrastructureComponent\` nodes at context level when they should
40868
+ live in an \`environment\` inventory slot.
40869
+ - Using \`usesProfile\` on a wire when only \`environmentsFrom\` is intended.
40870
+ - Forgetting \`--source <c4-file.ai>\` when rendering C4.
40871
+ - Expecting \`runsOn\` to draw traffic; use \`project:\` rules and \`uses\` for
40872
+ traffic/path projections.
40873
+ - Treating projected edges as source declarations; they are derived.
40874
+
40875
+ ## Validation Commands
40876
+
40877
+ \`\`\`shell
40878
+ archinsight structure . --format text
40879
+ archinsight link . --format text
40880
+ archinsight render . -c deployment_shop -s c4-deployment.ai -v c4 -f svg -o deployment-c4.svg
40881
+ \`\`\`
40882
+
40883
+ Use \`examples/c4-deployment-framework.ai\` and \`examples/c4-deployment.ai\` as
40884
+ a compact valid C4 model when syntax is unclear.
40885
+ `;
40886
+ }
40887
+ function genericScalingReference() {
40888
+ return `# Scaling an Archinsight Repository
40889
+
40890
+ Use this reference when a project grows beyond one or two files and you need to
40891
+ reuse definitions, environments, deployment profiles, or systems without
40892
+ duplicating them.
40893
+
40894
+ ## Repository Shape
40895
+
40896
+ Prefer one shared framework per repository:
40897
+
40898
+ - one definitions/framework area for \`extend type Environment\`, custom
40899
+ infrastructure types, presentation tweaks, projection-capable infrastructure,
40900
+ and reusable deployment profiles;
40901
+ - source files grouped by context directories when the repository is large;
40902
+ - model files that usually focus on one primary owned system being detailed;
40903
+ - one or more inventory files for concrete \`environment <id>\` instances and
40904
+ their env-local infrastructure;
40905
+ - shared external contexts for external actors and systems reused by many
40906
+ systems;
40907
+ - focused deployment-view files that attach deployment profiles and per-view
40908
+ traffic paths.
40909
+
40910
+ Do not copy the same \`extend type Environment\`, infra type definitions, or
40911
+ \`deploymentProfile\` blocks into every system file. Define the vocabulary and
40912
+ reusable archetypes once, import or reference them where needed, and validate the
40913
+ whole project.
40914
+
40915
+ ## Framework Once, Use Everywhere
40916
+
40917
+ A typical deployment framework file contains only shared vocabulary: type
40918
+ definitions, type extensions, projection rules, and presentation overrides. Do
40919
+ not mix \`define type\` / \`extend type\` declarations and \`context\`
40920
+ declarations in the same source file.
40921
+
40922
+ \`\`\`insight
40923
+ define type PublicGateway of InfrastructureComponent
40924
+ constructor publicGateway
40925
+ required InfrastructureComponent cdn
40926
+ required InfrastructureComponent loadBalancer
40927
+
40928
+ project:
40929
+ $from -> cdn
40930
+ cdn -> loadBalancer
40931
+ loadBalancer -> $this
40932
+ $this -> $to
40933
+
40934
+ extend type Environment
40935
+ Compute compute
40936
+ Storage storage
40937
+ Broker broker
40938
+ PublicGateway publicGateway
40939
+ NetworkConnection network
40940
+ \`\`\`
40941
+
40942
+ Concrete inventory/profile files then declare contexts, environments, and
40943
+ profiles:
40944
+
40945
+ \`\`\`insight
40946
+ context infra
40947
+ name = Shared Infrastructure
40948
+
40949
+ environment prod_eu
40950
+ name = Production EU
40951
+ compute:
40952
+ compute ecs
40953
+ name = ECS
40954
+ technology = AWS ECS
40955
+ broker:
40956
+ broker kafka
40957
+ name = Kafka
40958
+ technology = MSK
40959
+ address = kafka.prod.eu.internal
40960
+
40961
+ deploymentProfile regional_service
40962
+ environments:
40963
+ prod_eu
40964
+
40965
+ runsOn compute
40966
+ \`\`\`
40967
+
40968
+ System files should reuse these definitions instead of recreating \`compute\`,
40969
+ \`broker\`, or profile declarations locally.
40970
+
40971
+ ## System Files and External Contexts
40972
+
40973
+ The default model file is centered on one owned system:
40974
+
40975
+ \`\`\`text
40976
+ commerce/
40977
+ checkout.ai
40978
+ catalog.ai
40979
+ fulfillment.ai
40980
+ external/
40981
+ platforms.ai
40982
+ regulators.ai
40983
+ \`\`\`
40984
+
40985
+ \`commerce/checkout.ai\` would declare \`context commerce\`, the
40986
+ \`system checkout\` focal object, and the containers/services/components needed
40987
+ to explain checkout. \`commerce/catalog.ai\` would do the same for catalog.
40988
+
40989
+ Shared external actors and systems should not be copied into every system file.
40990
+ Put them in one external context, or a few semantically grouped external
40991
+ contexts:
40992
+
40993
+ \`\`\`insight
40994
+ context external_platforms
40995
+
40996
+ external system stripe
40997
+ name = Stripe
40998
+
40999
+ external system sendgrid
41000
+ name = SendGrid
41001
+ \`\`\`
41002
+
41003
+ Then import them where needed:
41004
+
41005
+ \`\`\`insight
41006
+ context commerce
41007
+
41008
+ import stripe from context external_platforms
41009
+
41010
+ system checkout
41011
+ links:
41012
+ -> stripe from external_platforms
41013
+ \`\`\`
41014
+
41015
+ Avoid making a separate file for every external actor or vendor unless the
41016
+ external dependency itself has substantial reusable structure. A small number of
41017
+ well-named external contexts gives all repository systems one shared vocabulary
41018
+ for outside dependencies.
41019
+
41020
+ When a system file becomes too large, split details by extending the focal
41021
+ object in utility subdirectories:
41022
+
41023
+ \`\`\`text
41024
+ commerce/
41025
+ checkout.ai
41026
+ checkout-components/
41027
+ pricing.ai
41028
+ payment.ai
41029
+ inventory.ai
41030
+ \`\`\`
41031
+
41032
+ Those files should repeat the same \`context commerce\`, explicitly import the
41033
+ object being extended when it lives in another source file, and use
41034
+ \`extend service checkout_api\`, \`extend container web_app\`, or another object
41035
+ extension to add focused details.
41036
+
41037
+ ## Same-Context Cross-File Imports
41038
+
41039
+ Insight resolves unqualified ids in this order: declarations in the same source
41040
+ file, explicit imports in the same source file, then it reports an error if the
41041
+ same id exists only in another source file of the same context.
41042
+
41043
+ That means splitting one context across files still requires imports:
41044
+
41045
+ \`\`\`insight
41046
+ context services
41047
+
41048
+ deploymentProfile eu_service
41049
+ \`\`\`
41050
+
41051
+ \`\`\`insight
41052
+ context services
41053
+
41054
+ import eu_service from context services
41055
+
41056
+ system checkout
41057
+ name = Checkout
41058
+ deployment:
41059
+ usesProfile eu_service
41060
+ \`\`\`
41061
+
41062
+ This is intentional. If a file is extracted, removed, or not included in the
41063
+ project, the linker should fail with an explicit identifier/import diagnostic
41064
+ instead of silently binding to whatever remains in the context.
41065
+
41066
+ ## Inline from Context
41067
+
41068
+ When a relationship target is declared outside the current source file, prefer
41069
+ an explicit context qualifier on the link target:
41070
+
41071
+ \`\`\`insight
41072
+ context commerce
41073
+
41074
+ import payments from context external_systems
41075
+
41076
+ system checkout
41077
+ name = Checkout
41078
+ links:
41079
+ -> payments from external_systems
41080
+ technology = HTTPS
41081
+ call = POST /payments
41082
+ \`\`\`
41083
+
41084
+ The \`import <id> from context <context-id>\` line documents the dependency and
41085
+ makes the id available for attributes such as profiles and environment slots.
41086
+ The inline \`from <context-id>\` on a link target states which context owns the
41087
+ linked element. Use the same pattern for same-context cross-file links when the
41088
+ source has been split and ambiguity matters:
41089
+
41090
+ \`\`\`insight
41091
+ context services
41092
+
41093
+ import inventory_api from context services
41094
+
41095
+ system checkout_api
41096
+ links:
41097
+ -> inventory_api from services
41098
+ technology = HTTPS
41099
+ call = GET /inventory
41100
+ \`\`\`
41101
+
41102
+ This explicitness is useful during refactors: if the source file holding
41103
+ \`inventory_api\` disappears, validation points at the missing declaration
41104
+ instead of creating a hidden dependency on file layout.
41105
+
41106
+ ## C4 Multi-File Pattern
41107
+
41108
+ For C4, keep these responsibilities separate:
41109
+
41110
+ - framework file: type extensions, infra constructors, presentation/projection
41111
+ definitions;
41112
+ - inventory/profile file: concrete environments and reusable deployment
41113
+ profiles;
41114
+ - deployment-view file: the relationships whose deployment path you want to
41115
+ render for one selected view.
41116
+
41117
+ When rendering C4 with \`-s <source.ai>\`, remember that source/tab scoping is
41118
+ part of the view. Put the view-driving logical relationships in the selected
41119
+ source file, or render from the source file that owns those relationships. Keep
41120
+ imported framework and inventory reusable, but validate the rendered C4 output
41121
+ after moving traffic relationships across files:
41122
+
41123
+ \`\`\`shell
41124
+ archinsight link . --format text
41125
+ archinsight render . -c deployment_shop -s c4-deployment.ai -v c4 -f svg -o deployment-c4.svg
41126
+ \`\`\`
41127
+
41128
+ If projected infrastructure edges disappear after a split, first check whether
41129
+ the selected \`-s\` file still contains the source logical relationship or an
41130
+ intended imported deployment-view relationship. Do not fix that by duplicating
41131
+ infrastructure nodes; fix the source selection or the file boundary.
41132
+
41133
+ ## Practical Workflow
41134
+
41135
+ 1. Run \`archinsight structure . --format text\`.
41136
+ 2. Identify contexts, source files, and declaration ids before editing.
41137
+ 3. Move shared vocabulary into one framework file.
41138
+ 4. Group model files by context directory when the repository is large.
41139
+ 5. Keep each ordinary system file focused on one owned system being detailed.
41140
+ 6. Put external actors/systems in shared external contexts, not one file per
41141
+ external element.
41142
+ 7. Move reusable environments and deployment profiles into inventory/profile
41143
+ files.
41144
+ 8. Add explicit imports for every cross-file dependency, including same-context
41145
+ dependencies.
41146
+ 9. Add inline \`from <context-id>\` on relationship targets that live outside
41147
+ the current source file.
41148
+ 10. Validate with \`archinsight link . --format text\`.
41149
+ 11. Render important C1/C2/C3/C4 views with explicit \`-c\`, \`-s\`, and \`-v\`
41150
+ options.
41151
+ `;
41152
+ }
39249
41153
  function genericProjectStructureReference() {
39250
41154
  return `# Project Structure Workflow
39251
41155
 
@@ -39253,6 +41157,37 @@ Use \`archinsight structure\` before broad edits, imports, or declaration lookup
39253
41157
  Do not start with raw grep when you need to know what the linked project
39254
41158
  contains.
39255
41159
 
41160
+ ## Source File Classes
41161
+
41162
+ Keep source files in one role:
41163
+
41164
+ - definition/framework files: \`define type\`, \`define operator\`,
41165
+ \`define presentation\`, \`extend type\`, \`extend enum of\`, and
41166
+ \`extend presentation\`;
41167
+ - model files: \`context <id>\`, imports, graph object declarations,
41168
+ relationships, environments, and deployment profiles.
41169
+
41170
+ Do not mix definition/framework declarations with \`context <id>\` in one file.
41171
+ When a model needs custom vocabulary, add or edit a framework file first, then
41172
+ use the resulting constructors and attributes from model files.
41173
+
41174
+ ## Directory and File Granularity
41175
+
41176
+ For larger repositories, group model files by context directory. Inside a
41177
+ context directory, default to one primary owned system per ordinary model file:
41178
+ the system that will be detailed by containers, services, components, links, and
41179
+ deployment information.
41180
+
41181
+ External actors and systems are different. Put reusable outside dependencies in
41182
+ one external context or a few semantically grouped external contexts. Do not
41183
+ create a separate file for every external actor or vendor unless that external
41184
+ dependency has real internal structure to model.
41185
+
41186
+ If a system needs further splitting, create a utility subdirectory for focused
41187
+ \`extend <object>\` files, such as per-service component files. Import the
41188
+ extended object explicitly when it is declared in another source file. Keep the
41189
+ main system file as the readable entry point.
41190
+
39256
41191
  ## Commands
39257
41192
 
39258
41193
  Human-readable overview:
@@ -39300,6 +41235,33 @@ links:
39300
41235
  -> payments from external_systems
39301
41236
  \`\`\`
39302
41237
 
41238
+ Imports are also required when a declaration lives in another source file of the
41239
+ same context:
41240
+
41241
+ \`\`\`insight
41242
+ context services
41243
+
41244
+ import eu_service from context services
41245
+
41246
+ system checkout_api
41247
+ deployment:
41248
+ usesProfile eu_service
41249
+ \`\`\`
41250
+
41251
+ The explicit import is intentional. If the source file that declared
41252
+ \`eu_service\` is removed or excluded, validation should fail with a clear
41253
+ missing import/identifier diagnostic instead of depending on hidden file layout.
41254
+
41255
+ For links, \`from <context-id>\` on the target is an inline context qualifier:
41256
+
41257
+ \`\`\`insight
41258
+ links:
41259
+ -> inventory_api from services
41260
+ \`\`\`
41261
+
41262
+ Use it when the relationship target is owned by another context or another
41263
+ source file whose context ownership should remain visible at the call site.
41264
+
39303
41265
  Do not guess context ids from filenames. Filenames, context ids, and element ids
39304
41266
  can differ.
39305
41267
 
@@ -39357,6 +41319,25 @@ Interpretation:
39357
41319
  Users can define more types in project files. Always inspect project structure
39358
41320
  and project framework files before assuming only core constructors exist.
39359
41321
 
41322
+ ## Built-in Deployment Infrastructure
41323
+
41324
+ \`core_deployment.ai\` provides common infrastructure inventory types:
41325
+
41326
+ - \`InfrastructureComponent\`: optional \`name\`, \`technology\`,
41327
+ \`description\`, plus deployment references.
41328
+ - \`Storage\` / constructor \`storage\`: for databases, buckets, volumes, and
41329
+ other stateful stores.
41330
+ - \`Broker\` / constructor \`broker\`: for message brokers and event buses;
41331
+ adds optional \`address\`.
41332
+ - \`Compute\` / constructor \`compute\`: for runtimes, clusters, nodes, and
41333
+ platforms; adds optional \`address\` and can contain nested infrastructure
41334
+ components in a \`components:\` block.
41335
+ - \`NetworkConnection\` / constructor \`networkConnection\`: for a direct
41336
+ network hop that projects \`$from -> $to\` on deployment views.
41337
+
41338
+ Extend \`Environment\` with slots for these types, then fill each concrete
41339
+ \`environment <id>\` with env-local instances.
41340
+
39360
41341
  ## Reading Type Extensions
39361
41342
 
39362
41343
  Project files can extend built-in or custom types:
@@ -39365,6 +41346,7 @@ Project files can extend built-in or custom types:
39365
41346
  extend type Environment
39366
41347
  Compute compute
39367
41348
  Storage storage
41349
+ Broker broker
39368
41350
  \`\`\`
39369
41351
 
39370
41352
  Interpretation:
@@ -39737,6 +41719,16 @@ diagram needs stable layout.
39737
41719
 
39738
41720
  ## Built-In View Patterns
39739
41721
 
41722
+ Exact built-in query sources are bundled in:
41723
+
41724
+ \`\`\`text
41725
+ examples/builtin-views/no-filter.aiq
41726
+ examples/builtin-views/c1.aiq
41727
+ examples/builtin-views/c2.aiq
41728
+ examples/builtin-views/c3.aiq
41729
+ examples/builtin-views/c4.aiq
41730
+ \`\`\`
41731
+
39740
41732
  C1 usually selects systems in the selected context and rolls lower-level links
39741
41733
  up to system-level relationships.
39742
41734
 
@@ -39749,6 +41741,10 @@ and returns component relationships.
39749
41741
  C4 usually selects deployment and container nodes from \`$tab\`, uses
39750
41742
  \`OPTIONAL MATCH ROLLUP\`, and returns projected relationships.
39751
41743
 
41744
+ When a built-in view is close but hides the wrong thing, read
41745
+ \`references/query-recipes.md\`, copy the nearest built-in \`.aiq\`, and change
41746
+ the filter or grouping deliberately.
41747
+
39752
41748
  ## Authoring Rules
39753
41749
 
39754
41750
  - Start from the view question: context, containers, components, or deployment.
@@ -39759,6 +41755,189 @@ C4 usually selects deployment and container nodes from \`$tab\`, uses
39759
41755
  - Keep custom queries in \`.aiq\` files when they are reused.
39760
41756
  `;
39761
41757
  }
41758
+ function genericQueryRecipesReference() {
41759
+ return `# Query Recipes and Built-In View Customization
41760
+
41761
+ Use this reference when a built-in C1/C2/C3/C4 view is close but not quite right:
41762
+ an expected element is hidden, a relationship is missing, infrastructure is too
41763
+ noisy, or the diagram needs a different scope.
41764
+
41765
+ ## Start From Built-In Queries
41766
+
41767
+ The generated skill includes exact built-in view queries:
41768
+
41769
+ \`\`\`text
41770
+ examples/builtin-views/no-filter.aiq
41771
+ examples/builtin-views/c1.aiq
41772
+ examples/builtin-views/c2.aiq
41773
+ examples/builtin-views/c3.aiq
41774
+ examples/builtin-views/c4.aiq
41775
+ \`\`\`
41776
+
41777
+ Before inventing a query from scratch, open the nearest built-in query, copy it
41778
+ to the project, and make the smallest change.
41779
+
41780
+ \`\`\`shell
41781
+ archinsight query . -c <context-id> -s <source.ai> -q queries/custom.aiq -f text
41782
+ archinsight render . -c <context-id> -s <source.ai> -q queries/custom.aiq -f svg -o custom.svg
41783
+ \`\`\`
41784
+
41785
+ Use \`references/queries.md\` for syntax details. Use this file for common
41786
+ customization patterns.
41787
+
41788
+ ## When To Customize
41789
+
41790
+ Write or adjust a \`.aiq\` query when:
41791
+
41792
+ - the built-in view hides a node or edge that exists in \`archinsight link\`;
41793
+ - the source/tab scope is right but the view intentionally filters out a type;
41794
+ - C4 should include actors, vendors, or a special deployment path;
41795
+ - the diagram should show only one layer, one flow, or one relationship class;
41796
+ - grouping needs to change, such as grouping by parent instead of \`runsOn\`.
41797
+
41798
+ Do not compensate for a view filter by duplicating model elements. First inspect
41799
+ the built-in query and decide whether the model or the query owns the behavior.
41800
+
41801
+ ## Diagnose A Missing Element
41802
+
41803
+ 1. Validate the model:
41804
+
41805
+ \`\`\`shell
41806
+ archinsight link . --format text
41807
+ \`\`\`
41808
+
41809
+ 2. Inspect declarations and source identities:
41810
+
41811
+ \`\`\`shell
41812
+ archinsight structure . --format text
41813
+ \`\`\`
41814
+
41815
+ 3. Run the built-in query text explicitly:
41816
+
41817
+ \`\`\`shell
41818
+ archinsight query . -c <context-id> -s <source.ai> -q examples/builtin-views/c4.aiq -f text
41819
+ \`\`\`
41820
+
41821
+ 4. Check the query filters:
41822
+
41823
+ - \`node.sourceIdentity = $tab\` means the node must be declared in the selected
41824
+ source file.
41825
+ - \`node IS DeploymentElement\` hides actors and ordinary logical elements.
41826
+ - \`{projected}\` means only derived deployment projection edges are selected.
41827
+ - \`{derived}\` means only rolled-up relationships are selected.
41828
+ - \`sourceIdentity: $tab\` on an edge means the relationship/projection must come
41829
+ from the selected source.
41830
+
41831
+ ## Include External Actors In C4
41832
+
41833
+ The built-in C4 query focuses on deployment/container nodes. If a deployment
41834
+ diagram needs the external actor that starts the traffic path, copy
41835
+ \`examples/builtin-views/c4.aiq\` and widen the node and projected target filters:
41836
+
41837
+ \`\`\`cypher
41838
+ MATCH (node:Element)
41839
+ WHERE node.sourceIdentity = $tab
41840
+ AND (node IS DeploymentElement OR node IS ContainerElement OR node IS Actor)
41841
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
41842
+ WHERE projectedTarget IS DeploymentElement
41843
+ OR projectedTarget IS ContainerElement
41844
+ OR projectedTarget IS External
41845
+ OR projectedTarget IS Actor
41846
+ OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
41847
+ WHERE node IS DeploymentElement
41848
+ AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
41849
+ GROUP BY node.runsOn
41850
+ RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
41851
+ \`\`\`
41852
+
41853
+ If the actor is declared in another source file, either render from that source
41854
+ or relax the \`node.sourceIdentity = $tab\` condition intentionally.
41855
+
41856
+ ## Show Only Async Flows
41857
+
41858
+ Use edge attributes when the question is about relationship kind:
41859
+
41860
+ \`\`\`cypher
41861
+ MATCH (source:Element)-[link]->(target:Element)
41862
+ WHERE source.context = $context
41863
+ AND link.model = 'async'
41864
+ GROUP BY source.parent
41865
+ RETURN source, link, target
41866
+ \`\`\`
41867
+
41868
+ This is useful for event-stream, broker, queue, or notification diagrams. Add
41869
+ \`source.sourceIdentity = $tab\` when the query should stay scoped to one file.
41870
+
41871
+ ## Hide Deployment Infrastructure
41872
+
41873
+ When a C4-oriented source file is too noisy and you only need logical containers
41874
+ or services, select logical container elements and direct logical relationships:
41875
+
41876
+ \`\`\`cypher
41877
+ MATCH (node:ContainerElement)
41878
+ WHERE node.sourceIdentity = $tab
41879
+ OPTIONAL MATCH (node)-[link]->(target:ContainerElement)
41880
+ GROUP BY node.parent
41881
+ RETURN node, link, target
41882
+ \`\`\`
41883
+
41884
+ This is intentionally closer to C2 than C4. Use it when deployment annotations
41885
+ exist in the file but the diagram question is still logical.
41886
+
41887
+ ## Show Projected Edges Across Split Files
41888
+
41889
+ The built-in C4 query restricts projected edges to \`sourceIdentity: $tab\`. That
41890
+ is usually correct for a focused deployment-view source file, but it can hide
41891
+ projected edges when traffic relationships were split across files.
41892
+
41893
+ Copy \`examples/builtin-views/c4.aiq\` and relax only the projected edge selector:
41894
+
41895
+ \`\`\`cypher
41896
+ MATCH (node:Element)
41897
+ WHERE node.sourceIdentity = $tab
41898
+ AND (node IS DeploymentElement OR node IS ContainerElement)
41899
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected}]->(projectedTarget:Element)
41900
+ WHERE projectedTarget IS DeploymentElement
41901
+ OR projectedTarget IS ContainerElement
41902
+ OR projectedTarget IS External
41903
+ OPTIONAL MATCH (node)-[directDeploymentLink {sourceIdentity: $tab}]->(directDeploymentTarget:Element)
41904
+ WHERE node IS DeploymentElement
41905
+ AND (directDeploymentTarget IS DeploymentElement OR directDeploymentTarget IS External)
41906
+ GROUP BY node.runsOn
41907
+ RETURN node, projectedLink, projectedTarget, directDeploymentLink, directDeploymentTarget
41908
+ \`\`\`
41909
+
41910
+ Use this deliberately. Removing the source filter can bring in projections from
41911
+ other view files, so validate the result with \`archinsight query\` before
41912
+ rendering.
41913
+
41914
+ ## Change Grouping
41915
+
41916
+ Grouping controls visual clusters. If C4 grouping by \`runsOn\` is not helpful,
41917
+ try grouping by parent:
41918
+
41919
+ \`\`\`cypher
41920
+ MATCH (node:Element)
41921
+ WHERE node.sourceIdentity = $tab
41922
+ AND (node IS DeploymentElement OR node IS ContainerElement)
41923
+ OPTIONAL MATCH ROLLUP (node)-[projectedLink {projected, sourceIdentity: $tab}]->(projectedTarget:Element)
41924
+ WHERE projectedTarget IS DeploymentElement
41925
+ OR projectedTarget IS ContainerElement
41926
+ OR projectedTarget IS External
41927
+ GROUP BY node.parent
41928
+ RETURN node, projectedLink, projectedTarget
41929
+ \`\`\`
41930
+
41931
+ Use \`GROUP BY node.runsOn\` for deployment placement; use \`GROUP BY node.parent\`
41932
+ for logical ownership.
41933
+
41934
+ ## Working Rule
41935
+
41936
+ If a diagram looks wrong but \`archinsight link\` is clean, inspect the selected
41937
+ source, built-in query, and returned aliases before changing the model. Many
41938
+ display issues are query scope issues, not schema or linker bugs.
41939
+ `;
41940
+ }
39762
41941
  function genericLayeredArchitectureExample() {
39763
41942
  return `context shop
39764
41943
  name = Shop Platform
@@ -39811,6 +41990,429 @@ system storefront
39811
41990
  responsibility = Calls the payment provider and normalizes errors
39812
41991
  `;
39813
41992
  }
41993
+ function genericC1ContextExample() {
41994
+ return `context customer_portal
41995
+ name = Customer Portal
41996
+
41997
+ external actor customer
41998
+ name = Customer
41999
+ technology = Browser, mobile app
42000
+ description = Manages account details and service requests
42001
+ links:
42002
+ -> portal
42003
+ description = Views account state and submits requests
42004
+
42005
+ external actor support_agent
42006
+ name = Support agent
42007
+ technology = Back-office browser
42008
+ description = Helps customers resolve account and service issues
42009
+ links:
42010
+ -> service_console
42011
+ description = Reviews account state and updates service requests
42012
+
42013
+ external system identity_provider
42014
+ name = Identity Provider
42015
+ technology = OIDC
42016
+ description = Authenticates customers and support staff
42017
+
42018
+ external system notification_platform
42019
+ name = Notification Platform
42020
+ technology = Email, SMS
42021
+ description = Sends customer notifications
42022
+
42023
+ system portal
42024
+ name = Portal
42025
+ technology = Web application
42026
+ description = Customer-facing self-service experience
42027
+ links:
42028
+ -> identity_provider
42029
+ technology = OIDC
42030
+ description = Authenticates customers
42031
+ -> notification_platform
42032
+ technology = HTTPS
42033
+ description = Sends request status notifications
42034
+
42035
+ system service_console
42036
+ name = Service Console
42037
+ technology = Internal web application
42038
+ description = Support-facing account and request management
42039
+ links:
42040
+ -> portal
42041
+ description = Reads customer account and request state
42042
+ -> identity_provider
42043
+ technology = OIDC
42044
+ description = Authenticates support staff
42045
+ `;
42046
+ }
42047
+ function genericC2ContainersExample() {
42048
+ return `context fulfillment
42049
+ name = Fulfillment Platform
42050
+
42051
+ external actor warehouse_operator
42052
+ name = Warehouse operator
42053
+ technology = Browser
42054
+ description = Picks, packs, and ships orders
42055
+ links:
42056
+ -> warehouse_ui
42057
+ description = Processes pick, pack, and ship work
42058
+
42059
+ external system carrier_api
42060
+ name = Carrier API
42061
+ technology = HTTPS API
42062
+ description = Books shipments and returns tracking updates
42063
+
42064
+ external system notification_platform
42065
+ name = Notification Platform
42066
+ technology = HTTPS API
42067
+ description = Sends shipment notifications to customers
42068
+
42069
+ system fulfillment
42070
+ name = Fulfillment
42071
+ technology = Fulfillment system
42072
+ description = Coordinates packing, shipping, and customer shipment updates
42073
+
42074
+ container warehouse_ui
42075
+ name = Warehouse UI
42076
+ technology = React, TypeScript
42077
+ description = Guides warehouse operators through pick, pack, and ship flows
42078
+ links:
42079
+ -> fulfillment_api
42080
+ technology = HTTPS, JSON
42081
+ call = POST /shipments
42082
+ description = Creates and updates shipment work
42083
+
42084
+ service fulfillment_api
42085
+ name = Fulfillment API
42086
+ technology = Kotlin, PostgreSQL
42087
+ description = Owns fulfillment workflow state and carrier integration
42088
+ links:
42089
+ -> carrier_api
42090
+ technology = HTTPS
42091
+ call = POST /labels
42092
+ description = Buys shipment labels
42093
+ -> notification_worker
42094
+ description = Enqueues shipment notification work
42095
+
42096
+ service notification_worker
42097
+ name = Notification Worker
42098
+ technology = Node.js worker
42099
+ description = Sends asynchronous shipment notifications
42100
+ links:
42101
+ -> notification_platform
42102
+ technology = HTTPS
42103
+ call = POST /messages
42104
+ description = Sends shipment status notifications
42105
+ `;
42106
+ }
42107
+ function genericC3ComponentsExample() {
42108
+ return `context commerce
42109
+ name = Commerce Platform
42110
+
42111
+ external actor shopper
42112
+ name = Shopper
42113
+ technology = Browser
42114
+ links:
42115
+ -> web_app
42116
+
42117
+ external system payment_provider
42118
+ name = Payment Provider
42119
+ technology = HTTPS API
42120
+
42121
+ external system analytics_platform
42122
+ name = Analytics Platform
42123
+ technology = Kafka consumer
42124
+
42125
+ system storefront
42126
+ name = Storefront
42127
+ technology = Commerce system
42128
+
42129
+ container web_app
42130
+ name = Web app
42131
+ technology = SvelteKit, TypeScript
42132
+ description = Presents checkout screens and calls the backend API
42133
+
42134
+ component checkout_page
42135
+ name = Checkout page
42136
+ technology = Svelte
42137
+ responsibility = Collects checkout details and shows order progress
42138
+ links:
42139
+ -> api_client
42140
+
42141
+ component api_client
42142
+ name = API client
42143
+ technology = Fetch, JSON
42144
+ responsibility = Wraps backend calls and maps transport errors to UI state
42145
+ links:
42146
+ -> checkout_api
42147
+ technology = HTTPS, JSON
42148
+ call = POST /checkout
42149
+
42150
+ service checkout_api
42151
+ name = Checkout API
42152
+ technology = Kotlin, PostgreSQL
42153
+ description = Prices carts, creates orders, and coordinates payment
42154
+ links:
42155
+ ~> analytics_platform
42156
+ technology = Kafka
42157
+ via = checkout.completed
42158
+ description = Publishes completed checkout events
42159
+
42160
+ component checkout_controller
42161
+ name = Checkout controller
42162
+ technology = REST controller
42163
+ responsibility = Accepts checkout requests and returns order status
42164
+ links:
42165
+ -> checkout_service
42166
+
42167
+ component checkout_service
42168
+ name = Checkout service
42169
+ technology = Kotlin
42170
+ responsibility = Coordinates pricing, payment authorization, and order creation
42171
+ links:
42172
+ -> payment_gateway
42173
+ call = authorize(paymentCommand)
42174
+ description = Requests payment authorization
42175
+ -> order_repository
42176
+ ~> checkout_events
42177
+ technology = Kafka
42178
+ via = checkout.completed
42179
+ description = Publishes completed checkout events
42180
+
42181
+ component payment_gateway
42182
+ name = Payment gateway
42183
+ technology = HTTP client
42184
+ responsibility = Translates internal payment commands to provider API calls
42185
+ links:
42186
+ -> payment_provider
42187
+ technology = HTTPS
42188
+ call = POST /payments/authorizations
42189
+ description = Authorizes customer payment
42190
+
42191
+ component order_repository
42192
+ name = Order repository
42193
+ technology = SQL
42194
+ responsibility = Stores order state and checkout audit records
42195
+
42196
+ component checkout_events
42197
+ name = Checkout events
42198
+ technology = Kafka producer
42199
+ responsibility = Publishes checkout lifecycle events for downstream consumers
42200
+ `;
42201
+ }
42202
+ function genericC4DeploymentFrameworkExample() {
42203
+ return `extend type Environment
42204
+ ServiceProvider cloud
42205
+ Compute compute
42206
+ Storage storage
42207
+ Broker broker
42208
+ PublicGateway publicGateway
42209
+ Monitoring observability
42210
+ NetworkConnection network
42211
+
42212
+ define type ServiceProvider of InfrastructureComponent
42213
+ constructor serviceProvider
42214
+
42215
+ define type PublicGateway of InfrastructureComponent
42216
+ constructor publicGateway
42217
+ required InfrastructureComponent cdn
42218
+ required InfrastructureComponent loadBalancer
42219
+
42220
+ project:
42221
+ $from -> cdn
42222
+ cdn -> loadBalancer
42223
+ loadBalancer -> $this
42224
+ $this -> $to
42225
+
42226
+ define type Monitoring of InfrastructureComponent
42227
+ constructor monitoring
42228
+ required InfrastructureComponent display
42229
+
42230
+ project:
42231
+ $this -> $from
42232
+ $this -> display
42233
+
42234
+ `;
42235
+ }
42236
+ function genericC4DeploymentExample() {
42237
+ return `context deployment_shop
42238
+ name = Deployment Shop
42239
+
42240
+ external actor shopper
42241
+ name = Shopper
42242
+ technology = Browser
42243
+ links:
42244
+ -> web_app
42245
+ deployment:
42246
+ environmentsFrom public_regional_service
42247
+ uses publicGateway
42248
+
42249
+ external system payment_provider
42250
+ name = Payment Provider
42251
+ technology = HTTPS API
42252
+
42253
+ deploymentProfile regional_service
42254
+ environments:
42255
+ prod
42256
+ staging
42257
+
42258
+ runsOn compute
42259
+ uses observability
42260
+
42261
+ deploymentProfile public_regional_service
42262
+ environments:
42263
+ prod
42264
+ staging
42265
+
42266
+ runsOn compute
42267
+ uses observability
42268
+
42269
+ environment prod
42270
+ name = Production
42271
+
42272
+ cloud:
42273
+ serviceProvider _
42274
+ name = AWS
42275
+
42276
+ compute:
42277
+ compute _
42278
+ name = EKS
42279
+ runsOn cloud
42280
+
42281
+ storage:
42282
+ storage _
42283
+ name = Aurora PostgreSQL
42284
+ technology = PostgreSQL
42285
+ runsOn cloud
42286
+
42287
+ broker:
42288
+ broker _
42289
+ name = Event broker
42290
+ technology = MSK Kafka
42291
+ address = kafka.prod.internal:9092
42292
+ runsOn compute
42293
+
42294
+ publicGateway:
42295
+ publicGateway _
42296
+ name = Public edge
42297
+ cdn:
42298
+ infrastructureComponent cloudfront
42299
+ name = CloudFront
42300
+ runsOn cloud
42301
+ loadBalancer:
42302
+ infrastructureComponent alb
42303
+ name = Application Load Balancer
42304
+ runsOn cloud
42305
+ runsOn compute
42306
+
42307
+ observability:
42308
+ monitoring _
42309
+ name = OpenTelemetry Collector
42310
+ display:
42311
+ infrastructureComponent _
42312
+ name = Grafana Cloud
42313
+ runsOn compute
42314
+
42315
+ network:
42316
+ networkConnection _
42317
+ name = Service mesh
42318
+ runsOn compute
42319
+
42320
+ environment staging
42321
+ name = Staging
42322
+
42323
+ cloud:
42324
+ serviceProvider _
42325
+ name = Google Cloud
42326
+
42327
+ compute:
42328
+ compute _
42329
+ name = Cloud Run
42330
+ runsOn cloud
42331
+
42332
+ storage:
42333
+ storage _
42334
+ name = Cloud SQL
42335
+ technology = PostgreSQL
42336
+ runsOn cloud
42337
+
42338
+ broker:
42339
+ broker _
42340
+ name = Event broker
42341
+ technology = Pub/Sub
42342
+ address = pubsub.googleapis.com
42343
+ runsOn compute
42344
+
42345
+ publicGateway:
42346
+ publicGateway _
42347
+ name = Public edge
42348
+ cdn:
42349
+ infrastructureComponent cloud_cdn
42350
+ name = Cloud CDN
42351
+ runsOn cloud
42352
+ loadBalancer:
42353
+ infrastructureComponent https_lb
42354
+ name = HTTPS Load Balancer
42355
+ runsOn cloud
42356
+ runsOn compute
42357
+
42358
+ observability:
42359
+ monitoring _
42360
+ name = Cloud Monitoring Agent
42361
+ display:
42362
+ infrastructureComponent _
42363
+ name = Cloud Monitoring
42364
+ runsOn compute
42365
+
42366
+ network:
42367
+ networkConnection _
42368
+ name = Internal routes
42369
+ runsOn compute
42370
+
42371
+ system storefront
42372
+ name = Storefront
42373
+ technology = Commerce system
42374
+
42375
+ container web_app
42376
+ name = Web app
42377
+ technology = SvelteKit, TypeScript
42378
+ description = Customer-facing checkout application
42379
+ deployment:
42380
+ usesProfile public_regional_service
42381
+ links:
42382
+ -> checkout_api
42383
+ technology = HTTPS, JSON
42384
+ call = POST /checkout
42385
+ deployment:
42386
+ environmentsFrom regional_service
42387
+ uses network
42388
+
42389
+ service checkout_api
42390
+ name = Checkout API
42391
+ technology = Kotlin, PostgreSQL
42392
+ description = Creates orders and coordinates payment
42393
+ deployment:
42394
+ usesProfile regional_service
42395
+ uses storage
42396
+ links:
42397
+ ~> order_worker
42398
+ technology = Kafka
42399
+ via = orders.events
42400
+ deployment:
42401
+ environmentsFrom regional_service
42402
+ uses broker
42403
+
42404
+ -> payment_provider
42405
+ technology = HTTPS
42406
+ call = POST /payments/authorizations
42407
+
42408
+ service order_worker
42409
+ name = Order Worker
42410
+ technology = Kotlin
42411
+ description = Processes order events asynchronously
42412
+ deployment:
42413
+ usesProfile regional_service
42414
+ `;
42415
+ }
39814
42416
  function genericC2QueryExample() {
39815
42417
  return `MATCH (container:ContainerElement)
39816
42418
  WHERE container.sourceIdentity = $tab