sysprom 1.19.0 → 1.21.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 (75) hide show
  1. package/README.md +3 -0
  2. package/dist/schema.json +4 -43
  3. package/dist/src/cli/commands/add.js +6 -2
  4. package/dist/src/cli/commands/query.js +5 -3
  5. package/dist/src/cli/commands/speckit.js +2 -2
  6. package/dist/src/cli/commands/update.js +6 -4
  7. package/dist/src/endpoint-types.d.ts +4 -0
  8. package/dist/src/endpoint-types.js +22 -116
  9. package/dist/src/json-to-md.js +2 -16
  10. package/dist/src/lifecycle-state.d.ts +9 -0
  11. package/dist/src/lifecycle-state.js +22 -0
  12. package/dist/src/mcp/server.js +3 -6
  13. package/dist/src/md-to-json.js +1 -19
  14. package/dist/src/operations/add-node.d.ts +21 -132
  15. package/dist/src/operations/add-plan-task.d.ts +14 -88
  16. package/dist/src/operations/add-relationship.d.ts +16 -102
  17. package/dist/src/operations/check.d.ts +7 -44
  18. package/dist/src/operations/graph-decision.d.ts +7 -44
  19. package/dist/src/operations/graph-decision.js +0 -1
  20. package/dist/src/operations/graph-dependency.d.ts +7 -44
  21. package/dist/src/operations/graph-dependency.js +3 -23
  22. package/dist/src/operations/graph-refinement.d.ts +7 -44
  23. package/dist/src/operations/graph-shared.js +1 -3
  24. package/dist/src/operations/graph.d.ts +7 -44
  25. package/dist/src/operations/infer-completeness.d.ts +10 -53
  26. package/dist/src/operations/infer-derived.d.ts +7 -44
  27. package/dist/src/operations/infer-derived.js +28 -4
  28. package/dist/src/operations/infer-impact.d.ts +49 -308
  29. package/dist/src/operations/infer-impact.js +22 -3
  30. package/dist/src/operations/infer-lifecycle.d.ts +8 -105
  31. package/dist/src/operations/infer-lifecycle.js +4 -10
  32. package/dist/src/operations/init-document.d.ts +7 -44
  33. package/dist/src/operations/json-to-markdown.d.ts +7 -44
  34. package/dist/src/operations/mark-task-done.d.ts +14 -88
  35. package/dist/src/operations/mark-task-undone.d.ts +14 -88
  36. package/dist/src/operations/markdown-to-json.d.ts +7 -44
  37. package/dist/src/operations/next-id.d.ts +8 -47
  38. package/dist/src/operations/node-history.d.ts +7 -44
  39. package/dist/src/operations/plan-add-task.d.ts +14 -88
  40. package/dist/src/operations/plan-gate.d.ts +7 -44
  41. package/dist/src/operations/plan-init.d.ts +7 -44
  42. package/dist/src/operations/plan-progress.d.ts +7 -44
  43. package/dist/src/operations/plan-status.d.ts +7 -44
  44. package/dist/src/operations/query-node.d.ts +29 -188
  45. package/dist/src/operations/query-nodes.d.ts +15 -89
  46. package/dist/src/operations/query-nodes.js +6 -4
  47. package/dist/src/operations/query-relationships.d.ts +9 -58
  48. package/dist/src/operations/remove-node.d.ts +21 -132
  49. package/dist/src/operations/remove-node.js +11 -1
  50. package/dist/src/operations/remove-relationship.d.ts +15 -101
  51. package/dist/src/operations/rename.d.ts +14 -88
  52. package/dist/src/operations/search.d.ts +14 -88
  53. package/dist/src/operations/speckit-diff.d.ts +7 -44
  54. package/dist/src/operations/speckit-export.d.ts +7 -44
  55. package/dist/src/operations/speckit-import.d.ts +7 -44
  56. package/dist/src/operations/speckit-sync.d.ts +22 -133
  57. package/dist/src/operations/speckit-sync.js +3 -3
  58. package/dist/src/operations/state-at.d.ts +7 -44
  59. package/dist/src/operations/stats.d.ts +7 -44
  60. package/dist/src/operations/sync.d.ts +21 -132
  61. package/dist/src/operations/task-list.d.ts +7 -44
  62. package/dist/src/operations/timeline.d.ts +7 -44
  63. package/dist/src/operations/trace-from-node.d.ts +21 -132
  64. package/dist/src/operations/update-metadata.d.ts +14 -88
  65. package/dist/src/operations/update-node.d.ts +20 -152
  66. package/dist/src/operations/update-plan-task.d.ts +14 -88
  67. package/dist/src/operations/validate.d.ts +7 -44
  68. package/dist/src/operations/validate.js +8 -6
  69. package/dist/src/schema.d.ts +22 -159
  70. package/dist/src/schema.js +4 -26
  71. package/dist/src/speckit/generate.js +10 -7
  72. package/dist/src/speckit/parse.js +6 -3
  73. package/dist/src/speckit/plan.js +1 -1
  74. package/package.json +12 -1
  75. package/schema.json +4 -43
package/README.md CHANGED
@@ -273,6 +273,9 @@ Recommended relationship usage:
273
273
 
274
274
  - `refines`: tighten intent into concepts and concepts into capabilities
275
275
  - `part_of`: decompose concepts, protocols, capabilities, and architecture structures
276
+ - `orchestrates`: connect abstract workflow machines to executable milestones, stages, gates, or artefact flows
277
+ - `precedes`: order milestones, stages, and gates within an executable flow
278
+ - `routes_to`: model artefact or data movement between artefact flows, stages, and artefacts
276
279
  - `realises`: connect design structures to implementation structures
277
280
  - `produces`: connect capabilities or stages to the artefacts they generate
278
281
  - `performs`: connect roles to capabilities, stages, protocols, and operational concepts
package/dist/schema.json CHANGED
@@ -210,10 +210,6 @@
210
210
  },
211
211
  "type": "array"
212
212
  },
213
- "input": {
214
- "description": "ID of the input artefact. Applicable to artefact_flow nodes.",
215
- "type": "string"
216
- },
217
213
  "lifecycle": {
218
214
  "additionalProperties": {
219
215
  "anyOf": [
@@ -306,10 +302,6 @@
306
302
  },
307
303
  "type": "array"
308
304
  },
309
- "output": {
310
- "description": "ID of the output artefact. Applicable to artefact_flow nodes.",
311
- "type": "string"
312
- },
313
305
  "plan": {
314
306
  "description": "Execution plan as a sequence of tasks. Applicable to change nodes.",
315
307
  "items": {
@@ -377,25 +369,8 @@
377
369
  "type": "string"
378
370
  },
379
371
  "status": {
380
- "enum": [
381
- "proposed",
382
- "accepted",
383
- "active",
384
- "implemented",
385
- "adopted",
386
- "defined",
387
- "introduced",
388
- "in_progress",
389
- "complete",
390
- "consolidated",
391
- "experimental",
392
- "deprecated",
393
- "retired",
394
- "superseded",
395
- "abandoned",
396
- "deferred"
397
- ],
398
- "type": "string"
372
+ "description": "Deprecated field. Node-level status is not supported; use lifecycle states instead.",
373
+ "not": {}
399
374
  },
400
375
  "subsystem": {
401
376
  "$ref": "#"
@@ -416,12 +391,10 @@
416
391
  "gate",
417
392
  "mode",
418
393
  "artefact",
419
- "artefact_flow",
420
394
  "decision",
421
395
  "change",
422
396
  "view",
423
- "milestone",
424
- "version"
397
+ "milestone"
425
398
  ],
426
399
  "type": "string"
427
400
  }
@@ -488,24 +461,12 @@
488
461
  "affects",
489
462
  "supersedes",
490
463
  "must_preserve",
491
- "performs",
492
464
  "part_of",
493
465
  "precedes",
494
466
  "must_follow",
495
- "blocks",
496
- "routes_to",
497
467
  "governed_by",
498
468
  "modifies",
499
- "triggered_by",
500
- "applies_to",
501
- "produces",
502
- "consumes",
503
- "transforms_into",
504
- "selects",
505
- "requires",
506
- "disables",
507
- "influence",
508
- "justifies"
469
+ "produces"
509
470
  ],
510
471
  "type": "string"
511
472
  }
@@ -50,8 +50,12 @@ const optsSchema = mutationOpts.extend({
50
50
  function populateNodeFromOpts(node, description, status, context, rationale, scope, selected, options) {
51
51
  if (description)
52
52
  node.description = description;
53
- if (status)
54
- node.status = status;
53
+ if (status) {
54
+ node.lifecycle = {
55
+ ...(node.lifecycle ?? {}),
56
+ [status]: true,
57
+ };
58
+ }
55
59
  if (context)
56
60
  node.context = context;
57
61
  if (rationale)
@@ -4,6 +4,7 @@ import { textToString } from "../../text.js";
4
4
  import { readOpts, loadDoc } from "../shared.js";
5
5
  import { queryNodesOp, queryNodeOp, queryRelationshipsOp, traceFromNodeOp, timelineOp, nodeHistoryOp, stateAtOp, } from "../../operations/index.js";
6
6
  import { NodeType, NodeStatus } from "../../schema.js";
7
+ import { primaryLifecycleState } from "../../lifecycle-state.js";
7
8
  // ---------------------------------------------------------------------------
8
9
  // Presentation helpers
9
10
  // ---------------------------------------------------------------------------
@@ -16,8 +17,9 @@ function printNodeCompact(r) {
16
17
  function printNodeVerbose(r) {
17
18
  console.log(`${pc.cyan(r.id)} — ${pc.bold(r.name)}`);
18
19
  console.log(` ${pc.dim("Type")}: ${r.type}`);
19
- if (r.status)
20
- console.log(` ${pc.dim("Status")}: ${pc.yellow(r.status)}`);
20
+ const state = primaryLifecycleState(r);
21
+ if (state)
22
+ console.log(` ${pc.dim("State")}: ${pc.yellow(state)}`);
21
23
  if (r.description)
22
24
  console.log(` ${pc.dim("Description")}: ${textToString(r.description)}`);
23
25
  if (r.context)
@@ -65,7 +67,7 @@ function printTraceTree(tn, depth) {
65
67
  // ---------------------------------------------------------------------------
66
68
  const nodesOpts = readOpts.extend({
67
69
  type: NodeType.optional().describe("filter by node type"),
68
- status: NodeStatus.optional().describe("filter by node status"),
70
+ status: NodeStatus.optional().describe("filter by lifecycle state"),
69
71
  });
70
72
  const nodeArgs = z.object({
71
73
  id: z.string().describe("node ID to retrieve"),
@@ -218,7 +218,7 @@ const syncSubcommand = {
218
218
  const specKitDoc = parseSpecKitFeature(specKitDir, idPrefix, constitutionPath);
219
219
  // Compare documents
220
220
  const diff = compareDocuments(syspromDoc, specKitDoc);
221
- // Merge: Spec-Kit wins for content (description, status), SysProM wins for structure
221
+ // Merge: Spec-Kit wins for content (description, lifecycle), SysProM wins for structure
222
222
  const mergedNodes = new Map(syspromDoc.nodes.map((n) => [n.id, n]));
223
223
  const specKitNodes = new Map(specKitDoc.nodes.map((n) => [n.id, n]));
224
224
  for (const [id, specKitNode] of specKitNodes) {
@@ -232,7 +232,7 @@ const syncSubcommand = {
232
232
  const merged = {
233
233
  ...syspromNode,
234
234
  description: specKitNode.description ?? syspromNode.description,
235
- status: specKitNode.status ?? syspromNode.status,
235
+ lifecycle: specKitNode.lifecycle ?? syspromNode.lifecycle,
236
236
  context: specKitNode.context ?? syspromNode.context,
237
237
  options: specKitNode.options ?? syspromNode.options,
238
238
  selected: specKitNode.selected ?? syspromNode.selected,
@@ -52,7 +52,7 @@ const updateNodeArgs = z.object({
52
52
  });
53
53
  const updateNodeOpts = mutationOpts.extend({
54
54
  description: z.string().optional().describe("update node description"),
55
- status: NodeStatus.optional().describe("update node status"),
55
+ status: NodeStatus.optional().describe("set lifecycle state to true"),
56
56
  context: z.string().optional().describe("update node context"),
57
57
  rationale: z.string().optional().describe("update node rationale"),
58
58
  lifecycle: z
@@ -97,13 +97,15 @@ const nodeSubcommand = {
97
97
  const fields = {};
98
98
  if (opts.description !== undefined)
99
99
  fields.description = opts.description;
100
- if (opts.status !== undefined)
101
- fields.status = opts.status;
102
100
  if (opts.context !== undefined)
103
101
  fields.context = opts.context;
104
102
  if (opts.rationale !== undefined)
105
103
  fields.rationale = opts.rationale;
106
- const lifecycleFields = parseLifecycleFields(node.lifecycle, opts.lifecycle ?? []);
104
+ const lifecycleArgs = [...(opts.lifecycle ?? [])];
105
+ if (opts.status !== undefined) {
106
+ lifecycleArgs.push(`${opts.status}=true`);
107
+ }
108
+ const lifecycleFields = parseLifecycleFields(node.lifecycle, lifecycleArgs);
107
109
  if (lifecycleFields) {
108
110
  fields.lifecycle = lifecycleFields;
109
111
  }
@@ -22,3 +22,7 @@ export declare const RELATIONSHIP_ENDPOINT_TYPES: Record<RelationshipType, {
22
22
  * ```
23
23
  */
24
24
  export declare function isValidEndpointPair(relType: RelationshipType, fromType: NodeType, toType: NodeType): boolean;
25
+ /**
26
+ * True when a relationship is a read-model view dependency.
27
+ */
28
+ export declare function isViewReadModelDependsOnRelationship(relType: RelationshipType, fromType: NodeType, toType: NodeType): boolean;
@@ -54,9 +54,9 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
54
54
  "gate",
55
55
  "mode",
56
56
  "artefact",
57
- "artefact_flow",
58
57
  "decision",
59
58
  "change",
59
+ "view",
60
60
  ],
61
61
  to: [
62
62
  "intent",
@@ -73,7 +73,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
73
73
  "gate",
74
74
  "mode",
75
75
  "artefact",
76
- "artefact_flow",
77
76
  "decision",
78
77
  "change",
79
78
  ],
@@ -92,26 +91,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
92
91
  ],
93
92
  to: ["invariant", "principle", "policy", "protocol", "concept"],
94
93
  },
95
- // Requires — explicit requirements
96
- requires: {
97
- from: [
98
- "intent",
99
- "concept",
100
- "capability",
101
- "element",
102
- "realisation",
103
- "stage",
104
- "change",
105
- ],
106
- to: [
107
- "intent",
108
- "concept",
109
- "capability",
110
- "element",
111
- "realisation",
112
- "artefact",
113
- ],
114
- },
115
94
  // Affects — broad impact relationships
116
95
  affects: {
117
96
  from: ["decision", "change", "artefact", "stage"],
@@ -145,7 +124,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
145
124
  "realisation",
146
125
  "decision",
147
126
  "change",
148
- "version",
149
127
  ],
150
128
  to: [
151
129
  "intent",
@@ -155,19 +133,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
155
133
  "realisation",
156
134
  "decision",
157
135
  "change",
158
- "version",
159
- ],
160
- },
161
- // Performs — process enactment
162
- performs: {
163
- from: ["stage", "role"],
164
- to: [
165
- "capability",
166
- "artefact",
167
- "artefact_flow",
168
- "stage",
169
- "concept",
170
- "protocol",
171
136
  ],
172
137
  },
173
138
  // Precedes — temporal ordering
@@ -213,16 +178,6 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
213
178
  "mode",
214
179
  ],
215
180
  },
216
- // Blocks — impediments and constraints
217
- blocks: {
218
- from: ["invariant", "policy", "decision", "principle"],
219
- to: ["decision", "change", "stage"],
220
- },
221
- // Routes to — data/process flow
222
- routes_to: {
223
- from: ["artefact_flow"],
224
- to: ["artefact_flow", "stage", "artefact"],
225
- },
226
181
  // Governed by — governance relationships
227
182
  governed_by: {
228
183
  from: [
@@ -241,7 +196,7 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
241
196
  },
242
197
  // Modifies — mutation and change
243
198
  modifies: {
244
- from: ["change", "artefact_flow", "stage"],
199
+ from: ["change", "stage"],
245
200
  to: [
246
201
  "intent",
247
202
  "concept",
@@ -251,80 +206,20 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
251
206
  "artefact",
252
207
  ],
253
208
  },
254
- // Transforms into — metamorphosis
255
- transforms_into: {
256
- from: ["artefact"],
257
- to: ["artefact"],
258
- },
259
- // Triggered by — causation
260
- triggered_by: {
261
- from: ["stage", "gate", "artefact_flow", "change"],
262
- to: ["decision", "artefact", "gate", "stage"],
263
- },
264
- // Disables — negation/reversal
265
- disables: {
266
- from: ["decision", "change"],
267
- to: ["capability", "realisation"],
268
- },
269
- // Applies to — applicability and scope
270
- applies_to: {
271
- from: ["policy", "principle", "mode", "protocol", "invariant"],
272
- to: [
273
- "intent",
274
- "concept",
275
- "capability",
276
- "element",
277
- "realisation",
278
- "stage",
279
- "decision",
280
- "change",
281
- "invariant",
282
- ],
283
- },
284
209
  // Produces — generation
285
210
  produces: {
286
- from: ["stage", "artefact_flow", "realisation", "concept", "capability"],
211
+ from: ["stage", "realisation", "concept", "capability"],
287
212
  to: ["artefact", "concept"],
288
213
  },
289
- // Consumes — usage
290
- consumes: {
291
- from: ["stage", "artefact_flow", "realisation", "role"],
292
- to: ["artefact"],
293
- },
294
- // Selects — choice and instantiation
295
- selects: {
296
- from: ["decision", "mode"],
297
- to: ["capability", "stage"],
298
- },
299
- // Influence — soft dependency between decisions and across nodes (CHG40)
300
- influence: {
301
- from: [
302
- "intent",
303
- "concept",
304
- "capability",
305
- "element",
306
- "realisation",
307
- "decision",
308
- "change",
309
- "stage",
310
- ],
311
- to: [
312
- "intent",
313
- "concept",
314
- "capability",
315
- "element",
316
- "realisation",
317
- "decision",
318
- "change",
319
- "stage",
320
- ],
321
- },
322
- // Justifies — design rationale grounding (principle/decision → invariant/decision/principle/concept)
323
- justifies: {
324
- from: ["principle", "decision"],
325
- to: ["invariant", "decision", "principle", "concept"],
326
- },
327
214
  };
215
+ const VIEW_READ_MODEL_DEPENDENCY_TARGETS = [
216
+ "concept",
217
+ "capability",
218
+ "element",
219
+ "stage",
220
+ "artefact",
221
+ "role",
222
+ ];
328
223
  /**
329
224
  * Check if a relationship type is valid for the given endpoint node types.
330
225
  * @param relType - The relationship type
@@ -337,6 +232,17 @@ export const RELATIONSHIP_ENDPOINT_TYPES = {
337
232
  * ```
338
233
  */
339
234
  export function isValidEndpointPair(relType, fromType, toType) {
235
+ if (relType === "depends_on" && fromType === "view") {
236
+ return VIEW_READ_MODEL_DEPENDENCY_TARGETS.includes(toType);
237
+ }
340
238
  const endpoints = RELATIONSHIP_ENDPOINT_TYPES[relType];
341
239
  return endpoints.from.includes(fromType) && endpoints.to.includes(toType);
342
240
  }
241
+ /**
242
+ * True when a relationship is a read-model view dependency.
243
+ */
244
+ export function isViewReadModelDependsOnRelationship(relType, fromType, toType) {
245
+ return (relType === "depends_on" &&
246
+ fromType === "view" &&
247
+ VIEW_READ_MODEL_DEPENDENCY_TARGETS.includes(toType));
248
+ }
@@ -1,6 +1,7 @@
1
1
  import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { NODE_FILE_MAP, NODE_TYPE_LABELS, NodeType, RelationshipType, RELATIONSHIP_TYPE_LABELS, } from "./schema.js";
4
+ import { primaryLifecycleState } from "./lifecycle-state.js";
4
5
  import { graphOp } from "./operations/graph.js";
5
6
  import { graphRefinementOp } from "./operations/graph-refinement.js";
6
7
  import { graphDecisionOp } from "./operations/graph-decision.js";
@@ -203,10 +204,6 @@ function renderNode(n, headingLevel, fromIdx, nodeMap, currentFile) {
203
204
  lines.push(...rels);
204
205
  lines.push("");
205
206
  }
206
- if (n.status) {
207
- lines.push(`- Status: ${n.status}`);
208
- lines.push("");
209
- }
210
207
  // Decision fields
211
208
  if (n.context) {
212
209
  lines.push(`Context: ${renderText(n.context)}`);
@@ -277,16 +274,6 @@ function renderNode(n, headingLevel, fromIdx, nodeMap, currentFile) {
277
274
  }
278
275
  lines.push("");
279
276
  }
280
- // Artefact flow
281
- if (n.input) {
282
- lines.push(`- Input: ${n.input}`);
283
- }
284
- if (n.output) {
285
- lines.push(`- Output: ${n.output}`);
286
- }
287
- if (n.input || n.output) {
288
- lines.push("");
289
- }
290
277
  // Inline external references
291
278
  if (n.external_references && n.external_references.length > 0) {
292
279
  lines.push(...renderExternalReferences(n.external_references));
@@ -533,7 +520,6 @@ export function jsonToMarkdownSingle(doc, options) {
533
520
  ...NODE_FILE_MAP.CHANGES,
534
521
  "view",
535
522
  "milestone",
536
- "version",
537
523
  ];
538
524
  lines.push(...renderNodesGrouped(doc.nodes, allTypes, fromIdx, 2, nodeMap));
539
525
  // Diagrams section
@@ -638,7 +624,7 @@ export function jsonToMarkdownMultiDoc(doc, outDir, options) {
638
624
  title: `${n.id} — ${n.name}`,
639
625
  doc_type: n.type,
640
626
  scope: n.type,
641
- status: n.status,
627
+ status: primaryLifecycleState(n),
642
628
  },
643
629
  };
644
630
  // Count how many distinct file types would be produced
@@ -0,0 +1,9 @@
1
+ import type { Node, NodeStatus } from "./schema.js";
2
+ /**
3
+ * Return true when a lifecycle state is marked as reached on a node.
4
+ */
5
+ export declare function hasLifecycleState(node: Node, state: string): boolean;
6
+ /**
7
+ * Return the most advanced reached lifecycle state, if any.
8
+ */
9
+ export declare function primaryLifecycleState(node: Node): NodeStatus | undefined;
@@ -0,0 +1,22 @@
1
+ import { NODE_STATUSES } from "./schema.js";
2
+ function isLifecycleReached(value) {
3
+ return value === true || typeof value === "string";
4
+ }
5
+ /**
6
+ * Return true when a lifecycle state is marked as reached on a node.
7
+ */
8
+ export function hasLifecycleState(node, state) {
9
+ return isLifecycleReached(node.lifecycle?.[state]);
10
+ }
11
+ /**
12
+ * Return the most advanced reached lifecycle state, if any.
13
+ */
14
+ export function primaryLifecycleState(node) {
15
+ for (let index = NODE_STATUSES.length - 1; index >= 0; index -= 1) {
16
+ const state = NODE_STATUSES[index];
17
+ if (hasLifecycleState(node, state)) {
18
+ return state;
19
+ }
20
+ }
21
+ return undefined;
22
+ }
@@ -113,11 +113,11 @@ server.registerTool("stats", {
113
113
  });
114
114
  // Register query-nodes tool
115
115
  server.registerTool("query-nodes", {
116
- description: "Query nodes by type, status, or other criteria",
116
+ description: "Query nodes by type, lifecycle state, or other criteria",
117
117
  inputSchema: z.object({
118
118
  path: z.string().describe("Path to SysProM file"),
119
119
  type: z.string().optional().describe("Filter by node type"),
120
- status: z.string().optional().describe("Filter by node status"),
120
+ status: z.string().optional().describe("Filter by lifecycle state"),
121
121
  }),
122
122
  }, ({ path, type, status }) => {
123
123
  const { doc } = loadDocument(path);
@@ -310,7 +310,6 @@ server.registerTool("update-node", {
310
310
  const allowedFields = [
311
311
  "name",
312
312
  "description",
313
- "status",
314
313
  "context",
315
314
  "options",
316
315
  "selected",
@@ -320,8 +319,6 @@ server.registerTool("update-node", {
320
319
  "plan",
321
320
  "propagation",
322
321
  "includes",
323
- "input",
324
- "output",
325
322
  "external_references",
326
323
  ];
327
324
  const droppedFields = [];
@@ -495,7 +492,7 @@ server.registerTool("infer-completeness", {
495
492
  });
496
493
  // Register infer-lifecycle tool
497
494
  server.registerTool("infer-lifecycle", {
498
- description: "Infer lifecycle state for nodes based on status and lifecycle fields",
495
+ description: "Infer lifecycle state for nodes based on lifecycle fields",
499
496
  inputSchema: z.object({
500
497
  path: z.string().describe("Path to SysProM file"),
501
498
  }),
@@ -1,7 +1,7 @@
1
1
  import * as z from "zod";
2
2
  import { readFileSync, existsSync, readdirSync, statSync } from "node:fs";
3
3
  import { join, basename } from "node:path";
4
- import { NODE_FILE_MAP, NODE_LABEL_TO_TYPE, RELATIONSHIP_TYPE_LABELS, RELATIONSHIP_LABEL_TO_TYPE, NodeType, RelationshipType, NodeStatus, ExternalReferenceRole, } from "./schema.js";
4
+ import { NODE_FILE_MAP, NODE_LABEL_TO_TYPE, RELATIONSHIP_TYPE_LABELS, RELATIONSHIP_LABEL_TO_TYPE, NodeType, RelationshipType, ExternalReferenceRole, } from "./schema.js";
5
5
  /** Strip markdown link syntax `[text](url)` → `text`. */
6
6
  /**
7
7
  * Strip markdown link syntax `[text](url)` → `text`.
@@ -27,12 +27,6 @@ function parseRelType(s) {
27
27
  throw new Error(`Unknown relationship type: "${s}". Valid types: ${RelationshipType.options.join(", ")}`);
28
28
  return result.data;
29
29
  }
30
- function parseNodeStatus(s) {
31
- const result = NodeStatus.safeParse(s);
32
- if (!result.success)
33
- throw new Error(`Unknown node status: "${s}". Valid statuses: ${NodeStatus.options.join(", ")}`);
34
- return result.data;
35
- }
36
30
  function parseExtRefRole(s) {
37
31
  const result = ExternalReferenceRole.safeParse(s);
38
32
  if (!result.success)
@@ -262,10 +256,6 @@ function parseNodeFromSection(section) {
262
256
  if (descLines.length > 0) {
263
257
  node.description = parseText(descLines.join("\n"));
264
258
  }
265
- // Status
266
- const status = parseSingleValue(body, "- Status");
267
- if (status)
268
- node.status = parseNodeStatus(status);
269
259
  // Decision fields
270
260
  const context = parseSingleValue(body, "Context");
271
261
  if (context)
@@ -316,13 +306,6 @@ function parseNodeFromSection(section) {
316
306
  const includes = parseListItems(body, "Includes");
317
307
  if (includes.length > 0)
318
308
  node.includes = includes;
319
- // Artefact flow
320
- const input = parseSingleValue(body, "- Input");
321
- if (input)
322
- node.input = input;
323
- const output = parseSingleValue(body, "- Output");
324
- if (output)
325
- node.output = output;
326
309
  // Lifecycle and propagation from child sections
327
310
  for (const child of section.children) {
328
311
  if (child.heading === "Lifecycle") {
@@ -484,7 +467,6 @@ export function markdownSingleToJson(content) {
484
467
  ...NODE_FILE_MAP.CHANGES,
485
468
  "view",
486
469
  "milestone",
487
- "version",
488
470
  ];
489
471
  const { nodes, rels } = parseDocFile(content, allTypes);
490
472
  const tableRels = parseRelationshipTable(body);