@principal-ai/subsystems-core 0.31.4 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,6 +13,7 @@
13
13
  *
14
14
  * Ontology: construct = what a node is, framework + stereotype = which
15
15
  * framework pattern it plays, role = where it sits, process = where it runs,
16
+ * module = which source file/module the export belongs to,
16
17
  * proposed = not yet in source (design / migration placeholder).
17
18
  * `symbol` is the code identity; `name` is the display label.
18
19
  */
@@ -40,8 +41,21 @@ export type SubsystemFramework = string;
40
41
  * Empty when no framework pattern applies. Pair with `framework` when set.
41
42
  */
42
43
  export type SubsystemStereotype = string;
43
- /** How `from` relates to `to` on an edge. */
44
- export type SubsystemEdgeMechanism = 'imports' | 'imports_from' | 're_exports' | 'defines' | 'calls' | 'extends' | 'inherits' | 'implements' | 'mixes_in' | 'uses' | 'method' | 'references' | 'contains' | 'feeds' | 'produces' | 'writes' | 'reads' | 'watches' | 'registers-into';
44
+ /**
45
+ * Topology relation type — structural / module / type claims between
46
+ * components. Belongs on `relations[]`, not on walkthrough hops.
47
+ */
48
+ export type SubsystemRelationType = 'imports' | 'extends' | 'inherits' | 'implements' | 'mixes_in' | 'method' | 'references' | 'contains';
49
+ /**
50
+ * Walkthrough hop mechanism — runtime seams with a `file:line` site.
51
+ * Belongs on walkthrough steps; graph edges for these are derived.
52
+ */
53
+ export type SubsystemWalkthroughMechanism = 'calls' | 'uses' | 'feeds' | 'produces' | 'writes' | 'reads' | 'watches' | 'registers-into';
54
+ /**
55
+ * Union used by derived graph edges / styling (topology relationType or
56
+ * walkthrough hop mechanism).
57
+ */
58
+ export type SubsystemEdgeMechanism = SubsystemRelationType | SubsystemWalkthroughMechanism;
45
59
  export type SubsystemDeclarationProvenance = 'verified' | 'authored';
46
60
  export type SubsystemDeclTokenKind = 'keyword' | 'name' | 'member' | 'type' | 'punctuation' | 'string' | 'newline';
47
61
  export interface SubsystemDeclToken {
@@ -91,12 +105,6 @@ export interface SubsystemReferenceInfo {
91
105
  context?: string;
92
106
  source_location?: string;
93
107
  }
94
- export interface SubsystemImportInfo {
95
- nodeId: string;
96
- name: string;
97
- relation?: string;
98
- source_location?: string;
99
- }
100
108
  export interface SubsystemClassDeclaration {
101
109
  kind: 'class';
102
110
  methods: SubsystemMethodInfo[];
@@ -120,17 +128,46 @@ export interface SubsystemMethodDeclaration {
120
128
  parameters?: SubsystemParamInfo[];
121
129
  returnType?: string;
122
130
  }
131
+ /** One generic type parameter, e.g. `T` or `K extends keyof StudioMessages`. */
132
+ export interface SubsystemTypeParamInfo {
133
+ name: string;
134
+ /** Constraint written after `extends` (or language equivalent). */
135
+ constraint?: string;
136
+ }
137
+ /** A callable/function type: `(params) => returnType`. */
138
+ export interface SubsystemCallableTypeInfo {
139
+ parameters?: SubsystemParamInfo[];
140
+ returnType?: string;
141
+ }
142
+ /** One enum member, with its optional literal value. */
143
+ export interface SubsystemEnumMemberInfo {
144
+ name: string;
145
+ value?: string;
146
+ }
147
+ /**
148
+ * Type-family declaration (interface / type alias / enum). Structured buckets
149
+ * cover common shapes; `rhs` is the verbatim escape hatch when none fit.
150
+ */
123
151
  export interface SubsystemTypeDeclaration {
124
152
  kind: 'type';
125
153
  properties: SubsystemPropertyInfo[];
126
154
  usedBy: SubsystemReferenceInfo[];
127
155
  implementors: string[];
128
- }
129
- export interface SubsystemModuleDeclaration {
130
- kind: 'module';
131
- exports: string[];
132
- imports: SubsystemImportInfo[];
133
- symbols: string[];
156
+ /** Generic type parameters, e.g. `<K extends keyof StudioMessages>`. */
157
+ generics?: SubsystemTypeParamInfo[];
158
+ /** Callable type — `(params) => returnType`. */
159
+ signature?: SubsystemCallableTypeInfo;
160
+ /** Enum members (name, optional literal value). */
161
+ enumMembers?: SubsystemEnumMemberInfo[];
162
+ /** Alias whose RHS is a plain reference, e.g. `ServerSessionRow[]`. */
163
+ aliasOf?: string;
164
+ /** Simple union of alternatives, e.g. `'started' | 'stopped'`. */
165
+ unionOf?: string[];
166
+ /**
167
+ * Verbatim RHS — escape hatch for shapes the structured fields can't
168
+ * express. Wins over every shape above when set.
169
+ */
170
+ rhs?: string;
134
171
  }
135
172
  export interface SubsystemExternalDeclaration {
136
173
  kind: 'external';
@@ -138,6 +175,11 @@ export interface SubsystemExternalDeclaration {
138
175
  }
139
176
  export interface SubsystemStoreDeclaration {
140
177
  kind: 'store';
178
+ /** Where retained state lives / who mediates access. Authored, never
179
+ * extracted: `memory` (process-lifetime RAM), `disk` (this process
180
+ * reads/writes files), or `external` (another system — db/service; carries
181
+ * no `process`). */
182
+ storage?: 'memory' | 'disk' | 'external';
141
183
  properties: SubsystemPropertyInfo[];
142
184
  }
143
185
  /** A single authored attribute on a custom entity — free-form key/value. */
@@ -155,7 +197,7 @@ export interface SubsystemCustomEntityDeclaration {
155
197
  attributes: SubsystemCustomEntityAttribute[];
156
198
  }
157
199
  /** Structured declaration shape of a construct. */
158
- export type SubsystemConstructDeclaration = SubsystemClassDeclaration | SubsystemFunctionDeclaration | SubsystemMethodDeclaration | SubsystemTypeDeclaration | SubsystemModuleDeclaration | SubsystemExternalDeclaration | SubsystemStoreDeclaration | SubsystemCustomEntityDeclaration;
200
+ export type SubsystemConstructDeclaration = SubsystemClassDeclaration | SubsystemFunctionDeclaration | SubsystemMethodDeclaration | SubsystemTypeDeclaration | SubsystemExternalDeclaration | SubsystemStoreDeclaration | SubsystemCustomEntityDeclaration;
159
201
  /** A component node — the named unit, construct-tagged. */
160
202
  export interface SubsystemComponent {
161
203
  id: string;
@@ -186,6 +228,15 @@ export interface SubsystemComponent {
186
228
  */
187
229
  stereotype?: SubsystemStereotype;
188
230
  process?: string;
231
+ /**
232
+ * Source-module membership — which file/module this export belongs to
233
+ * (e.g. `src/session/transcript.ts`). Nodes sharing a `module` are drawn
234
+ * inside one boundary frame. Prefer this over inventing a module construct:
235
+ * anchor each export as its real construct (`function` / `class` / …) and
236
+ * set `module` so the file reads as a frame, not a node. Orthogonal to
237
+ * `process` (runtime deployment unit).
238
+ */
239
+ module?: string;
189
240
  /** Code identity — real declaration in `file` when set. */
190
241
  symbol?: string;
191
242
  /**
@@ -206,19 +257,35 @@ export interface SubsystemComponent {
206
257
  /** Location anchor (file/line/hash) — distinct from `declaration` (shape). */
207
258
  declarationRef?: SubsystemDeclarationRef;
208
259
  }
209
- /** A cross-component edge. */
210
- export interface SubsystemComponentEdge {
260
+ /** A topology relation between components (structural / module / type). */
261
+ export interface SubsystemRelation {
211
262
  id: string;
212
263
  /** Source component id. */
213
264
  from: string;
214
265
  /** Target component id (or external label). */
215
266
  to: string;
216
- mechanism: SubsystemEdgeMechanism;
267
+ relationType: SubsystemRelationType;
217
268
  /** Concrete file/symbol evidence (often purls). */
218
269
  refs?: string[];
219
270
  }
220
- export interface SubsystemThroughlineStep {
221
- edgeId: string;
271
+ /**
272
+ * Derived / display graph edge used by renderers. Built from `relations`
273
+ * and/or walkthrough hops — not authored as its own document field.
274
+ */
275
+ export interface SubsystemComponentEdge {
276
+ id: string;
277
+ from: string;
278
+ to: string;
279
+ mechanism: SubsystemEdgeMechanism;
280
+ refs?: string[];
281
+ }
282
+ export interface SubsystemWalkthroughStep {
283
+ /** Source component id. */
284
+ from: string;
285
+ /** Target component id. */
286
+ to: string;
287
+ /** Runtime seam label (Set B). */
288
+ mechanism: SubsystemWalkthroughMechanism;
222
289
  file: string;
223
290
  /** 1-based line within `file`. */
224
291
  line: number;
@@ -231,11 +298,11 @@ export interface SubsystemThroughlineStep {
231
298
  */
232
299
  annotation?: string;
233
300
  }
234
- /** Ordered execution story over existing edges (one per flow). */
235
- export interface SubsystemThroughline {
301
+ /** Ordered runtime walkthrough (one named behavior story). */
302
+ export interface SubsystemWalkthrough {
236
303
  id: string;
237
304
  title: string;
238
- steps: SubsystemThroughlineStep[];
305
+ steps: SubsystemWalkthroughStep[];
239
306
  }
240
307
  export interface SubsystemRepoRef {
241
308
  owner: string;
@@ -255,8 +322,10 @@ export interface SubsystemModelDocument {
255
322
  title: string;
256
323
  description?: string;
257
324
  components: SubsystemComponent[];
258
- edges: SubsystemComponentEdge[];
259
- throughlines?: SubsystemThroughline[];
325
+ /** Topology relations (structural / module / type). May be empty. */
326
+ relations: SubsystemRelation[];
327
+ /** Runtime walkthroughs (ordered hops with sites). */
328
+ walkthroughs?: SubsystemWalkthrough[];
260
329
  }
261
330
  /**
262
331
  * Host/machine fields layered onto a portable document for local use.
@@ -305,4 +374,14 @@ export declare function isSubsystemModelDocument(value: unknown): value is Subsy
305
374
  * share surface that must stay schema-clean.
306
375
  */
307
376
  export declare function toPortableDocument(doc: SubsystemModelDocument): SubsystemModelDocument;
377
+ /** Stable id for a derived graph edge from a relation or walkthrough hop. */
378
+ export declare function derivedGraphEdgeId(from: string, to: string, mechanism: SubsystemEdgeMechanism): string;
379
+ /**
380
+ * Build display edges for the graph canvas from topology relations and
381
+ * walkthrough hops (deduped by from/to/mechanism).
382
+ */
383
+ export declare function deriveGraphEdges(doc: {
384
+ relations?: SubsystemRelation[];
385
+ walkthroughs?: SubsystemWalkthrough[];
386
+ }): SubsystemComponentEdge[];
308
387
  //# sourceMappingURL=subsystem-model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"subsystem-model.d.ts","sourceRoot":"","sources":["../../src/types/subsystem-model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subsystem-model.d.ts","sourceRoot":"","sources":["../../src/types/subsystem-model.ts"],"names":[],"mappings":"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"}
@@ -14,11 +14,12 @@
14
14
  *
15
15
  * Ontology: construct = what a node is, framework + stereotype = which
16
16
  * framework pattern it plays, role = where it sits, process = where it runs,
17
+ * module = which source file/module the export belongs to,
17
18
  * proposed = not yet in source (design / migration placeholder).
18
19
  * `symbol` is the code identity; `name` is the display label.
19
20
  */
20
21
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.toPortableDocument = exports.isSubsystemModelDocument = void 0;
22
+ exports.deriveGraphEdges = exports.derivedGraphEdgeId = exports.toPortableDocument = exports.isSubsystemModelDocument = void 0;
22
23
  /**
23
24
  * Type guard: true when the value plausibly conforms to a portable
24
25
  * subsystem model. Shallow check — full validation belongs to the schema /
@@ -30,7 +31,7 @@ function isSubsystemModelDocument(value) {
30
31
  const v = value;
31
32
  return (typeof v.title === 'string' &&
32
33
  Array.isArray(v.components) &&
33
- Array.isArray(v.edges));
34
+ Array.isArray(v.relations));
34
35
  }
35
36
  exports.isSubsystemModelDocument = isSubsystemModelDocument;
36
37
  /**
@@ -42,15 +43,54 @@ function toPortableDocument(doc) {
42
43
  const out = {
43
44
  title: doc.title,
44
45
  components: doc.components,
45
- edges: doc.edges,
46
+ relations: doc.relations,
46
47
  };
47
48
  if (doc.$schema)
48
49
  out.$schema = doc.$schema;
49
50
  if (doc.description)
50
51
  out.description = doc.description;
51
- if (doc.throughlines)
52
- out.throughlines = doc.throughlines;
52
+ if (doc.walkthroughs)
53
+ out.walkthroughs = doc.walkthroughs;
53
54
  return out;
54
55
  }
55
56
  exports.toPortableDocument = toPortableDocument;
57
+ /** Stable id for a derived graph edge from a relation or walkthrough hop. */
58
+ function derivedGraphEdgeId(from, to, mechanism) {
59
+ return `${from}--${mechanism}-->${to}`;
60
+ }
61
+ exports.derivedGraphEdgeId = derivedGraphEdgeId;
62
+ /**
63
+ * Build display edges for the graph canvas from topology relations and
64
+ * walkthrough hops (deduped by from/to/mechanism).
65
+ */
66
+ function deriveGraphEdges(doc) {
67
+ const byId = new Map();
68
+ for (const r of doc.relations ?? []) {
69
+ const id = r.id || derivedGraphEdgeId(r.from, r.to, r.relationType);
70
+ if (!byId.has(id)) {
71
+ byId.set(id, {
72
+ id,
73
+ from: r.from,
74
+ to: r.to,
75
+ mechanism: r.relationType,
76
+ refs: r.refs,
77
+ });
78
+ }
79
+ }
80
+ for (const w of doc.walkthroughs ?? []) {
81
+ for (const step of w.steps) {
82
+ const id = derivedGraphEdgeId(step.from, step.to, step.mechanism);
83
+ if (!byId.has(id)) {
84
+ byId.set(id, {
85
+ id,
86
+ from: step.from,
87
+ to: step.to,
88
+ mechanism: step.mechanism,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ return [...byId.values()];
94
+ }
95
+ exports.deriveGraphEdges = deriveGraphEdges;
56
96
  //# sourceMappingURL=subsystem-model.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"subsystem-model.js","sourceRoot":"","sources":["../../src/types/subsystem-model.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAsWH;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,KAAc;IACrD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,CAAC,GAAG,KAIT,CAAC;IACF,OAAO,CACL,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CACvB,CAAC;AACJ,CAAC;AAZD,4DAYC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAChC,GAA2B;IAE3B,MAAM,GAAG,GAA2B;QAClC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC;IACF,IAAI,GAAG,CAAC,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC3C,IAAI,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;IACvD,IAAI,GAAG,CAAC,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAZD,gDAYC"}
1
+ {"version":3,"file":"subsystem-model.js","sourceRoot":"","sources":["../../src/types/subsystem-model.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AA4aH;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,KAAc;IACrD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,CAAC,GAAG,KAIT,CAAC;IACF,OAAO,CACL,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;QAC3B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAC3B,CAAC;AACJ,CAAC;AAZD,4DAYC;AAED;;;;GAIG;AACH,SAAgB,kBAAkB,CAChC,GAA2B;IAE3B,MAAM,GAAG,GAA2B;QAClC,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;KACzB,CAAC;IACF,IAAI,GAAG,CAAC,OAAO;QAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC3C,IAAI,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;IACvD,IAAI,GAAG,CAAC,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;IAC1D,OAAO,GAAG,CAAC;AACb,CAAC;AAZD,gDAYC;AAED,6EAA6E;AAC7E,SAAgB,kBAAkB,CAChC,IAAY,EACZ,EAAU,EACV,SAAiC;IAEjC,OAAO,GAAG,IAAI,KAAK,SAAS,MAAM,EAAE,EAAE,CAAC;AACzC,CAAC;AAND,gDAMC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,GAGhC;IACC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAkC,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,SAAS,IAAI,EAAE,EAAE;QACnC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,kBAAkB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YACjB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;gBACX,EAAE;gBACF,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,SAAS,EAAE,CAAC,CAAC,YAAY;gBACzB,IAAI,EAAE,CAAC,CAAC,IAAI;aACb,CAAC,CAAC;SACJ;KACF;IACD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE;QACtC,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE;YAC1B,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAClE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBACjB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE;oBACX,EAAE;oBACF,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,EAAE,EAAE,IAAI,CAAC,EAAE;oBACX,SAAS,EAAE,IAAI,CAAC,SAAS;iBAC1B,CAAC,CAAC;aACJ;SACF;KACF;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAC5B,CAAC;AA/BD,4CA+BC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@principal-ai/subsystems-core",
3
- "version": "0.31.4",
3
+ "version": "0.33.0",
4
4
  "description": "Subsystem model types and agent-session tooling for Principal AI",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -2,12 +2,12 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://principal-ai.dev/schemas/subsystem-model.schema.json",
4
4
  "title": "Subsystem Model",
5
- "description": "Portable subsystem model — the shareable standard. Construct-tagged components (nodes) plus typed edges describing one subsystem of a codebase. Ontology: construct = what a node is, framework + stereotype = which framework pattern it plays, role = where it sits, process = where it runs. Symbol is the code identity; name is the display label (often derived from symbol). Host-only fields (local path binding, provenance, store ids, verification) are NOT part of this document; they belong on a hydrated envelope around it.",
5
+ "description": "Portable subsystem model — the shareable standard. Construct-tagged components (nodes) plus topology relations and/or runtime walkthroughs describing one subsystem of a codebase. Ontology: construct = what a node is, framework + stereotype = which framework pattern it plays, role = where it sits, process = where it runs, module = which source file/module the export belongs to. Symbol is the code identity; name is the display label (often derived from symbol). Host-only fields (local path binding, provenance, store ids, verification) are NOT part of this document; they belong on a hydrated envelope around it.",
6
6
  "type": "object",
7
7
  "required": [
8
8
  "title",
9
9
  "components",
10
- "edges"
10
+ "relations"
11
11
  ],
12
12
  "additionalProperties": false,
13
13
  "properties": {
@@ -31,18 +31,18 @@
31
31
  "$ref": "#/$defs/component"
32
32
  }
33
33
  },
34
- "edges": {
34
+ "relations": {
35
35
  "type": "array",
36
- "description": "Typed interactions between components. `from` / `to` reference component `id`s.",
36
+ "description": "Topology relations (structural / module / type). `from` / `to` reference component `id`s. Runtime seams belong on walkthrough steps, not here.",
37
37
  "items": {
38
- "$ref": "#/$defs/edge"
38
+ "$ref": "#/$defs/relation"
39
39
  }
40
40
  },
41
- "throughlines": {
41
+ "walkthroughs": {
42
42
  "type": "array",
43
- "description": "Ordered execution stories over existing edges (one throughline per flow). Each step names an edge id, the concrete file:line where that seam fires, and an optional frame symbol.",
43
+ "description": "Ordered runtime walkthroughs (one per named behavior). Each step names from/to/mechanism and the concrete file:line where that seam fires.",
44
44
  "items": {
45
- "$ref": "#/$defs/throughline"
45
+ "$ref": "#/$defs/walkthrough"
46
46
  }
47
47
  }
48
48
  },
@@ -92,23 +92,26 @@
92
92
  "authored"
93
93
  ]
94
94
  },
95
- "mechanism": {
95
+ "relationType": {
96
96
  "type": "string",
97
- "description": "How `from` relates to `to`. Pick the closest label; put specifics in `refs`. `uses` = general dependency; `feeds` = data-flow into a processor; `produces` = emits an output; `references` = type/symbol reference that is not a call; `writes`/`reads`/`watches` = retained-state interactions.",
97
+ "description": "Topology relation type — structural / module / type claim between components.",
98
98
  "enum": [
99
99
  "imports",
100
- "imports_from",
101
- "re_exports",
102
- "defines",
103
- "calls",
104
100
  "extends",
105
101
  "inherits",
106
102
  "implements",
107
103
  "mixes_in",
108
- "uses",
109
104
  "method",
110
105
  "references",
111
- "contains",
106
+ "contains"
107
+ ]
108
+ },
109
+ "mechanism": {
110
+ "type": "string",
111
+ "description": "Walkthrough hop mechanism — how `from` relates to `to` at a runtime site. `uses` = general dependency; `feeds` = data-flow into a processor; `produces` = emits an output; `writes`/`reads`/`watches` = retained-state interactions.",
112
+ "enum": [
113
+ "calls",
114
+ "uses",
112
115
  "feeds",
113
116
  "produces",
114
117
  "writes",
@@ -131,7 +134,7 @@
131
134
  "id": {
132
135
  "type": "string",
133
136
  "minLength": 1,
134
- "description": "Stable unique id. Referenced by edge `from` / `to`; never rename on update."
137
+ "description": "Stable unique id. Referenced by relation / walkthrough `from` / `to`; never rename on update."
135
138
  },
136
139
  "name": {
137
140
  "type": "string",
@@ -182,6 +185,10 @@
182
185
  "type": "string",
183
186
  "description": "Runtime process / deployment unit membership (e.g. `principal-studio/host`). Nodes sharing a process are drawn in one boundary region; nodes without one sit outside every boundary."
184
187
  },
188
+ "module": {
189
+ "type": "string",
190
+ "description": "Source-module membership — which file/module this export belongs to (e.g. `src/session/transcript.ts`). Nodes sharing a module are drawn in one boundary frame. Prefer anchoring each export as its real construct and setting module, rather than a module construct."
191
+ },
185
192
  "layer": {
186
193
  "type": "integer",
187
194
  "description": "Semantic layout layer/phase (lower = closer to entry). When set, layout places the component in this layer for a left-to-right pipeline."
@@ -206,20 +213,20 @@
206
213
  }
207
214
  }
208
215
  },
209
- "edge": {
216
+ "relation": {
210
217
  "type": "object",
211
218
  "required": [
212
219
  "id",
213
220
  "from",
214
221
  "to",
215
- "mechanism"
222
+ "relationType"
216
223
  ],
217
224
  "additionalProperties": false,
218
225
  "properties": {
219
226
  "id": {
220
227
  "type": "string",
221
228
  "minLength": 1,
222
- "description": "Stable unique edge id. Referenced by throughline steps."
229
+ "description": "Stable unique relation id."
223
230
  },
224
231
  "from": {
225
232
  "type": "string",
@@ -231,12 +238,12 @@
231
238
  "minLength": 1,
232
239
  "description": "Target component `id` (or external target label)."
233
240
  },
234
- "mechanism": {
235
- "$ref": "#/$defs/mechanism"
241
+ "relationType": {
242
+ "$ref": "#/$defs/relationType"
236
243
  },
237
244
  "refs": {
238
245
  "type": "array",
239
- "description": "Concrete file/symbol evidence backing the edge (often purl refs).",
246
+ "description": "Concrete file/symbol evidence backing the relation (often purl refs).",
240
247
  "items": {
241
248
  "type": "string",
242
249
  "minLength": 1
@@ -244,24 +251,34 @@
244
251
  }
245
252
  }
246
253
  },
247
- "throughlineStep": {
254
+ "walkthroughStep": {
248
255
  "type": "object",
249
256
  "required": [
250
- "edgeId",
257
+ "from",
258
+ "to",
259
+ "mechanism",
251
260
  "file",
252
261
  "line"
253
262
  ],
254
263
  "additionalProperties": false,
255
264
  "properties": {
256
- "edgeId": {
265
+ "from": {
266
+ "type": "string",
267
+ "minLength": 1,
268
+ "description": "Source component `id`."
269
+ },
270
+ "to": {
257
271
  "type": "string",
258
272
  "minLength": 1,
259
- "description": "Id of an existing edge this hop traverses."
273
+ "description": "Target component `id`."
274
+ },
275
+ "mechanism": {
276
+ "$ref": "#/$defs/mechanism"
260
277
  },
261
278
  "file": {
262
279
  "type": "string",
263
280
  "minLength": 1,
264
- "description": "Repo-root-relative path where the edge fires for this flow."
281
+ "description": "Repo-root-relative path where the seam fires for this walkthrough."
265
282
  },
266
283
  "line": {
267
284
  "type": "integer",
@@ -280,7 +297,7 @@
280
297
  }
281
298
  }
282
299
  },
283
- "throughline": {
300
+ "walkthrough": {
284
301
  "type": "object",
285
302
  "required": [
286
303
  "id",
@@ -292,18 +309,18 @@
292
309
  "id": {
293
310
  "type": "string",
294
311
  "minLength": 1,
295
- "description": "Stable unique throughline id."
312
+ "description": "Stable unique walkthrough id."
296
313
  },
297
314
  "title": {
298
315
  "type": "string",
299
316
  "minLength": 1,
300
- "description": "Flow name (e.g. save flow, load flow)."
317
+ "description": "Walkthrough name (e.g. save, load, refresh)."
301
318
  },
302
319
  "steps": {
303
320
  "type": "array",
304
321
  "description": "Ordered hops; array order is execution order.",
305
322
  "items": {
306
- "$ref": "#/$defs/throughlineStep"
323
+ "$ref": "#/$defs/walkthroughStep"
307
324
  }
308
325
  }
309
326
  }
@@ -496,28 +513,6 @@
496
513
  }
497
514
  }
498
515
  },
499
- "importInfo": {
500
- "type": "object",
501
- "required": [
502
- "nodeId",
503
- "name"
504
- ],
505
- "additionalProperties": false,
506
- "properties": {
507
- "nodeId": {
508
- "type": "string"
509
- },
510
- "name": {
511
- "type": "string"
512
- },
513
- "relation": {
514
- "type": "string"
515
- },
516
- "source_location": {
517
- "type": "string"
518
- }
519
- }
520
- },
521
516
  "constructDeclaration": {
522
517
  "description": "Discriminated structured declaration of a construct (`kind`). Hand-authored declarations should set component.declarationProvenance to authored.",
523
518
  "oneOf": [
@@ -533,9 +528,6 @@
533
528
  {
534
529
  "$ref": "#/$defs/typeDeclaration"
535
530
  },
536
- {
537
- "$ref": "#/$defs/moduleDeclaration"
538
- },
539
531
  {
540
532
  "$ref": "#/$defs/externalDeclaration"
541
533
  },
@@ -666,6 +658,35 @@
666
658
  }
667
659
  }
668
660
  },
661
+ "typeParamInfo": {
662
+ "type": "object",
663
+ "required": ["name"],
664
+ "additionalProperties": false,
665
+ "properties": {
666
+ "name": { "type": "string" },
667
+ "constraint": { "type": "string" }
668
+ }
669
+ },
670
+ "callableTypeInfo": {
671
+ "type": "object",
672
+ "additionalProperties": false,
673
+ "properties": {
674
+ "parameters": {
675
+ "type": "array",
676
+ "items": { "$ref": "#/$defs/paramInfo" }
677
+ },
678
+ "returnType": { "type": "string" }
679
+ }
680
+ },
681
+ "enumMemberInfo": {
682
+ "type": "object",
683
+ "required": ["name"],
684
+ "additionalProperties": false,
685
+ "properties": {
686
+ "name": { "type": "string" },
687
+ "value": { "type": "string" }
688
+ }
689
+ },
669
690
  "typeDeclaration": {
670
691
  "type": "object",
671
692
  "required": [
@@ -675,6 +696,7 @@
675
696
  "implementors"
676
697
  ],
677
698
  "additionalProperties": false,
699
+ "description": "Type-family declaration (interface / type alias / enum). Prefer structured buckets; use `rhs` when none fit.",
678
700
  "properties": {
679
701
  "kind": {
680
702
  "const": "type"
@@ -696,40 +718,24 @@
696
718
  "items": {
697
719
  "type": "string"
698
720
  }
699
- }
700
- }
701
- },
702
- "moduleDeclaration": {
703
- "type": "object",
704
- "required": [
705
- "kind",
706
- "exports",
707
- "imports",
708
- "symbols"
709
- ],
710
- "additionalProperties": false,
711
- "description": "Declaration shape for module-like drill-down. Prefer not authoring module *components*; this payload may still appear from tooling.",
712
- "properties": {
713
- "kind": {
714
- "const": "module"
715
721
  },
716
- "exports": {
722
+ "generics": {
717
723
  "type": "array",
718
- "items": {
719
- "type": "string"
720
- }
724
+ "items": { "$ref": "#/$defs/typeParamInfo" }
721
725
  },
722
- "imports": {
726
+ "signature": { "$ref": "#/$defs/callableTypeInfo" },
727
+ "enumMembers": {
723
728
  "type": "array",
724
- "items": {
725
- "$ref": "#/$defs/importInfo"
726
- }
729
+ "items": { "$ref": "#/$defs/enumMemberInfo" }
727
730
  },
728
- "symbols": {
731
+ "aliasOf": { "type": "string" },
732
+ "unionOf": {
729
733
  "type": "array",
730
- "items": {
731
- "type": "string"
732
- }
734
+ "items": { "type": "string" }
735
+ },
736
+ "rhs": {
737
+ "type": "string",
738
+ "description": "Verbatim RHS escape hatch; wins over structured buckets when set."
733
739
  }
734
740
  }
735
741
  },
@@ -767,6 +773,11 @@
767
773
  "items": {
768
774
  "$ref": "#/$defs/propertyInfo"
769
775
  }
776
+ },
777
+ "storage": {
778
+ "type": "string",
779
+ "enum": ["memory", "disk", "external"],
780
+ "description": "Where the retained state physically lives / who mediates access. Authored — graphify cannot infer it: `memory` = process-lifetime RAM, `disk` = this process reads/writes the filesystem, `external` = mediated by another system (db/service)."
770
781
  }
771
782
  }
772
783
  },
@@ -13,6 +13,7 @@
13
13
  *
14
14
  * Ontology: construct = what a node is, framework + stereotype = which
15
15
  * framework pattern it plays, role = where it sits, process = where it runs,
16
+ * module = which source file/module the export belongs to,
16
17
  * proposed = not yet in source (design / migration placeholder).
17
18
  * `symbol` is the code identity; `name` is the display label.
18
19
  */
@@ -55,21 +56,27 @@ export type SubsystemFramework = string;
55
56
  */
56
57
  export type SubsystemStereotype = string;
57
58
 
58
- /** How `from` relates to `to` on an edge. */
59
- export type SubsystemEdgeMechanism =
59
+ /**
60
+ * Topology relation type — structural / module / type claims between
61
+ * components. Belongs on `relations[]`, not on walkthrough hops.
62
+ */
63
+ export type SubsystemRelationType =
60
64
  | 'imports'
61
- | 'imports_from'
62
- | 're_exports'
63
- | 'defines'
64
- | 'calls'
65
65
  | 'extends'
66
66
  | 'inherits'
67
67
  | 'implements'
68
68
  | 'mixes_in'
69
- | 'uses'
70
69
  | 'method'
71
70
  | 'references'
72
- | 'contains'
71
+ | 'contains';
72
+
73
+ /**
74
+ * Walkthrough hop mechanism — runtime seams with a `file:line` site.
75
+ * Belongs on walkthrough steps; graph edges for these are derived.
76
+ */
77
+ export type SubsystemWalkthroughMechanism =
78
+ | 'calls'
79
+ | 'uses'
73
80
  | 'feeds'
74
81
  | 'produces'
75
82
  | 'writes'
@@ -77,6 +84,14 @@ export type SubsystemEdgeMechanism =
77
84
  | 'watches'
78
85
  | 'registers-into';
79
86
 
87
+ /**
88
+ * Union used by derived graph edges / styling (topology relationType or
89
+ * walkthrough hop mechanism).
90
+ */
91
+ export type SubsystemEdgeMechanism =
92
+ | SubsystemRelationType
93
+ | SubsystemWalkthroughMechanism;
94
+
80
95
  export type SubsystemDeclarationProvenance = 'verified' | 'authored';
81
96
 
82
97
  export type SubsystemDeclTokenKind =
@@ -142,13 +157,6 @@ export interface SubsystemReferenceInfo {
142
157
  source_location?: string;
143
158
  }
144
159
 
145
- export interface SubsystemImportInfo {
146
- nodeId: string;
147
- name: string;
148
- relation?: string;
149
- source_location?: string;
150
- }
151
-
152
160
  export interface SubsystemClassDeclaration {
153
161
  kind: 'class';
154
162
  methods: SubsystemMethodInfo[];
@@ -175,18 +183,49 @@ export interface SubsystemMethodDeclaration {
175
183
  returnType?: string;
176
184
  }
177
185
 
186
+ /** One generic type parameter, e.g. `T` or `K extends keyof StudioMessages`. */
187
+ export interface SubsystemTypeParamInfo {
188
+ name: string;
189
+ /** Constraint written after `extends` (or language equivalent). */
190
+ constraint?: string;
191
+ }
192
+
193
+ /** A callable/function type: `(params) => returnType`. */
194
+ export interface SubsystemCallableTypeInfo {
195
+ parameters?: SubsystemParamInfo[];
196
+ returnType?: string;
197
+ }
198
+
199
+ /** One enum member, with its optional literal value. */
200
+ export interface SubsystemEnumMemberInfo {
201
+ name: string;
202
+ value?: string;
203
+ }
204
+
205
+ /**
206
+ * Type-family declaration (interface / type alias / enum). Structured buckets
207
+ * cover common shapes; `rhs` is the verbatim escape hatch when none fit.
208
+ */
178
209
  export interface SubsystemTypeDeclaration {
179
210
  kind: 'type';
180
211
  properties: SubsystemPropertyInfo[];
181
212
  usedBy: SubsystemReferenceInfo[];
182
213
  implementors: string[];
183
- }
184
-
185
- export interface SubsystemModuleDeclaration {
186
- kind: 'module';
187
- exports: string[];
188
- imports: SubsystemImportInfo[];
189
- symbols: string[];
214
+ /** Generic type parameters, e.g. `<K extends keyof StudioMessages>`. */
215
+ generics?: SubsystemTypeParamInfo[];
216
+ /** Callable type — `(params) => returnType`. */
217
+ signature?: SubsystemCallableTypeInfo;
218
+ /** Enum members (name, optional literal value). */
219
+ enumMembers?: SubsystemEnumMemberInfo[];
220
+ /** Alias whose RHS is a plain reference, e.g. `ServerSessionRow[]`. */
221
+ aliasOf?: string;
222
+ /** Simple union of alternatives, e.g. `'started' | 'stopped'`. */
223
+ unionOf?: string[];
224
+ /**
225
+ * Verbatim RHS — escape hatch for shapes the structured fields can't
226
+ * express. Wins over every shape above when set.
227
+ */
228
+ rhs?: string;
190
229
  }
191
230
 
192
231
  export interface SubsystemExternalDeclaration {
@@ -196,6 +235,11 @@ export interface SubsystemExternalDeclaration {
196
235
 
197
236
  export interface SubsystemStoreDeclaration {
198
237
  kind: 'store';
238
+ /** Where retained state lives / who mediates access. Authored, never
239
+ * extracted: `memory` (process-lifetime RAM), `disk` (this process
240
+ * reads/writes files), or `external` (another system — db/service; carries
241
+ * no `process`). */
242
+ storage?: 'memory' | 'disk' | 'external';
199
243
  properties: SubsystemPropertyInfo[];
200
244
  }
201
245
 
@@ -221,7 +265,6 @@ export type SubsystemConstructDeclaration =
221
265
  | SubsystemFunctionDeclaration
222
266
  | SubsystemMethodDeclaration
223
267
  | SubsystemTypeDeclaration
224
- | SubsystemModuleDeclaration
225
268
  | SubsystemExternalDeclaration
226
269
  | SubsystemStoreDeclaration
227
270
  | SubsystemCustomEntityDeclaration;
@@ -256,6 +299,15 @@ export interface SubsystemComponent {
256
299
  */
257
300
  stereotype?: SubsystemStereotype;
258
301
  process?: string;
302
+ /**
303
+ * Source-module membership — which file/module this export belongs to
304
+ * (e.g. `src/session/transcript.ts`). Nodes sharing a `module` are drawn
305
+ * inside one boundary frame. Prefer this over inventing a module construct:
306
+ * anchor each export as its real construct (`function` / `class` / …) and
307
+ * set `module` so the file reads as a frame, not a node. Orthogonal to
308
+ * `process` (runtime deployment unit).
309
+ */
310
+ module?: string;
259
311
  /** Code identity — real declaration in `file` when set. */
260
312
  symbol?: string;
261
313
  /**
@@ -277,20 +329,37 @@ export interface SubsystemComponent {
277
329
  declarationRef?: SubsystemDeclarationRef;
278
330
  }
279
331
 
280
- /** A cross-component edge. */
281
- export interface SubsystemComponentEdge {
332
+ /** A topology relation between components (structural / module / type). */
333
+ export interface SubsystemRelation {
282
334
  id: string;
283
335
  /** Source component id. */
284
336
  from: string;
285
337
  /** Target component id (or external label). */
286
338
  to: string;
287
- mechanism: SubsystemEdgeMechanism;
339
+ relationType: SubsystemRelationType;
288
340
  /** Concrete file/symbol evidence (often purls). */
289
341
  refs?: string[];
290
342
  }
291
343
 
292
- export interface SubsystemThroughlineStep {
293
- edgeId: string;
344
+ /**
345
+ * Derived / display graph edge used by renderers. Built from `relations`
346
+ * and/or walkthrough hops — not authored as its own document field.
347
+ */
348
+ export interface SubsystemComponentEdge {
349
+ id: string;
350
+ from: string;
351
+ to: string;
352
+ mechanism: SubsystemEdgeMechanism;
353
+ refs?: string[];
354
+ }
355
+
356
+ export interface SubsystemWalkthroughStep {
357
+ /** Source component id. */
358
+ from: string;
359
+ /** Target component id. */
360
+ to: string;
361
+ /** Runtime seam label (Set B). */
362
+ mechanism: SubsystemWalkthroughMechanism;
294
363
  file: string;
295
364
  /** 1-based line within `file`. */
296
365
  line: number;
@@ -304,11 +373,11 @@ export interface SubsystemThroughlineStep {
304
373
  annotation?: string;
305
374
  }
306
375
 
307
- /** Ordered execution story over existing edges (one per flow). */
308
- export interface SubsystemThroughline {
376
+ /** Ordered runtime walkthrough (one named behavior story). */
377
+ export interface SubsystemWalkthrough {
309
378
  id: string;
310
379
  title: string;
311
- steps: SubsystemThroughlineStep[];
380
+ steps: SubsystemWalkthroughStep[];
312
381
  }
313
382
 
314
383
  export interface SubsystemRepoRef {
@@ -331,8 +400,10 @@ export interface SubsystemModelDocument {
331
400
  title: string;
332
401
  description?: string;
333
402
  components: SubsystemComponent[];
334
- edges: SubsystemComponentEdge[];
335
- throughlines?: SubsystemThroughline[];
403
+ /** Topology relations (structural / module / type). May be empty. */
404
+ relations: SubsystemRelation[];
405
+ /** Runtime walkthroughs (ordered hops with sites). */
406
+ walkthroughs?: SubsystemWalkthrough[];
336
407
  }
337
408
 
338
409
  /**
@@ -383,12 +454,12 @@ export function isSubsystemModelDocument(value: unknown): value is SubsystemMode
383
454
  const v = value as {
384
455
  title?: unknown;
385
456
  components?: unknown;
386
- edges?: unknown;
457
+ relations?: unknown;
387
458
  };
388
459
  return (
389
460
  typeof v.title === 'string' &&
390
461
  Array.isArray(v.components) &&
391
- Array.isArray(v.edges)
462
+ Array.isArray(v.relations)
392
463
  );
393
464
  }
394
465
 
@@ -403,10 +474,56 @@ export function toPortableDocument(
403
474
  const out: SubsystemModelDocument = {
404
475
  title: doc.title,
405
476
  components: doc.components,
406
- edges: doc.edges,
477
+ relations: doc.relations,
407
478
  };
408
479
  if (doc.$schema) out.$schema = doc.$schema;
409
480
  if (doc.description) out.description = doc.description;
410
- if (doc.throughlines) out.throughlines = doc.throughlines;
481
+ if (doc.walkthroughs) out.walkthroughs = doc.walkthroughs;
411
482
  return out;
412
483
  }
484
+
485
+ /** Stable id for a derived graph edge from a relation or walkthrough hop. */
486
+ export function derivedGraphEdgeId(
487
+ from: string,
488
+ to: string,
489
+ mechanism: SubsystemEdgeMechanism,
490
+ ): string {
491
+ return `${from}--${mechanism}-->${to}`;
492
+ }
493
+
494
+ /**
495
+ * Build display edges for the graph canvas from topology relations and
496
+ * walkthrough hops (deduped by from/to/mechanism).
497
+ */
498
+ export function deriveGraphEdges(doc: {
499
+ relations?: SubsystemRelation[];
500
+ walkthroughs?: SubsystemWalkthrough[];
501
+ }): SubsystemComponentEdge[] {
502
+ const byId = new Map<string, SubsystemComponentEdge>();
503
+ for (const r of doc.relations ?? []) {
504
+ const id = r.id || derivedGraphEdgeId(r.from, r.to, r.relationType);
505
+ if (!byId.has(id)) {
506
+ byId.set(id, {
507
+ id,
508
+ from: r.from,
509
+ to: r.to,
510
+ mechanism: r.relationType,
511
+ refs: r.refs,
512
+ });
513
+ }
514
+ }
515
+ for (const w of doc.walkthroughs ?? []) {
516
+ for (const step of w.steps) {
517
+ const id = derivedGraphEdgeId(step.from, step.to, step.mechanism);
518
+ if (!byId.has(id)) {
519
+ byId.set(id, {
520
+ id,
521
+ from: step.from,
522
+ to: step.to,
523
+ mechanism: step.mechanism,
524
+ });
525
+ }
526
+ }
527
+ }
528
+ return [...byId.values()];
529
+ }