@nanobpm/nano-workforce 0.171.2 → 0.171.3

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.
@@ -108,7 +108,10 @@ describe("plan-fanout escalation SLA + assignment (U5)", () => {
108
108
  }
109
109
 
110
110
  async function openTask(app: TestApp, processKey: string, elementId: string): Promise<InboxTask> {
111
- const tasks = await app.engine.searchUserTasks({ processInstanceKey: processKey });
111
+ // Root-scoped: the implement-stage escalation now parks on a `human-escalation` grandchild the
112
+ // shared `implement-cell` spawns (ADR 0006 S4); plan-level tasks (plan-review, trial-merge) still
113
+ // park on the root instance and remain discoverable under a root-scoped search (superset).
114
+ const tasks = await app.engine.searchUserTasks({ rootProcessInstanceKey: processKey });
112
115
  const match = tasks.find((t) => t.elementId === elementId);
113
116
  assert.ok(match, `expected an open ${elementId} user task (open: ${tasks.map((t) => t.elementId).join(", ")})`);
114
117
  return match!;
@@ -118,7 +121,7 @@ describe("plan-fanout escalation SLA + assignment (U5)", () => {
118
121
  * filter) and NOT by a bogus group — proving `zeebe:assignmentDefinition candidateGroups` took. */
119
122
  async function assertAssignmentFilterable(app: TestApp, processKey: string, elementId: string) {
120
123
  const byOperators = await app.engine.searchUserTasks({
121
- processInstanceKey: processKey,
124
+ rootProcessInstanceKey: processKey,
122
125
  candidateGroup: "operators",
123
126
  });
124
127
  assert.ok(
@@ -126,7 +129,7 @@ describe("plan-fanout escalation SLA + assignment (U5)", () => {
126
129
  `${elementId} is filterable by the operators candidate group`,
127
130
  );
128
131
  const byBogus = await app.engine.searchUserTasks({
129
- processInstanceKey: processKey,
132
+ rootProcessInstanceKey: processKey,
130
133
  candidateGroup: "nobody-here",
131
134
  });
132
135
  assert.ok(
@@ -150,20 +153,21 @@ describe("plan-fanout escalation SLA + assignment (U5)", () => {
150
153
  }),
151
154
  },
152
155
  async ({ app, processKey }) => {
153
- await openTask(app, processKey, "feature-escalation");
154
- await assertAssignmentFilterable(app, processKey, "feature-escalation");
156
+ await openTask(app, processKey, "escalation");
157
+ await assertAssignmentFilterable(app, processKey, "escalation");
155
158
 
156
- // Never answer — let the SLA elapse. The interrupting boundary cancels the parked task and
157
- // routes to the task-done end (the safe auto-abandon default).
159
+ // Never answer — let the SLA elapse. The interrupting boundary (on the human-escalation cell's
160
+ // `escalation` task) cancels the parked task and routes to its SLA auto-abandon end; the cell
161
+ // then takes its abandon default (the safe auto-abandon of the slice).
158
162
  await advancePastTimer(app, PAST_SLA_MS);
159
163
 
160
164
  const flows = takenFlows(app);
161
165
  assert.ok(
162
- flows.includes("be_feature_sla->w_end"),
163
- `the SLA boundary auto-abandoned to the task-done end (flows: ${flows.join(", ")})`,
166
+ flows.includes("be_he_sla->he_end_sla"),
167
+ `the SLA boundary auto-abandoned to the human-escalation cell's SLA end (flows: ${flows.join(", ")})`,
164
168
  );
165
169
  assert.ok(
166
- !flows.includes("w_gw_answer->implement-task"),
170
+ !flows.includes("ic_gw_answer->record-implementing"),
167
171
  "the human answer loop was NOT taken",
168
172
  );
169
173
  },
@@ -106,7 +106,11 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
106
106
  }
107
107
 
108
108
  async function openTask(app: TestApp, processKey: string, elementId: string): Promise<InboxTask> {
109
- const tasks = await app.engine.searchUserTasks({ processInstanceKey: processKey });
109
+ // Root-scoped: the implement-stage escalation now parks on a `human-escalation` grandchild the
110
+ // shared `implement-cell` spawns (ADR 0006 S4); plan-level tasks (plan-review, empty-plan,
111
+ // trial-merge, the caps-timeout `feature-escalation`) still park on the root and remain
112
+ // discoverable under a root-scoped search (a superset of the parent's own tasks).
113
+ const tasks = await app.engine.searchUserTasks({ rootProcessInstanceKey: processKey });
110
114
  const match = tasks.find((t) => t.elementId === elementId);
111
115
  assert.ok(match, `expected an open ${elementId} user task (open: ${tasks.map((t) => t.elementId).join(", ")})`);
112
116
  return match!;
@@ -131,20 +135,20 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
131
135
  },
132
136
  },
133
137
  async ({ app, processKey }) => {
134
- const task = await openTask(app, processKey, "feature-escalation");
135
- assert.ok(task.userTaskKey, "the feature escalation carries a completable userTaskKey");
138
+ const task = await openTask(app, processKey, "escalation");
139
+ assert.ok(task.userTaskKey, "the human-escalation cell task carries a completable userTaskKey");
136
140
 
137
- // Answer it: the typed resolution loops the child back to re-dispatch the SAME task.
141
+ // Answer it: the typed resolution loops the cell back to re-dispatch the SAME task.
138
142
  await app.engine.completeUserTask(task.userTaskKey, { resolution: "answer", answer: "use v2" });
139
143
  await app.settle();
140
144
 
141
145
  const flows = takenFlows(app);
142
146
  assert.ok(
143
- flows.includes("w_gw_answer->implement-task"),
144
- `answer routed back to implement-task (flows: ${flows.join(", ")})`,
147
+ flows.includes("ic_gw_answer->record-implementing") && flows.includes("record-implementing->implement-task"),
148
+ `answer routed back to implement-task through the cell reset (flows: ${flows.join(", ")})`,
145
149
  );
146
150
  assert.ok(
147
- !flows.includes("w_gw_answer->w_end"),
151
+ !flows.includes("ic_gw_answer->ic_end"),
148
152
  "the abandon (default) flow was NOT taken",
149
153
  );
150
154
  },
@@ -163,17 +167,17 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
163
167
  }),
164
168
  },
165
169
  async ({ app, processKey }) => {
166
- const task = await openTask(app, processKey, "feature-escalation");
170
+ const task = await openTask(app, processKey, "escalation");
167
171
  await app.engine.completeUserTask(task.userTaskKey, { resolution: "abandon" });
168
172
  await app.settle();
169
173
 
170
174
  const flows = takenFlows(app);
171
175
  assert.ok(
172
- flows.includes("w_gw_answer->w_end"),
173
- `abandon routed to the task-done end (flows: ${flows.join(", ")})`,
176
+ flows.includes("ic_gw_answer->ic_end"),
177
+ `abandon routed to the cell's task-done end (flows: ${flows.join(", ")})`,
174
178
  );
175
179
  assert.ok(
176
- !flows.includes("w_gw_answer->implement-task"),
180
+ !flows.includes("ic_gw_answer->record-implementing"),
177
181
  "the answer loop was NOT taken",
178
182
  );
179
183
  },
@@ -454,7 +458,7 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
454
458
  `task with needs routed through the barrier gateway to wait-caps-resolved (flows: ${parked.join(", ")})`,
455
459
  );
456
460
  assert.ok(
457
- !parked.includes("w_gw_needs->implement-task"),
461
+ !parked.includes("w_gw_needs->implement-cell-call"),
458
462
  "the no-needs shortcut was NOT taken for a task that declares needs",
459
463
  );
460
464
  assert.equal(featureBrief, undefined, "the agent has not been dispatched while parked at the barrier");
@@ -471,8 +475,8 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
471
475
 
472
476
  const flows = takenFlows(app);
473
477
  assert.ok(
474
- flows.includes("wait-caps-resolved->implement-task"),
475
- `caps-resolved released the barrier into implement-task (flows: ${flows.join(", ")})`,
478
+ flows.includes("wait-caps-resolved->implement-cell-call") && flows.includes("Start->implement-task"),
479
+ `caps-resolved released the barrier into the implement cell (flows: ${flows.join(", ")})`,
476
480
  );
477
481
  assert.equal(
478
482
  featureBrief,
@@ -534,15 +538,16 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
534
538
  `the caps bound escalated the parked task to the operator (flows: ${flows.join(", ")})`,
535
539
  );
536
540
  assert.ok(
537
- !flows.includes("wait-caps-resolved->implement-task"),
541
+ !flows.includes("wait-caps-resolved->implement-cell-call"),
538
542
  "the resolve arm was withdrawn — the token did not also proceed as if resolved",
539
543
  );
540
544
  assert.equal(featureRan, false, "the agent was NOT dispatched — the unresolved task escalated instead");
541
545
 
542
- // The escalation is a genuine, operable operator decision point: answering it loops the
543
- // child back to re-dispatch the task (the operator having unblocked/decided), exactly like an
544
- // agent-raised escalation — proving this is a real bounded wait + operator escalation, not a
545
- // dead end.
546
+ // The escalation is a genuine, operable operator decision point: answering it releases the
547
+ // caps barrier into the implement cell (the operator having unblocked/decided), proving this is
548
+ // a real bounded wait + operator escalation, not a dead end. This is the plan-fanout's OWN
549
+ // caps-timeout `feature-escalation` task (the fan-out-specific barrier is surrounding
550
+ // orchestration, retained per ADR 0006 S4), distinct from the implement cell's `escalation`.
546
551
  const task = await openTask(app, processKey, "feature-escalation");
547
552
  assert.ok(task.userTaskKey, "the caps-timeout escalation carries a completable userTaskKey");
548
553
  await app.engine.completeUserTask(task.userTaskKey, { resolution: "answer", answer: "shipped it manually" });
@@ -550,8 +555,8 @@ describe("plan-fanout escalations (U2 — task + plan-review + trial-merge → u
550
555
 
551
556
  const answered = takenFlows(app);
552
557
  assert.ok(
553
- answered.includes("w_gw_answer->implement-task"),
554
- `answering the caps escalation routed back to implement-task (flows: ${answered.join(", ")})`,
558
+ answered.includes("w_gw_answer->implement-cell-call") && answered.includes("Start->implement-task"),
559
+ `answering the caps escalation released the barrier into the implement cell (flows: ${answered.join(", ")})`,
555
560
  );
556
561
  assert.equal(featureRan, true, "the agent was dispatched once the operator answered the caps escalation");
557
562
  },
package/nano.app.json CHANGED
@@ -172,10 +172,6 @@
172
172
  "taskType": "pr.record-wave",
173
173
  "handler": "workers/record-wave/worker.ts"
174
174
  },
175
- {
176
- "taskType": "pr.record-wave-escalation",
177
- "handler": "workers/record-wave-escalation/worker.ts"
178
- },
179
175
  {
180
176
  "taskType": "pr.record-feature",
181
177
  "handler": "workers/record-feature/worker.ts"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanobpm/nano-workforce",
3
- "version": "0.171.2",
3
+ "version": "0.171.3",
4
4
  "description": "Nano Workforce — an Agent Graph Orchestration application for Agentic SDLC: durable BPMN processes that coordinate a graph of AI agents across the software delivery lifecycle.",
5
5
  "type": "module",
6
6
  "main": "main.ts",
@@ -63,12 +63,12 @@
63
63
  },
64
64
  "dependencies": {
65
65
  "@nanobpm/agentic": "^0.10.0",
66
- "@nanobpm/urban": "^0.88.1",
66
+ "@nanobpm/urban": "^0.90.0",
67
67
  "bpmn-auto-layout": "^2.0.0-alpha.2"
68
68
  },
69
69
  "devDependencies": {
70
70
  "@biomejs/biome": "^2.4.11",
71
- "@nanobpm/urban-testkit": "^1.0.1",
71
+ "@nanobpm/urban-testkit": "^1.2.0",
72
72
  "@nanobpm/workflow": "^0.14.0",
73
73
  "@semantic-release/changelog": "^7.0.0",
74
74
  "@semantic-release/git": "^11.0.0",
@@ -9,12 +9,9 @@
9
9
  <nano:extend name="pr" type="string" optional="true" />
10
10
  <nano:extend name="summary" type="string" optional="true" />
11
11
  </nano:shape>
12
- <nano:shape id="RecordFeatureEscalationIn" name="Record feature escalation — input">
13
- <nano:extend name="featureKey" type="string" />
14
- <nano:extend name="question" type="string" optional="true" />
15
- </nano:shape>
16
12
  <nano:shape id="RecordFeatureImplementingIn" name="Record feature implementing — input">
17
- <nano:extend name="featureKey" type="string" />
13
+ <nano:extend name="featureKey" type="string" optional="true" />
14
+ <nano:extend name="subjectKey" type="string" optional="true" />
18
15
  </nano:shape>
19
16
  <nano:shape id="ConvergeFeatureIn" name="Converge feature PR — input">
20
17
  <nano:extend name="featureKey" type="string" />
@@ -172,23 +169,28 @@
172
169
  <bpmn:incoming>f_readiness_done</bpmn:incoming>
173
170
  <bpmn:outgoing>f_toImplement</bpmn:outgoing>
174
171
  </bpmn:serviceTask>
175
- <bpmn:serviceTask id="implement-task" name="Implement (agent)">
172
+ <bpmn:callActivity id="implement" name="Implement cell">
176
173
  <bpmn:extensionElements>
177
- <zeebe:taskDefinition type="senior:feature" />
178
- <zeebe:linkedResources>
179
- <zeebe:linkedResource resourceId="prompts/feature.md" bindingType="latest" resourceType="GenericScript" linkName="prompt" />
180
- </zeebe:linkedResources>
174
+ <zeebe:calledElement processId="implement-cell" />
181
175
  <zeebe:ioMapping>
182
- <zeebe:input source="=&#34;&#10;&#10;---&#10;&#10;&#34; + task.prompt + (if (baseBranchBrief = null) then &#34;&#34; else baseBranchBrief) + (if (resolvedArtifacts = null or count(resolvedArtifacts[item != null]) = 0) then &#34;&#34; else (&#34;&#10;&#10;---&#10;&#10;**Bound upstream readiness (intake gate).** This feature was scheduled to wait until an upstream landed and published. Build/install/clone against EXACTLY these resolved published versions (the ones first carrying the awaited capability), and bump the consumer dependency to them — never merely the newest:&#10;&#10;&#34; + string join(resolvedArtifacts[item != null], &#34;&#10;&#34;))) + (if (customInstructions = null) then &#34;&#34; else &#34;&#10;&#10;---&#10;&#10;## Operator custom instructions&#10;&#10;The operator supplied these instructions for this run — follow them:&#10;&#10;&#34; + customInstructions)" target="appendPrompt" />
176
+ <zeebe:input source="=task" target="task" />
177
+ <zeebe:input source="=if (is defined(baseBranchBrief)) then baseBranchBrief else null" target="baseBranchBrief" />
178
+ <zeebe:input source="=if (is defined(resolvedArtifacts)) then resolvedArtifacts else null" target="resolvedArtifacts" />
179
+ <zeebe:input source="=if (is defined(customInstructions)) then customInstructions else null" target="customInstructions" />
183
180
  <zeebe:input source="=if (is defined(transcriptUrlBase)) then transcriptUrlBase else null" target="transcriptUrlBase" />
181
+ <zeebe:input source="=if (is defined(escalationAssignee)) then escalationAssignee else null" target="escalationAssignee" />
182
+ <zeebe:input source="=escalationSlaTimeout" target="escalationSlaTimeout" />
183
+ <zeebe:input source="=featureKey" target="subjectKey" />
184
184
  <zeebe:output source="=status" target="status" />
185
- <zeebe:output source="=question" target="question" />
185
+ <zeebe:output source="=if (is defined(summary)) then summary else null" target="summary" />
186
+ <zeebe:output source="=if (is defined(pr)) then pr else null" target="pr" />
187
+ <zeebe:output source="=if (is defined(question)) then question else null" target="question" />
186
188
  <zeebe:output source="=if (is defined(transcriptUrl)) then transcriptUrl else null" target="transcriptUrl" />
187
189
  </zeebe:ioMapping>
188
190
  </bpmn:extensionElements>
189
191
  <bpmn:incoming>f_implementing</bpmn:incoming>
190
- <bpmn:outgoing>w_toGw</bpmn:outgoing>
191
- </bpmn:serviceTask>
192
+ <bpmn:outgoing>w_toRecord</bpmn:outgoing>
193
+ </bpmn:callActivity>
192
194
  <bpmn:serviceTask id="record-feature-implementing" name="Record implementing">
193
195
  <bpmn:extensionElements>
194
196
  <zeebe:taskDefinition type="pr.record-feature-implementing" />
@@ -197,44 +199,8 @@
197
199
  </zeebe:properties>
198
200
  </bpmn:extensionElements>
199
201
  <bpmn:incoming>f_toImplement</bpmn:incoming>
200
- <bpmn:incoming>w_answerLoop</bpmn:incoming>
201
202
  <bpmn:outgoing>f_implementing</bpmn:outgoing>
202
203
  </bpmn:serviceTask>
203
- <bpmn:exclusiveGateway id="w_gw" name="escalated?" default="w_done">
204
- <bpmn:incoming>w_toGw</bpmn:incoming>
205
- <bpmn:outgoing>w_escalate</bpmn:outgoing>
206
- <bpmn:outgoing>w_done</bpmn:outgoing>
207
- </bpmn:exclusiveGateway>
208
- <bpmn:serviceTask id="record-feature-escalation" name="Record escalation">
209
- <bpmn:extensionElements>
210
- <zeebe:taskDefinition type="pr.record-feature-escalation" />
211
- <zeebe:properties>
212
- <zeebe:property name="io.nanobpm.dataEnvelope.in" value="RecordFeatureEscalationIn" />
213
- </zeebe:properties>
214
- </bpmn:extensionElements>
215
- <bpmn:incoming>w_escalate</bpmn:incoming>
216
- <bpmn:outgoing>w_toEscalationTask</bpmn:outgoing>
217
- </bpmn:serviceTask>
218
- <bpmn:userTask id="feature-escalation" name="Task escalation (human)">
219
- <bpmn:extensionElements>
220
- <zeebe:formDefinition formId="feature-escalation" />
221
- <zeebe:userTask />
222
- <zeebe:assignmentDefinition candidateGroups="operators" assignee="=if (is defined(escalationAssignee) and escalationAssignee != null and trim(string(escalationAssignee)) != &#34;&#34;) then escalationAssignee else null" />
223
- </bpmn:extensionElements>
224
- <bpmn:incoming>w_toEscalationTask</bpmn:incoming>
225
- <bpmn:outgoing>w_toAnswerGw</bpmn:outgoing>
226
- </bpmn:userTask>
227
- <bpmn:boundaryEvent id="be_feature_sla" name="SLA elapsed" attachedToRef="feature-escalation">
228
- <bpmn:outgoing>w_sla</bpmn:outgoing>
229
- <bpmn:timerEventDefinition id="ted_feature_sla">
230
- <bpmn:timeDuration xsi:type="bpmn:tFormalExpression">=escalationSlaTimeout</bpmn:timeDuration>
231
- </bpmn:timerEventDefinition>
232
- </bpmn:boundaryEvent>
233
- <bpmn:exclusiveGateway id="w_gw_answer" name="answer?" default="w_abandon">
234
- <bpmn:incoming>w_toAnswerGw</bpmn:incoming>
235
- <bpmn:outgoing>w_answerLoop</bpmn:outgoing>
236
- <bpmn:outgoing>w_abandon</bpmn:outgoing>
237
- </bpmn:exclusiveGateway>
238
204
  <bpmn:serviceTask id="record-feature" name="Record result">
239
205
  <bpmn:extensionElements>
240
206
  <zeebe:taskDefinition type="pr.record-feature" />
@@ -242,9 +208,7 @@
242
208
  <zeebe:property name="io.nanobpm.dataEnvelope.in" value="RecordFeatureIn" />
243
209
  </zeebe:properties>
244
210
  </bpmn:extensionElements>
245
- <bpmn:incoming>w_done</bpmn:incoming>
246
- <bpmn:incoming>w_abandon</bpmn:incoming>
247
- <bpmn:incoming>w_sla</bpmn:incoming>
211
+ <bpmn:incoming>w_toRecord</bpmn:incoming>
248
212
  <bpmn:outgoing>f_toBlockedGw</bpmn:outgoing>
249
213
  </bpmn:serviceTask>
250
214
  <bpmn:exclusiveGateway id="gw-blocked" name="blocked?" default="f_notBlocked">
@@ -301,19 +265,8 @@
301
265
  <bpmn:sequenceFlow id="f_readiness_skip" name="no gate" sourceRef="gw-readiness" targetRef="ensure-base-branch" />
302
266
  <bpmn:sequenceFlow id="f_readiness_done" sourceRef="readiness-preflight" targetRef="ensure-base-branch" />
303
267
  <bpmn:sequenceFlow id="f_toImplement" sourceRef="ensure-base-branch" targetRef="record-feature-implementing" />
304
- <bpmn:sequenceFlow id="f_implementing" sourceRef="record-feature-implementing" targetRef="implement-task" />
305
- <bpmn:sequenceFlow id="w_toGw" sourceRef="implement-task" targetRef="w_gw" />
306
- <bpmn:sequenceFlow id="w_escalate" name="escalated" sourceRef="w_gw" targetRef="record-feature-escalation">
307
- <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=status = "escalated" and question != null and trim(question) != ""</bpmn:conditionExpression>
308
- </bpmn:sequenceFlow>
309
- <bpmn:sequenceFlow id="w_toEscalationTask" sourceRef="record-feature-escalation" targetRef="feature-escalation" />
310
- <bpmn:sequenceFlow id="w_done" name="done" sourceRef="w_gw" targetRef="record-feature" />
311
- <bpmn:sequenceFlow id="w_toAnswerGw" sourceRef="feature-escalation" targetRef="w_gw_answer" />
312
- <bpmn:sequenceFlow id="w_answerLoop" name="answer" sourceRef="w_gw_answer" targetRef="record-feature-implementing">
313
- <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=resolution = "answer"</bpmn:conditionExpression>
314
- </bpmn:sequenceFlow>
315
- <bpmn:sequenceFlow id="w_abandon" name="abandon" sourceRef="w_gw_answer" targetRef="record-feature" />
316
- <bpmn:sequenceFlow id="w_sla" name="SLA auto-abandon" sourceRef="be_feature_sla" targetRef="record-feature" />
268
+ <bpmn:sequenceFlow id="f_implementing" sourceRef="record-feature-implementing" targetRef="implement" />
269
+ <bpmn:sequenceFlow id="w_toRecord" sourceRef="implement" targetRef="record-feature" />
317
270
  <bpmn:sequenceFlow id="f_toBlockedGw" sourceRef="record-feature" targetRef="gw-blocked" />
318
271
  <bpmn:sequenceFlow id="f_blocked" name="blocked" sourceRef="gw-blocked" targetRef="feature-blocked">
319
272
  <bpmn:conditionExpression xsi:type="bpmn:tFormalExpression">=featureStatus = "blocked"</bpmn:conditionExpression>
@@ -347,64 +300,40 @@
347
300
  <bpmndi:BPMNShape id="BPMNShape_ensure-base-branch" bpmnElement="ensure-base-branch">
348
301
  <dc:Bounds x="566" y="80" width="100" height="80" />
349
302
  </bpmndi:BPMNShape>
350
- <bpmndi:BPMNShape id="BPMNShape_implement-task" bpmnElement="implement-task">
303
+ <bpmndi:BPMNShape id="BPMNShape_implement" bpmnElement="implement">
351
304
  <dc:Bounds x="966" y="80" width="100" height="80" />
352
305
  </bpmndi:BPMNShape>
353
306
  <bpmndi:BPMNShape id="BPMNShape_record-feature-implementing" bpmnElement="record-feature-implementing">
354
307
  <dc:Bounds x="766" y="80" width="100" height="80" />
355
308
  </bpmndi:BPMNShape>
356
- <bpmndi:BPMNShape id="BPMNShape_w_gw" bpmnElement="w_gw" isMarkerVisible="true">
357
- <dc:Bounds x="1166" y="95" width="50" height="50" />
358
- <bpmndi:BPMNLabel>
359
- <dc:Bounds x="1154" y="76" width="74" height="14" />
360
- </bpmndi:BPMNLabel>
361
- </bpmndi:BPMNShape>
362
- <bpmndi:BPMNShape id="BPMNShape_record-feature-escalation" bpmnElement="record-feature-escalation">
363
- <dc:Bounds x="1316" y="240" width="100" height="80" />
364
- </bpmndi:BPMNShape>
365
- <bpmndi:BPMNShape id="BPMNShape_feature-escalation" bpmnElement="feature-escalation">
366
- <dc:Bounds x="1516" y="240" width="100" height="80" />
367
- </bpmndi:BPMNShape>
368
- <bpmndi:BPMNShape id="BPMNShape_w_gw_answer" bpmnElement="w_gw_answer" isMarkerVisible="true">
369
- <dc:Bounds x="1716" y="255" width="50" height="50" />
370
- <bpmndi:BPMNLabel>
371
- <dc:Bounds x="1713" y="236" width="56" height="14" />
372
- </bpmndi:BPMNLabel>
373
- </bpmndi:BPMNShape>
374
309
  <bpmndi:BPMNShape id="BPMNShape_record-feature" bpmnElement="record-feature">
375
- <dc:Bounds x="1866" y="80" width="100" height="80" />
310
+ <dc:Bounds x="1166" y="80" width="100" height="80" />
376
311
  </bpmndi:BPMNShape>
377
312
  <bpmndi:BPMNShape id="BPMNShape_gw-blocked" bpmnElement="gw-blocked" isMarkerVisible="true">
378
- <dc:Bounds x="2066" y="95" width="50" height="50" />
313
+ <dc:Bounds x="1366" y="95" width="50" height="50" />
379
314
  <bpmndi:BPMNLabel>
380
- <dc:Bounds x="2061" y="76" width="60" height="14" />
315
+ <dc:Bounds x="1361" y="76" width="60" height="14" />
381
316
  </bpmndi:BPMNLabel>
382
317
  </bpmndi:BPMNShape>
383
318
  <bpmndi:BPMNShape id="BPMNShape_feature-blocked" bpmnElement="feature-blocked">
384
- <dc:Bounds x="2216" y="400" width="100" height="80" />
319
+ <dc:Bounds x="1516" y="400" width="100" height="80" />
385
320
  </bpmndi:BPMNShape>
386
321
  <bpmndi:BPMNShape id="BPMNShape_record-blocked-ack" bpmnElement="record-blocked-ack">
387
- <dc:Bounds x="2416" y="400" width="100" height="80" />
322
+ <dc:Bounds x="1716" y="400" width="100" height="80" />
388
323
  </bpmndi:BPMNShape>
389
324
  <bpmndi:BPMNShape id="BPMNShape_gw-converge" bpmnElement="gw-converge" isMarkerVisible="true">
390
- <dc:Bounds x="2241" y="95" width="50" height="50" />
325
+ <dc:Bounds x="1541" y="95" width="50" height="50" />
391
326
  <bpmndi:BPMNLabel>
392
- <dc:Bounds x="2233" y="76" width="67" height="14" />
327
+ <dc:Bounds x="1533" y="76" width="67" height="14" />
393
328
  </bpmndi:BPMNLabel>
394
329
  </bpmndi:BPMNShape>
395
330
  <bpmndi:BPMNShape id="BPMNShape_converge" bpmnElement="converge">
396
- <dc:Bounds x="2416" y="240" width="100" height="80" />
331
+ <dc:Bounds x="1716" y="240" width="100" height="80" />
397
332
  </bpmndi:BPMNShape>
398
333
  <bpmndi:BPMNShape id="BPMNShape_End" bpmnElement="End">
399
- <dc:Bounds x="2616" y="102" width="36" height="36" />
400
- <bpmndi:BPMNLabel>
401
- <dc:Bounds x="2617" y="83" width="34" height="14" />
402
- </bpmndi:BPMNLabel>
403
- </bpmndi:BPMNShape>
404
- <bpmndi:BPMNShape id="BPMNShape_be_feature_sla" bpmnElement="be_feature_sla">
405
- <dc:Bounds x="1548" y="302" width="36" height="36" />
334
+ <dc:Bounds x="1916" y="102" width="36" height="36" />
406
335
  <bpmndi:BPMNLabel>
407
- <dc:Bounds x="1524" y="383" width="84" height="14" />
336
+ <dc:Bounds x="1917" y="83" width="34" height="14" />
408
337
  </bpmndi:BPMNLabel>
409
338
  </bpmndi:BPMNShape>
410
339
  <bpmndi:BPMNEdge id="BPMNEdge_f_toReadinessGw" bpmnElement="f_toReadinessGw">
@@ -426,41 +355,26 @@
426
355
  <di:waypoint x="866" y="120" />
427
356
  <di:waypoint x="966" y="120" />
428
357
  </bpmndi:BPMNEdge>
429
- <bpmndi:BPMNEdge id="BPMNEdge_w_toGw" bpmnElement="w_toGw">
358
+ <bpmndi:BPMNEdge id="BPMNEdge_w_toRecord" bpmnElement="w_toRecord">
430
359
  <di:waypoint x="1066" y="120" />
431
360
  <di:waypoint x="1166" y="120" />
432
361
  </bpmndi:BPMNEdge>
433
- <bpmndi:BPMNEdge id="BPMNEdge_w_done" bpmnElement="w_done">
434
- <di:waypoint x="1216" y="120" />
435
- <di:waypoint x="1866" y="120" />
436
- <bpmndi:BPMNLabel>
437
- <dc:Bounds x="1525" y="98" width="32" height="14" />
438
- </bpmndi:BPMNLabel>
439
- </bpmndi:BPMNEdge>
440
362
  <bpmndi:BPMNEdge id="BPMNEdge_f_toBlockedGw" bpmnElement="f_toBlockedGw">
441
- <di:waypoint x="1966" y="120" />
442
- <di:waypoint x="2066" y="120" />
363
+ <di:waypoint x="1266" y="120" />
364
+ <di:waypoint x="1366" y="120" />
443
365
  </bpmndi:BPMNEdge>
444
366
  <bpmndi:BPMNEdge id="BPMNEdge_f_notBlocked" bpmnElement="f_notBlocked">
445
- <di:waypoint x="2116" y="120" />
446
- <di:waypoint x="2241" y="120" />
367
+ <di:waypoint x="1416" y="120" />
368
+ <di:waypoint x="1541" y="120" />
447
369
  <bpmndi:BPMNLabel>
448
- <dc:Bounds x="2140" y="98" width="78" height="14" />
370
+ <dc:Bounds x="1440" y="98" width="78" height="14" />
449
371
  </bpmndi:BPMNLabel>
450
372
  </bpmndi:BPMNEdge>
451
373
  <bpmndi:BPMNEdge id="BPMNEdge_f_noConverge" bpmnElement="f_noConverge">
452
- <di:waypoint x="2291" y="120" />
453
- <di:waypoint x="2616" y="120" />
454
- <bpmndi:BPMNLabel>
455
- <dc:Bounds x="2418" y="98" width="71" height="14" />
456
- </bpmndi:BPMNLabel>
457
- </bpmndi:BPMNEdge>
458
- <bpmndi:BPMNEdge id="BPMNEdge_w_abandon" bpmnElement="w_abandon">
459
- <di:waypoint x="1766" y="280" />
460
- <di:waypoint x="1916" y="280" />
461
- <di:waypoint x="1916" y="160" />
374
+ <di:waypoint x="1591" y="120" />
375
+ <di:waypoint x="1916" y="120" />
462
376
  <bpmndi:BPMNLabel>
463
- <dc:Bounds x="1815" y="258" width="53" height="14" />
377
+ <dc:Bounds x="1718" y="98" width="71" height="14" />
464
378
  </bpmndi:BPMNLabel>
465
379
  </bpmndi:BPMNEdge>
466
380
  <bpmndi:BPMNEdge id="BPMNEdge_f_readiness_gate" bpmnElement="f_readiness_gate">
@@ -471,28 +385,20 @@
471
385
  <dc:Bounds x="246" y="206" width="39" height="14" />
472
386
  </bpmndi:BPMNLabel>
473
387
  </bpmndi:BPMNEdge>
474
- <bpmndi:BPMNEdge id="BPMNEdge_w_escalate" bpmnElement="w_escalate">
475
- <di:waypoint x="1191" y="145" />
476
- <di:waypoint x="1191" y="280" />
477
- <di:waypoint x="1316" y="280" />
478
- <bpmndi:BPMNLabel>
479
- <dc:Bounds x="1196" y="206" width="67" height="14" />
480
- </bpmndi:BPMNLabel>
481
- </bpmndi:BPMNEdge>
482
388
  <bpmndi:BPMNEdge id="BPMNEdge_f_blocked" bpmnElement="f_blocked">
483
- <di:waypoint x="2091" y="145" />
484
- <di:waypoint x="2091" y="440" />
485
- <di:waypoint x="2216" y="440" />
389
+ <di:waypoint x="1391" y="145" />
390
+ <di:waypoint x="1391" y="440" />
391
+ <di:waypoint x="1516" y="440" />
486
392
  <bpmndi:BPMNLabel>
487
- <dc:Bounds x="2096" y="286" width="53" height="14" />
393
+ <dc:Bounds x="1396" y="286" width="53" height="14" />
488
394
  </bpmndi:BPMNLabel>
489
395
  </bpmndi:BPMNEdge>
490
396
  <bpmndi:BPMNEdge id="BPMNEdge_f_converge" bpmnElement="f_converge">
491
- <di:waypoint x="2266" y="145" />
492
- <di:waypoint x="2266" y="280" />
493
- <di:waypoint x="2416" y="280" />
397
+ <di:waypoint x="1566" y="145" />
398
+ <di:waypoint x="1566" y="280" />
399
+ <di:waypoint x="1716" y="280" />
494
400
  <bpmndi:BPMNLabel>
495
- <dc:Bounds x="2271" y="206" width="60" height="14" />
401
+ <dc:Bounds x="1571" y="206" width="60" height="14" />
496
402
  </bpmndi:BPMNLabel>
497
403
  </bpmndi:BPMNEdge>
498
404
  <bpmndi:BPMNEdge id="BPMNEdge_f_readiness_done" bpmnElement="f_readiness_done">
@@ -500,45 +406,19 @@
500
406
  <di:waypoint x="616" y="280" />
501
407
  <di:waypoint x="616" y="160" />
502
408
  </bpmndi:BPMNEdge>
503
- <bpmndi:BPMNEdge id="BPMNEdge_w_toEscalationTask" bpmnElement="w_toEscalationTask">
504
- <di:waypoint x="1416" y="280" />
505
- <di:waypoint x="1516" y="280" />
506
- </bpmndi:BPMNEdge>
507
- <bpmndi:BPMNEdge id="BPMNEdge_w_toAnswerGw" bpmnElement="w_toAnswerGw">
508
- <di:waypoint x="1616" y="280" />
509
- <di:waypoint x="1716" y="280" />
510
- </bpmndi:BPMNEdge>
511
409
  <bpmndi:BPMNEdge id="BPMNEdge_f_toBlockedAck" bpmnElement="f_toBlockedAck">
512
- <di:waypoint x="2316" y="440" />
513
- <di:waypoint x="2416" y="440" />
410
+ <di:waypoint x="1616" y="440" />
411
+ <di:waypoint x="1716" y="440" />
514
412
  </bpmndi:BPMNEdge>
515
413
  <bpmndi:BPMNEdge id="BPMNEdge_f_blockedEnd" bpmnElement="f_blockedEnd">
516
- <di:waypoint x="2516" y="440" />
517
- <di:waypoint x="2634" y="440" />
518
- <di:waypoint x="2634" y="138" />
414
+ <di:waypoint x="1816" y="440" />
415
+ <di:waypoint x="1934" y="440" />
416
+ <di:waypoint x="1934" y="138" />
519
417
  </bpmndi:BPMNEdge>
520
418
  <bpmndi:BPMNEdge id="BPMNEdge_f_toEndConverged" bpmnElement="f_toEndConverged">
521
- <di:waypoint x="2516" y="280" />
522
- <di:waypoint x="2634" y="280" />
523
- <di:waypoint x="2634" y="138" />
524
- </bpmndi:BPMNEdge>
525
- <bpmndi:BPMNEdge id="BPMNEdge_w_sla" bpmnElement="w_sla">
526
- <di:waypoint x="1566" y="338" />
527
- <di:waypoint x="1566" y="358" />
528
- <di:waypoint x="1916" y="358" />
529
- <di:waypoint x="1916" y="160" />
530
- <bpmndi:BPMNLabel>
531
- <dc:Bounds x="1757" y="325" width="88" height="28" />
532
- </bpmndi:BPMNLabel>
533
- </bpmndi:BPMNEdge>
534
- <bpmndi:BPMNEdge id="BPMNEdge_w_answerLoop" bpmnElement="w_answerLoop">
535
- <di:waypoint x="1741" y="305" />
536
- <di:waypoint x="1741" y="360" />
537
- <di:waypoint x="816" y="360" />
538
- <di:waypoint x="816" y="160" />
539
- <bpmndi:BPMNLabel>
540
- <dc:Bounds x="1254" y="338" width="49" height="14" />
541
- </bpmndi:BPMNLabel>
419
+ <di:waypoint x="1816" y="280" />
420
+ <di:waypoint x="1934" y="280" />
421
+ <di:waypoint x="1934" y="138" />
542
422
  </bpmndi:BPMNEdge>
543
423
  </bpmndi:BPMNPlane>
544
424
  </bpmndi:BPMNDiagram>