@principal-ai/subsystems-react 0.51.4 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/index.d.ts +4 -4
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/subsystem/C4Graph.d.ts +3 -7
  6. package/dist/subsystem/C4Graph.d.ts.map +1 -1
  7. package/dist/subsystem/C4Graph.js +193 -47
  8. package/dist/subsystem/C4Graph.js.map +1 -1
  9. package/dist/subsystem/C4NodeCard.d.ts +33 -27
  10. package/dist/subsystem/C4NodeCard.d.ts.map +1 -1
  11. package/dist/subsystem/C4NodeCard.js +89 -43
  12. package/dist/subsystem/C4NodeCard.js.map +1 -1
  13. package/dist/subsystem/IssueList.d.ts +1 -1
  14. package/dist/subsystem/IssueList.d.ts.map +1 -1
  15. package/dist/subsystem/IssueList.js +20 -1
  16. package/dist/subsystem/IssueList.js.map +1 -1
  17. package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
  18. package/dist/subsystem/SubsystemComponentGraph.js +42 -19
  19. package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
  20. package/dist/subsystem/c4.d.ts +48 -49
  21. package/dist/subsystem/c4.d.ts.map +1 -1
  22. package/dist/subsystem/c4.js +50 -0
  23. package/dist/subsystem/c4.js.map +1 -1
  24. package/dist/subsystem/c4Evidence.d.ts +88 -84
  25. package/dist/subsystem/c4Evidence.d.ts.map +1 -1
  26. package/dist/subsystem/c4Evidence.js +113 -166
  27. package/dist/subsystem/c4Evidence.js.map +1 -1
  28. package/dist/subsystem/model.d.ts +35 -245
  29. package/dist/subsystem/model.d.ts.map +1 -1
  30. package/dist/subsystem/model.js +11 -29
  31. package/dist/subsystem/model.js.map +1 -1
  32. package/dist/subsystem/nodes.js +5 -5
  33. package/dist/subsystem/nodes.js.map +1 -1
  34. package/dist/subsystem/techIcons/index.d.ts +5 -0
  35. package/dist/subsystem/techIcons/index.d.ts.map +1 -1
  36. package/dist/subsystem/techIcons/index.js +3 -0
  37. package/dist/subsystem/techIcons/index.js.map +1 -1
  38. package/dist/utils/edgeLabel.d.ts +15 -1
  39. package/dist/utils/edgeLabel.d.ts.map +1 -1
  40. package/dist/utils/edgeLabel.js +25 -1
  41. package/dist/utils/edgeLabel.js.map +1 -1
  42. package/dist/utils/elkLayout.d.ts +47 -0
  43. package/dist/utils/elkLayout.d.ts.map +1 -1
  44. package/dist/utils/elkLayout.js +71 -7
  45. package/dist/utils/elkLayout.js.map +1 -1
  46. package/package.json +3 -3
  47. package/src/index.ts +8 -6
  48. package/src/stories/Subsystem/C4Graph/C4Component.stories.tsx +198 -0
  49. package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +42 -6
  50. package/src/stories/Subsystem/C4Graph/C4NodeGallery.stories.tsx +9 -7
  51. package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +686 -2
  52. package/src/subsystem/C4Graph.tsx +278 -82
  53. package/src/subsystem/C4NodeCard.test.ts +32 -22
  54. package/src/subsystem/C4NodeCard.tsx +134 -69
  55. package/src/subsystem/IssueList.tsx +23 -0
  56. package/src/subsystem/SubsystemComponentGraph.tsx +38 -16
  57. package/src/subsystem/c4.protocolColor.test.ts +26 -0
  58. package/src/subsystem/c4.ts +76 -52
  59. package/src/subsystem/c4Evidence.test.ts +177 -237
  60. package/src/subsystem/c4Evidence.ts +160 -235
  61. package/src/subsystem/model.ts +62 -305
  62. package/src/subsystem/nodes.group.test.tsx +15 -0
  63. package/src/subsystem/nodes.tsx +7 -7
  64. package/src/subsystem/techIcons/index.tsx +8 -0
  65. package/src/utils/edgeLabel.test.ts +21 -2
  66. package/src/utils/edgeLabel.ts +29 -1
  67. package/src/utils/elkLayout.test.ts +16 -0
  68. package/src/utils/elkLayout.ts +119 -7
  69. package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +0 -602
@@ -12,6 +12,12 @@
12
12
  * supplies the drawable model directly rather than having trails converted into
13
13
  * lines.
14
14
  *
15
+ * The element set is an umbrella over a model, not a standalone artifact: what
16
+ * sits inside a box resolves from the model document's `process` fields, folded
17
+ * to the claiming container's key by accepted consolidation records (see
18
+ * `c4Evidence`). Nothing here stores membership, so nothing here can drift from
19
+ * the model it organizes.
20
+ *
15
21
  * ## Why a union and not one type with two axes
16
22
  *
17
23
  * C4's vocabulary is closed: software system, container, component, code —
@@ -31,7 +37,6 @@
31
37
  *
32
38
  * [C4 notation]: https://c4model.com/diagrams/notation
33
39
  */
34
- import type { SubsystemComponent } from './model';
35
40
  /**
36
41
  * Has anyone signed off on this element yet?
37
42
  *
@@ -50,27 +55,22 @@ interface C4ElementBase {
50
55
  /** Display name. */
51
56
  label: string;
52
57
  /**
53
- * The component aliases that live directly inside this element.
54
- *
55
- * Named explicitly rather than derived from a `process` value, because two
56
- * runs of code being one container is a judgement, not a lookup.
57
- *
58
- * Each alias belongs to exactly one element.
59
- */
60
- members: string[];
61
- /**
62
- * The `process` values this element consolidated, when it came from more than
63
- * one. Purely provenance — it lets the confirm UI show "this box absorbed
64
- * principal-studio/host". Never used to infer membership.
58
+ * Nesting parent. A component's container, or a container's system frame.
59
+ * Absent on an external system or a person — both are outside the boundary:
60
+ * an external is someone else's system, a person is never part of one.
65
61
  */
66
- derivedFrom?: string[];
62
+ parentId?: string;
67
63
  /** C4 asks every element to carry a one-line responsibility. */
68
64
  description?: string;
69
65
  state: C4ElementState;
70
66
  /** Why this element is proposed as it is — shown in the confirm UI. */
71
67
  rationale?: string;
72
- /** Who or what authored it. */
73
- author?: string;
68
+ /** The component aliases this element groups. */
69
+ members?: string[];
70
+ /** Distinct constructs among the members, when resolved from a document. */
71
+ constructs?: string[];
72
+ /** Source model ids that contributed members, when attribution is supplied. */
73
+ models?: string[];
74
74
  /** When the state last changed (ISO). */
75
75
  decidedAt?: string;
76
76
  }
@@ -91,6 +91,12 @@ export interface C4Container extends C4ElementBase {
91
91
  containerKind: C4ContainerKind;
92
92
  /** C4 requires a technology on every container. */
93
93
  technology: string;
94
+ /**
95
+ * The `process` key this container claims — the boundary it verifies,
96
+ * matched exactly against the model document's keys. Not a member list:
97
+ * the components inside resolve from the model document.
98
+ */
99
+ process?: string;
94
100
  }
95
101
  /**
96
102
  * A functional grouping inside a container — the C4 level 3 box.
@@ -120,7 +126,14 @@ export interface C4Person extends C4ElementBase {
120
126
  }
121
127
  /** One element. Four kinds, no fifth. */
122
128
  export type C4Element = C4Container | C4Component | C4ExternalSystem | C4Person;
123
- /** A whole authored element list, for one repo or composed graph. */
129
+ /**
130
+ * A whole authored element list, for one repo or composed graph. This is the
131
+ * shape the durable element store persists (`~/.principal/c4-elements/<purl>.json`):
132
+ * **accepted elements only** — the set is the approved architecture, not a
133
+ * history. `proposed` exists only on in-memory proposal scaffolds and is never
134
+ * persisted; a rejected proposal stays remembered by the proposal store, which
135
+ * is where proposing agents consult prior rejections.
136
+ */
124
137
  export interface C4ElementSet {
125
138
  /** Repo key this set describes, e.g. `pkg:github/owner/name`. */
126
139
  repoKey: string;
@@ -130,37 +143,6 @@ export interface C4ElementSet {
130
143
  }
131
144
  /** Which level to draw. Determines which frames are drawn. */
132
145
  export type C4View = 'container' | 'component';
133
- /**
134
- * A flattened element, as the renderer reads it.
135
- *
136
- * The union above is what an author writes; this is the one shape every box
137
- * draws with, so the card does not branch on kind to find a label.
138
- */
139
- export interface C4Node {
140
- id: string;
141
- kind: C4Element['kind'];
142
- /**
143
- * Nesting parent: a component's container, a container or external system's
144
- * frame, and nothing for a person — C4 puts people outside every system.
145
- */
146
- parentId?: string;
147
- label: string;
148
- technology?: string;
149
- description?: string;
150
- state: C4ElementState;
151
- /** `application` / `data-store`. Set on containers only. */
152
- containerKind?: C4ContainerKind;
153
- /** Provenance, when the element consolidated several derived keys. */
154
- derivedFrom?: string[];
155
- /** Resolved members, when a document was supplied. A container's list includes its components'. */
156
- members: string[];
157
- /** Distinct constructs among resolved members. */
158
- constructs: string[];
159
- /** Present at component level when the document resolved it. */
160
- component?: SubsystemComponent;
161
- /** Source model ids that contributed members, when attribution is supplied. */
162
- models?: string[];
163
- }
164
146
  /** A compound frame: the system, or a container holding its components. */
165
147
  export interface C4Group {
166
148
  id: string;
@@ -190,6 +172,23 @@ export interface C4Edge {
190
172
  /** How many underlying steps this line rolled up. */
191
173
  count: number;
192
174
  }
175
+ /**
176
+ * Protocol hues, keyed by a canonical protocol token.
177
+ *
178
+ * C4's notation is colour-free, so this is a local choice — but on a container
179
+ * diagram the protocol is what a reader wants to distinguish at a glance
180
+ * (in-process RPC vs HTTP vs file I/O), more than the trail verb the line came
181
+ * from. Keys are lowercase, matched loosely (see `protocolColor`).
182
+ */
183
+ export declare const PROTOCOL_COLOR: Record<string, string>;
184
+ /** Fallback hue for an edge whose protocol we have no colour for (or none). */
185
+ export declare const PROTOCOL_COLOR_FALLBACK = "#9ca3af";
186
+ /**
187
+ * Colour for an edge's protocol. Matches the longest known token contained in
188
+ * the (lowercased) protocol string, so `Electrobun RPC` finds `rpc` and
189
+ * `JSON-RPC` finds the `json-rpc` entry before `rpc`.
190
+ */
191
+ export declare function protocolColor(protocol: string | undefined): string;
193
192
  /** A drawable C4 projection. Authored, not derived. */
194
193
  export interface C4Model {
195
194
  view: C4View;
@@ -198,7 +197,7 @@ export interface C4Model {
198
197
  label: string;
199
198
  repoKey?: string;
200
199
  };
201
- nodes: C4Node[];
200
+ nodes: C4Element[];
202
201
  groups: C4Group[];
203
202
  edges: C4Edge[];
204
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"c4.d.ts","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"c4.d.ts","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;AAElE,uDAAuD;AACvD,UAAU,aAAa;IACrB;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,cAAc,CAAC;IACtB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iDAAiD;IACjD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,YAAY,CAAC;AAE3D,yDAAyD;AACzD,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,WAAW,CAAC;IAClB,sCAAsC;IACtC,aAAa,EAAE,eAAe,CAAC;IAC/B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,IAAI,EAAE,WAAW,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,6DAA6D;AAC7D,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,IAAI,EAAE,iBAAiB,CAAC;IACxB,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gEAAgE;AAChE,MAAM,WAAW,QAAS,SAAQ,aAAa;IAC7C,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,yCAAyC;AACzC,MAAM,MAAM,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAEhF;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED,8DAA8D;AAC9D,MAAM,MAAM,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;AAE/C,2EAA2E;AAC3E,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAiBjD,CAAC;AAEF,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,YAAY,CAAC;AAEjD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQlE;AAED,uDAAuD;AACvD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACxD,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIlD"}
@@ -12,6 +12,12 @@
12
12
  * supplies the drawable model directly rather than having trails converted into
13
13
  * lines.
14
14
  *
15
+ * The element set is an umbrella over a model, not a standalone artifact: what
16
+ * sits inside a box resolves from the model document's `process` fields, folded
17
+ * to the claiming container's key by accepted consolidation records (see
18
+ * `c4Evidence`). Nothing here stores membership, so nothing here can drift from
19
+ * the model it organizes.
20
+ *
15
21
  * ## Why a union and not one type with two axes
16
22
  *
17
23
  * C4's vocabulary is closed: software system, container, component, code —
@@ -31,6 +37,50 @@
31
37
  *
32
38
  * [C4 notation]: https://c4model.com/diagrams/notation
33
39
  */
40
+ /**
41
+ * Protocol hues, keyed by a canonical protocol token.
42
+ *
43
+ * C4's notation is colour-free, so this is a local choice — but on a container
44
+ * diagram the protocol is what a reader wants to distinguish at a glance
45
+ * (in-process RPC vs HTTP vs file I/O), more than the trail verb the line came
46
+ * from. Keys are lowercase, matched loosely (see `protocolColor`).
47
+ */
48
+ export const PROTOCOL_COLOR = {
49
+ rpc: '#22c55e',
50
+ http: '#e8853a',
51
+ https: '#e8853a',
52
+ rest: '#e8853a',
53
+ graphql: '#e061a3',
54
+ fs: '#0ea5e9',
55
+ 'file i/o': '#0ea5e9',
56
+ sql: '#a78bfa',
57
+ sqlite: '#a78bfa',
58
+ postgres: '#a78bfa',
59
+ 'json-rpc': '#22c55e',
60
+ ws: '#e3b341',
61
+ websocket: '#e3b341',
62
+ mcp: '#4ec9b0',
63
+ stdin: '#9ca3af',
64
+ stdout: '#9ca3af',
65
+ };
66
+ /** Fallback hue for an edge whose protocol we have no colour for (or none). */
67
+ export const PROTOCOL_COLOR_FALLBACK = '#9ca3af';
68
+ /**
69
+ * Colour for an edge's protocol. Matches the longest known token contained in
70
+ * the (lowercased) protocol string, so `Electrobun RPC` finds `rpc` and
71
+ * `JSON-RPC` finds the `json-rpc` entry before `rpc`.
72
+ */
73
+ export function protocolColor(protocol) {
74
+ if (!protocol)
75
+ return PROTOCOL_COLOR_FALLBACK;
76
+ const p = protocol.toLowerCase();
77
+ let best = '';
78
+ for (const key of Object.keys(PROTOCOL_COLOR)) {
79
+ if (key.length > best.length && p.includes(key))
80
+ best = key;
81
+ }
82
+ return best ? PROTOCOL_COLOR[best] : PROTOCOL_COLOR_FALLBACK;
83
+ }
34
84
  /**
35
85
  * `owner/name` from a purl, trimmed of scheme and fragment. Used to label the
36
86
  * system frame when a repo key is known.
@@ -1 +1 @@
1
- {"version":3,"file":"c4.js","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAwLH;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC;AACnD,CAAC"}
1
+ {"version":3,"file":"c4.js","sourceRoot":"","sources":["../../src/subsystem/c4.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAoJH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAA2B;IACpD,GAAG,EAAE,SAAS;IACd,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,SAAS;IAClB,EAAE,EAAE,SAAS;IACb,UAAU,EAAE,SAAS;IACrB,GAAG,EAAE,SAAS;IACd,MAAM,EAAE,SAAS;IACjB,QAAQ,EAAE,SAAS;IACnB,UAAU,EAAE,SAAS;IACrB,EAAE,EAAE,SAAS;IACb,SAAS,EAAE,SAAS;IACpB,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,SAAS;CAClB,CAAC;AAEF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG,SAAS,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,QAA4B;IACxD,IAAI,CAAC,QAAQ;QAAE,OAAO,uBAAuB,CAAC;IAC9C,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;QAC7C,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,IAAI,GAAG,GAAG,CAAC;KAC7D;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC;AAChE,CAAC;AAWD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC9C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC;AACnD,CAAC"}
@@ -1,53 +1,27 @@
1
1
  /**
2
- * C4 evidence — what an agent needs in order to propose elements.
2
+ * C4 evidence — the pure read-side of proposing and verifying C4 containers.
3
3
  *
4
- * This module does not decide anything. It answers "what is worth asking
5
- * about?" so an agent can go and read the source, then propose a
6
- * `C4Element` with a rationale. The questions come from the C4 notation
7
- * rules the document cannot satisfy on its own:
4
+ * This module does not decide anything. The proposing agent reads the
5
+ * subsystem diagrams, queries the existing containers, reasons, and writes
6
+ * its own rationale; what lives here is only the mechanical part of that
7
+ * loop:
8
8
  *
9
- * - every container needs a technology
10
- * - every element needs a description
11
- * - a container is a runtime boundary, so a library is not one
12
- * - a container cannot straddle two software systems
9
+ * - `proposeElements` — the proposal scaffold: skip keys containers
10
+ * already claim, skip boundaries no container can be discerned from
11
+ * (no runtime code behind them)
12
+ * - `verifyProcessBoundaries` — a boundary's verification status, read
13
+ * off the claiming container
14
+ * - `verificationIssues` — those statuses as dynamic-topology findings,
15
+ * so verification surfaces through the standard diagnostics pipeline
16
+ * - `findUnassigned` — runtime components no `process` names at all
13
17
  *
14
- * The output is a set of concerns. Resolving one is the agent's job, and the
15
- * answer lands in an element's `rationale`.
18
+ * Judgements — is this the same unit under a different name? is one function
19
+ * a deployable unit? — belong to the agent and the human, never to a
20
+ * matcher.
16
21
  */
17
22
  import type { C4ContainerKind, C4Element, C4ElementSet } from './c4';
18
- /** What a concern is about — a derived key, or an existing element id. */
19
- export interface C4Concern {
20
- /** The process key, module path, or element id this concerns. */
21
- target: string;
22
- kind: C4ConcernKind;
23
- message: string;
24
- /** Aliases that triggered it. */
25
- members?: string[];
26
- }
27
- /**
28
- * The questions worth a human's attention.
29
- *
30
- * Each maps to something an agent cannot settle by reading a string — it has
31
- * to open the source, or ask the user.
32
- */
33
- export type C4ConcernKind =
34
- /** two or more process keys may be the same deployable unit */
35
- 'merge_candidate'
36
- /** exactly one member — a lone function is not a deployable unit */
37
- | 'singleton'
38
- /** no member executes at runtime — a library is not a container */
39
- | 'library_shaped'
40
- /** a store whose storage kind was never decided */
41
- | 'store_unclassified'
42
- /** members claim more than one repo — a container cannot straddle systems */
43
- | 'spans_repos'
44
- /** an external with no resolvable identity */
45
- | 'external_unidentified'
46
- /** a runtime component with no process at all */
47
- | 'unassigned'
48
- /** C4 requires technology on every container */
49
- | 'missing_technology';
50
- /** The fields a concern check reads off a component. */
23
+ import type { SubsystemIssue } from './IssueList';
24
+ /** The fields the propose/verify gates read off a component. */
51
25
  export interface C4MemberView {
52
26
  alias: string;
53
27
  construct: string;
@@ -60,31 +34,6 @@ export interface C4MemberView {
60
34
  }
61
35
  /** True when a component runs, and so can be part of a deployable unit. */
62
36
  export declare function isRuntimeConstruct(construct: string): boolean;
63
- /**
64
- * Derive the questions worth asking about one candidate element.
65
- *
66
- * Pure over the rollup, so it runs identically against a single model, the 40
67
- * composed models, or a fixture. Pure *questions* — it never proposes an
68
- * answer, because the answers are architectural.
69
- */
70
- export declare function deriveConcerns(key: string, members: readonly C4MemberView[], tech?: {
71
- frameworks: readonly string[];
72
- }): C4Concern[];
73
- /**
74
- * Suggest merges between keys that share a trailing role.
75
- *
76
- * `subsystems-studio/host` and `principal-studio/host` are the same role under
77
- * two app names. This is a *question*, never a merge — only the user knows
78
- * whether they are one process or two.
79
- */
80
- export declare function suggestMerges(rollup: ReadonlyArray<{
81
- key: string;
82
- memberCount: number;
83
- }>): Array<{
84
- role: string;
85
- keys: string[];
86
- reason: string;
87
- }>;
88
37
  /**
89
38
  * Runtime components that state no `process` at all.
90
39
  *
@@ -94,26 +43,80 @@ export declare function suggestMerges(rollup: ReadonlyArray<{
94
43
  */
95
44
  export declare function findUnassigned(members: readonly C4MemberView[]): C4MemberView[];
96
45
  /**
97
- * Fold a decided merge into an element set.
46
+ * How far a process boundary has travelled toward being a container.
98
47
  *
99
- * Two process keys that are really one container become ONE element holding
100
- * both sets of members. The survivor keeps the id, label, and confirmed
101
- * attributes; the other disappears and its members move across.
48
+ * A boundary starts `unassigned` — no container claims it. Proposing an
49
+ * element for it (see `proposeElements`) assigns the boundary to a container,
50
+ * which reads as `proposed` until a human decides. `accepted` verifies the
51
+ * boundary: someone approved this run of code as one deployable unit.
52
+ * `rejected` means the proposal was wrong and the boundary should not be
53
+ * drawn as a box.
54
+ */
55
+ export type C4ProcessVerification = 'unassigned' | 'proposed' | 'rejected' | 'verified';
56
+ /** One process boundary's assignment and its review state. */
57
+ export interface C4ProcessBoundaryStatus {
58
+ /** The `process` key, e.g. `principal-studio/host`. */
59
+ key: string;
60
+ /** Aliases carrying this key in the model, when the caller supplied them. */
61
+ memberAliases: string[];
62
+ status: C4ProcessVerification;
63
+ /** The container whose state decided the status. Absent when `unassigned`. */
64
+ element?: C4Element;
65
+ }
66
+ /**
67
+ * Read a process boundary's verification off its container assignment.
102
68
  *
103
- * Which side survives is the **evidence-heavy** one — the element holding more
104
- * members — because folding the 113-member host into the 1-member one would
105
- * leave the box labelled after an almost-empty process and lose its confirmed
106
- * technology. Pass `preferId` to override.
69
+ * The claimant is the container whose `process` equals the boundary's key —
70
+ * a plain string match, no indirection. Two keys that are one deployable unit
71
+ * under two names are fixed in the model document (a consolidation proposal
72
+ * rewrites the components' `process` fields), so the reader never sees a
73
+ * discrepancy to resolve. When several containers claim one key (a
74
+ * hand-edited set can do this), the decided one wins: accepted over rejected
75
+ * over proposed, so one reviewer's yes outranks another's no.
107
76
  *
108
- * Returns a new set; the input is untouched. Idempotent.
77
+ * Pure: the same rollup and elements always read the same. `rollup` accepts
78
+ * `SubsystemProcessRegion`s directly — only `key` and `memberAliases` are read.
109
79
  */
110
- export declare function mergeElements(elements: readonly C4Element[], derivedFromKeys: readonly string[], preferId?: string, memberCountByKey?: ReadonlyMap<string, number>): C4Element[];
80
+ export declare function verifyProcessBoundaries(options: {
81
+ rollup: ReadonlyArray<{
82
+ key: string;
83
+ memberAliases?: readonly string[];
84
+ }>;
85
+ elements: readonly C4Element[];
86
+ }): C4ProcessBoundaryStatus[];
111
87
  /**
112
- * A starting point for an agent: one proposed element per derived key, shaped
113
- * by the mechanical evidence, with the open questions in the rationale.
88
+ * Verification statuses as diagnostics findings — the dynamic-topology layer
89
+ * of the issues list. One finding per boundary that is NOT verified: an
90
+ * unclaimed boundary is the absence a proposing agent run resolves, a
91
+ * `proposed` one awaits the human's decision, a `rejected` one records that
92
+ * the decision was no. `verified` reports nothing — the audit reports
93
+ * absence only, and silence is the good state.
94
+ *
95
+ * The findings ride the existing pipeline untouched: they badge the process
96
+ * frame (target kind `process`), list under Dynamic topology, focus their
97
+ * members on click, and carry the fix the decision needs. Pure over its
98
+ * input, like the rest of this module.
99
+ */
100
+ export declare function verificationIssues(statuses: readonly C4ProcessBoundaryStatus[]): SubsystemIssue[];
101
+ /**
102
+ * A starting point for an agent, shaped by the two questions that matter when
103
+ * assessing a process boundary:
104
+ *
105
+ * 1. **Does a container already exist for it?** (`elements`) — a key one
106
+ * already claims is never re-proposed; proposing another would be
107
+ * exactly the duplicate this module exists to prevent. The exact claim
108
+ * is a fact and skipped here; whether a *similarly named* container is
109
+ * the same unit is a judgement, so it belongs to the agent querying the
110
+ * container list — the fix there is a consolidation proposal, not a
111
+ * second box.
112
+ * 2. **Can the boundary be discerned into a container?** — code that never
113
+ * runs cannot be, so a library-shaped group gets no proposal; that
114
+ * fact is the agent's to report, not the scaffold's.
114
115
  *
115
- * Every element comes back `proposed`. This is a scaffold to edit and argue
116
- * with — not an answer, and never `accepted`.
116
+ * For boundaries passing both, one `proposed` container per key. The
117
+ * rationale is the proposing agent's own reasoning, written on the proposal
118
+ * it POSTs — this scaffold does not fabricate one. A scaffold to edit and
119
+ * argue with — not an answer, and never `accepted`.
117
120
  */
118
121
  export declare function proposeElements(options: {
119
122
  repoKey: string;
@@ -122,7 +125,8 @@ export declare function proposeElements(options: {
122
125
  members: readonly C4MemberView[];
123
126
  frameworks: readonly string[];
124
127
  }>;
125
- author?: string;
128
+ /** Containers that already exist (from the element store), by `process` claim. */
129
+ elements?: readonly C4Element[];
126
130
  }): C4ElementSet;
127
131
  /**
128
132
  * A first guess at what sort of container this is, offered as a *default* for
@@ -1 +1 @@
1
- {"version":3,"file":"c4Evidence.d.ts","sourceRoot":"","sources":["../../src/subsystem/c4Evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAe,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAElF,0EAA0E;AAC1E,MAAM,WAAW,SAAS;IACxB,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa;AACvB,+DAA+D;AAC7D,iBAAiB;AACnB,oEAAoE;GAClE,WAAW;AACb,mEAAmE;GACjE,gBAAgB;AAClB,mDAAmD;GACjD,oBAAoB;AACtB,6EAA6E;GAC3E,aAAa;AACf,8CAA8C;GAC5C,uBAAuB;AACzB,iDAAiD;GAC/C,YAAY;AACd,gDAAgD;GAC9C,oBAAoB,CAAC;AAEzB,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAUD,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,IAAI,GAAE;IAAE,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;CAAuB,GAC3D,SAAS,EAAE,CAwEb;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,aAAa,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1D,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBzD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE,CAE/E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,SAAS,SAAS,EAAE,EAC9B,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,QAAQ,CAAC,EAAE,MAAM,EACjB,gBAAgB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7C,SAAS,EAAE,CAwCb;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE;IACP,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;QAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACxG,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,YAAY,CAyBd;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,eAAe,CAOtF"}
1
+ {"version":3,"file":"c4Evidence.d.ts","sourceRoot":"","sources":["../../src/subsystem/c4Evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAe,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAClF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAUD,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,YAAY,EAAE,CAE/E;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,UAAU,GACV,UAAU,GACV,UAAU,CAAC;AAEf,8DAA8D;AAC9D,MAAM,WAAW,uBAAuB;IACtC,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,MAAM,EAAE,aAAa,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,EAAE,SAAS,SAAS,EAAE,CAAC;CAChC,GAAG,uBAAuB,EAAE,CAsB5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAC3C,cAAc,EAAE,CAyBlB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,SAAS,YAAY,EAAE,CAAC;QACjC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;KAC/B,CAAC,CAAC;IACH,kFAAkF;IAClF,QAAQ,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;CACjC,GAAG,YAAY,CA6Bf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,eAAe,CAOtF"}